Web渗透:文件上传-后端过滤

在上一篇文件上传的内容中笔者阐述了文件上传漏洞产生的相关原理以及使用了一个pikachu靶场的例子进行演示,在这个例子中涉及到了前端代码对于文件上传漏洞的相关防护,以及站在攻击者的角度我们要如何绕过前端的防护成功进行攻击;但是事实上对于文件上传漏洞相关的安全防护不仅在前端能够部署,在后端也能够部署,那么本文我们就来探讨一下在后端的相关过滤措施有哪些以及站在攻击者的角度我们如何进行绕过。

1.MIME类型过滤:

MIME:

MIME(Multipurpose Internet Mail Extensions)是一种互联网标准,用于描述电子邮件、Web等互联网应用中传输的数据类型。MIME类型最初是为了解决电子邮件中传输多媒体内容的问题,现在已经广泛用于HTTP协议中,用于描述和处理多种类型的网络资源。

MIME类型的结构

MIME类型由两部分组成,格式为type/subtype

  • type:主要类型,表示数据的大类,例如textimageaudiovideoapplication等。

  • subtype:具体子类型,表示数据的具体格式,例如plainhtmljpegpngmpegjson等。

例如:

text/html 表示HTML文档
image/jpeg 表示JPEG图像
application/json 表示JSON数据

言归正传,文件上传MIME类型过滤是指在文件上传功能中,通过检查上传文件的MIME类型来限制允许上传的文件类型。这可以防止用户上传恶意文件,增强应用程序的安全性。以下是一些关于如何实现文件上传MIME类型过滤的详细信息和示例。

相关源码:

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {$allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];$fileType = mime_content_type($_FILES['file']['tmp_name']);
​if (!in_array($fileType, $allowedTypes)) {die('Invalid file type.');}
​// 处理文件上传逻辑,例如移动文件到目标目录move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . basename($_FILES['file']['name']));echo 'File uploaded successfully.';
}
?>
<form method="POST" enctype="multipart/form-data"><input type="file" name="file"><button type="submit">Upload</button>
</form>
 

$allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];定义一个数组,包含允许上传的文件MIME类型。

$fileType = mime_content_type($_FILES['file']['tmp_name']);使用mime_content_type函数获取上传文件的MIME类型。$_FILES['file']['tmp_name']是上传文件的临时文件路径。

if (!in_array($fileType, $allowedTypes)) {die('Invalid file type.');
}
  • 使用in_array函数检查上传文件的MIME类型是否在允许的类型列表中。如果不在,则终止脚本执行并输出"Invalid file type."。

绕过方式:

通过BP抓包,通过修改请求头中的Content-Type字段进行绕过;当我们上传的文件为php文件时,该字段的内容如下图:

这个时候我们可以将该字段修改为如下示例MIME类型进行绕过:

image/jpeg, image/png, application/pdf,text/plain,text/html,image/png

以下是一个包含常见MIME类型的表格(10行):

文件扩展名MIME类型描述
.htmltext/htmlHTML文档
.csstext/cssCSS样式表
.jstext/javascriptJavaScript代码
.jsonapplication/jsonJSON格式
.jpgimage/jpegJPEG图像
.pngimage/pngPNG图像
.gifimage/gifGIF图像
.mp3audio/mpegMP3音频
.mp4video/mp4MP4视频
.pdfapplication/pdfPDF文档

当然可修改的值不止这些,我们完全可以将各种MIME类型存入txt文件中,到时候再使用BP进行FUZZ测试即可。

2.扩展名验证:

①黑名单:

使用扩展名黑名单是防止文件上传漏洞的一种有效方法。通过禁止上传包含特定扩展名的文件,可以减少恶意文件被上传到服务器的风险。以下是一些常见的恶意文件扩展名,可以添加到黑名单中;相关代码(upload靶场为例):

 if (file_exists(UPLOAD_PATH)) {$deny_ext = array('.asp','.aspx','.php','.jsp');$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //收尾去空
​if(!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            if (move_uploaded_file($temp_file,$img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';}
代码逻辑:

$deny_ext = array('.asp','.aspx','.php','.jsp');定义一个数组,包含不允许上传的文件扩展名。

接着通过对上传文件名进行处理,获取上传文件的扩展名;紧接着!in_array($file_ext, $deny_ext)判断当前上传文件扩展名是否再黑名单列表中,若在则禁止上传(不将文件进行保存)。

此时的绕过思路:

使用特殊文件后缀进行绕过,以php为例子:

①.php3, .php4, .php5, .php7:用于指定 PHP 版本的文件后缀,较少使用。
②.phtml:表示包含 PHP 代码的 HTML 文件,通常用于混合 HTML 和 PHP 代码。
③.inc:通常表示包含文件(include file),虽然本身不是 PHP 后缀,但常包含 PHP 代码并通过 include 或 require 引入其他 PHP 文件。(需要配合文件包含漏洞)

因为上述代码中的黑名单列表并不完善所以这个时候我们只需要将php文件后缀进行修改上传即可。如果是自身在进行开发时需要将黑名单列表尽可能地完善,一下时常见的黑名单列表:

.php, .php3, .php4, .php5, .phtml, .phps, .asp, .aspx, .jsp, .jspx, .cfm, .cgi, .pl, .py, .rb, .sh, .bat, .exe, .com, .cmd, .dll, .scr, .msi, .vbs, .js, .jse, .wsf, .wsh, .ps1

②白名单

在文件上传防护中,使用白名单过滤是一个有效的方法,通过只允许特定的、安全的文件类型和扩展名来降低风险。以下是如何实现白名单过滤的详细步骤及示例代码:

if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);if(in_array($file_ext,$ext_arr)){$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
​if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = '上传出错!';}} else{$msg = "只允许上传.jpg|.png|.gif类型文件!";}
}
?>

$ext_arr = array('jpg','png','gif');设置了允许上传文件后缀的白名单列表;当文件后缀名在白名单中才能够成功上传文件。

绕过方式:

00截断:当文件名中包含NULL字符时,某些编程语言和服务器会在处理字符串时将NULL字符后的内容截断。例如,在PHP中,example.php\0.jpg文件名在某些情况下会被截断为example.php,从而绕过扩展名检查。

其他绕过手法总结
1.大小写绕过:利用服务器文件系统或代码对文件扩展名大小写不敏感的特性,绕过安全检测和过滤。

一些文件系统不区分文件名的大小写,这意味着 example.phpexample.PHP 被视为同一个文件。在这种情况下,攻击者可以使用大小写变种绕过文件扩展名的检测。

Windows 文件系统(NTFS、FAT32):默认情况下不区分大小写。
macOS 文件系统(HFS+):默认情况下不区分大小写。
Linux 文件系统(ext3、ext4、XFS):默认情况下区分大小写。

但是在上述代码中包含将获取的扩展名进行统一转换的操作:

$file_ext = strtolower($file_ext); //转换为小写

所以此时大小写绕过放在上一个环境中无法生效。

2.双重扩展名

通过使用双重扩展名,服务器可能只检查第一个扩展名,从而绕过检测。

示例:

  • example.php.aa

  • example.php.bb

此时中间件在进行解析时会从后往前进行识别,将自身能够辨别的后缀名作为当前文件的类型。

3.文件内容混淆

原理:在文件内容中添加无害字符或注释,使其通过内容检查。

示例:

在PHP文件中添加JPEG文件头。

适用条件:服务器检查文件内容,但允许无害字符。

4.特殊字符绕过

原理:利用特殊字符或编码方式绕过检查。

示例:example.php%00.jpg(%00 是 NULL 字符)

适用条件:服务器在处理字符串时忽略特殊字符或编码。

5.编码绕过

原理:通过URL编码或Unicode编码绕过检查。

示例:example%2Ephp(%2E 代表 .)

适用条件:服务器在处理编码时不进行解码或不正确解码。

6.::$DATA

原理:利用NTFS文件系统的ADS特性,在文件名中加入::$DATA

示例:example.php::$DATA

适用条件:服务器运行在Windows且使用NTFS文件系统。

防御措施

1.严格的白名单机制:只允许特定的文件扩展名和MIME类型。
2.统一转换为小写:在处理扩展名时,统一将其转换为小写。
3。验证文件内容:不仅检查文件扩展名,还要检查文件内容的实际类型(MIME类型和文件头)。
4.移除特殊字符:在处理文件名时,移除包括NULL字符和::等特殊字符。
5.重命名上传文件:上传文件后,重命名文件以移除任何潜在的恶意扩展名。
6.设置正确的文件权限:确保上传目录没有执行权限,防止文件被执行。
示例代码

以下是一个综合了多种防御措施的文件上传代码示例:

<?php
function sanitize_filename($filename) {// 移除NULL字符和NTFS数据流标识符以及其他特殊字符$filename = str_replace(["\0", '::$DATA'], '', $filename);  $filename = preg_replace('/[^a-zA-Z0-9._-]/', '', $filename);return $filename;
}
​
$allowed_ext = array('jpg', 'jpeg', 'png', 'pdf');  //后缀名白名单
$allowed_mime_types = array('image/jpeg', 'image/png', 'application/pdf'); //mime白名单
​
$file_name = sanitize_filename($_FILES['upload_file']['name']);
$file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
​
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$file_mime_type = finfo_file($finfo, $_FILES['upload_file']['tmp_name']);
finfo_close($finfo);
​
if (in_array($file_ext, $allowed_ext) && in_array($file_mime_type, $allowed_mime_types)) {$temp_file = $_FILES['upload_file']['tmp_name'];$destination = 'uploads/' . uniqid() . '.' . $file_ext;if (move_uploaded_file($temp_file, $destination)) {echo 'File uploaded successfully.';} else {echo 'Error moving uploaded file.';}
} else {echo 'Invalid file type.';
}
?>
​
<form method="POST" enctype="multipart/form-data"><input type="file" name="upload_file"><button type="submit">Upload</button>
</form>
 

安全性分析

  1. 文件名清理sanitize_filename函数移除NULL字符和NTFS数据流标识符,并只保留字母、数字、点、下划线和横杠。这有效地防止了常见的文件名绕过技术。

  2. 文件扩展名和MIME类型检查

    ①检查文件扩展名是否在允许的列表中。

    ②使用finfo_file函数获取文件的MIME类型,并检查它是否在允许的列表中。这双重检查确保文件类型是安全的。

  3. 唯一文件名:使用uniqid函数生成唯一文件名,避免文件覆盖问题。

  4. 错误处理:如果文件移动失败,输出错误信息;这虽然不能完全防止攻击,但可以帮助调试和改进代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/32966.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux下手动查杀木马与Rootkit的实战指南

模拟木马程序的自动运行 黑客可以通过多种方式让木马程序自动运行&#xff0c;包括&#xff1a; 计划任务 (crontab)&#xff1a;通过设置定时任务来周期性地执行木马脚本。开机启动&#xff1a;在系统的启动脚本中添加木马程序&#xff0c;确保系统启动时木马也随之运行。替…

力扣-2663

题目 如果一个字符串满足以下条件&#xff0c;则称其为 美丽字符串 &#xff1a; 它由英语小写字母表的前 k 个字母组成。它不包含任何长度为 2 或更长的回文子字符串。 给你一个长度为 n 的美丽字符串 s 和一个正整数 k 。 请你找出并返回一个长度为 n 的美丽字符串&#…

JAVA+Netty简单实现Nginx反向代理网关功能【设计实践】

背景 本文实现一个类似于nginx或gateway的反向代理网关&#xff0c;实现思路是访客通过网络请求反向代理服务&#xff0c;代理服务连接到真实服务&#xff0c;维护访客和真实服务的数据交互。 这个实现和之前的内网穿透项目思路相似&#xff0c;只不过内网穿透是由客户端主动…

用python写一个AI Agent对接企业微信上下游协同的案例

要实现一个AI Agent对接企业微信上下游协同&#xff0c;我们可以使用Python编写一个企业微信机器人&#xff0c;用于接收和处理来自企业微信的消息。在此示例中&#xff0c;我们将使用wechatpy库来实现企业微信机器人&#xff0c;并使用requests库实现与上下游系统的通信。 首…

很冷门但真的有趣的IOS应用

Tuesday Tuesday纪念日小组件是一款功能丰富的倒数日和桌面小组件工具APP。此外&#xff0c;Tuesday软件还具有超萌小清新的风格&#xff0c;界面设计清新可爱&#xff0c;适合各种场景使用。用户可以通过小组件实现各种趣味功能&#xff0c;满足不同心情需求。 SideNotes Si…

查看显卡使用情况

查看 NVIDIA 显卡的使用情况&#xff0c;你可以使用命令行工具 nvidia-smi。这是一个非常有用的命令&#xff0c;可以提供关于你的 NVIDIA GPU 的详细信息&#xff0c;包括 GPU 的使用率、显存使用情况、GPU 时钟频率、电源使用情况、温度以及正在运行的进程等。 以下是一些基…

吴恩达机器学习 第三课 week2 推荐算法(上)

目录 01 学习目标 02 推荐算法 2.1 定义 2.2 应用 2.3 算法 03 协同过滤推荐算法 04 电影推荐系统 4.1 问题描述 4.2 算法实现 05 总结 01 学习目标 &#xff08;1&#xff09;了解推荐算法 &#xff08;2&#xff09;掌握协同过滤推荐算法&#xff08;Collabo…

2025秋招NLP算法面试真题(一)-史上最全Transformer面试题

史上最全Transformer面试题 Transformer为何使用多头注意力机制&#xff1f;&#xff08;为什么不使用一个头&#xff09;Transformer为什么Q和K使用不同的权重矩阵生成&#xff0c;为何不能使用同一个值进行自身的点乘&#xff1f; &#xff08;注意和第一个问题的区别&#…

查找和排序

目录 一、查找 1.1查找的基本概念 1.2顺序查找 1.3折半查找&#xff08;二分查找&#xff09; 1.4散列表的查找 1.4.1基本概念 1.4.2散列函数的构造方法 1.4.3解决冲突的方法 二、排序 2.1排序的基本概念 2.2插入排序 2.2.1直接插入排序&#xff1a; 2.2.2希尔排序…

linux 简单使用 sftp 和 lftp命令

目录 一. 环境准备二. sftp命令连接到SFTP服务器三. lftp命令3.1 连接FTP和SFTP服务器3.2 将文件从sftp服务器下载到本地指定目录 四. 通过WinSCP命令行从SFTP服务器获取文件到Windows 一. 环境准备 ⏹在安卓手机上下载个MiXplorer&#xff0c;用作SFTP和FTP服务器 官网: htt…

第12天:前端集成与Django后端 - 用户认证与状态管理

第12天&#xff1a;前端集成与Django后端 - 用户认证与状态管理 目标 整合Django后端与Vue.js前端&#xff0c;实现用户认证和应用状态管理。 任务概览 设置Django后端用户认证。创建Vue.js前端应用。使用Vuex进行状态管理。实现前端与后端的用户认证流程。 详细步骤 1. …

windows无法启动redis-server

Warning: no config file specified, using the default config. In order to specify a config file use D:\Code_enve\Redis\redis-server.exe /path/to/redis.conf Creating Server TCP listening socket *:6379: bind: No such file or directory以上是问题的报错信息&…

AIGC-Animate Anyone阿里的图像到视频 角色合成的框架-论文解读

Animate Anyone: Consistent and Controllable Image-to-Video Synthesis for Character Animation 论文:https://arxiv.org/pdf/2311.17117 网页:https://humanaigc.github.io/animate-anyone/ MOTIVATION 角色动画的目标是将静态图像转换成逼真的视频&#xff0c;这在在线零…

vue.js获取body高度

在mounted生命周期钩子中获取&#xff1a; export default {mounted() {this.bodyHeight document.body.offsetHeight;},data() {return {bodyHeight: 0};} }; export default {data() {return {bodyHeight: 0};},mounted() {this.bodyHeight window.innerHeight;} };expor…

如何高效地为pip换源:详细操作指南

在Python开发中&#xff0c;pip是我们不可或缺的包管理工具。然而&#xff0c;默认的官方源下载速度较慢&#xff0c;尤其是在国内使用时可能会遇到网络问题。为了提高下载速度&#xff0c;我们可以通过更换国内的镜像源来解决这一问题。本文将详细介绍如何高效地为pip换源&…

计网:网络应用层【Email应用/SMTP协议】

Email应用与SMTP协议 Email应用层的构成 客户端服务器协议 用户代理 用于读写邮件消息&#xff1b;与服务器交互&#xff0c;收发邮件消息 常见的客户端&#xff1a;Outlook&#xff0c;Foxmail&#xff08;这两个是需要下载的客户端&#xff09;&#xff0c;Web客户端&…

【论文复现|智能算法改进】一种基于多策略改进的鲸鱼算法

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 SCI二区|鲸鱼优化算法&#xff08;WOA&#xff09;原理及实现【附完整Matlab代码】 2.改进点 混沌反向学习策略 将混沌映射和反向学习策略结合&#xff0c;形成混沌反向学习方法&#xff0c;通过该方 法…

python中不同维度的Tensor向量为何可以直接相加——广播机制

文章目录 广播机制示例解释广播机制如何工作代码示例输出解释广播机制的本质 在矩阵加法中&#xff0c;如果两个张量的形状不同&#xff0c;但其中一个张量的形状可以通过广播机制扩展到与另一个张量的形状相同&#xff0c;则可以进行加法操作。广播机制在深度学习框架&#xf…

VB实现加法计算

textbox1失去焦点&#xff0c;检查输入的值是否为数字。 textbox2中按下Enter键&#xff0c;检查输入的值是否为数字。 textbox3获得焦点&#xff0c;计算textbox1和textbox2的和。 Public Class Form1Private Sub TextBox1_LostFocus(sender As Object, e As EventArgs) Hand…

计算机组成原理-第6章计算机的运算方法

6.1无符号数和有符号数 6.1.1无符号数 没有符号&#xff0c;在寄存器中的每一位均可用来存放数值。 6.1.2有符号数 1&#xff0c;机器数与真值&#xff1a;0表示正&#xff0c;1表示负。 把符号数字化的数称为机器数&#xff0c;而把带或-符号的数称为真值。 2&#xff0…