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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【ACM出版】2024人工智能与自然语言处理国际学术会议(AINLP 2024,7月19-21)

2024人工智能与自然语言处理国际学术会议&#xff08;AINLP 2024&#xff09;将于2024年7月19-21日在中国珠海召开&#xff0c;该会议作为第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09;分会场召开。 本次会议主要围绕“人工智能与自然语言处…

pycharm的一些配置

1.安装 2.字体 3.新建文件模版 4.快捷键设置

【会议征稿,CPS出版】第四届管理科学和软件工程国际学术会议(ICMSSE 2024,7月19-21)

第四届管理科学和软件工程国际学术会议(ICMSSE 2024)由ACM珠海分会&#xff0c;广州番禺职业技术学院主办&#xff1b;全国区块链行业产教融合共同体&#xff0c;AEIC学术交流中心承办&#xff0c;将于2024年7月19-21日于广州召开。 会议旨在为从事管理与软件工程领域的专家学…

[Qt] Qt Creator中配置 Vs-Code 编码风格

新建vscode-onedark.xml文档 &#xff0c;将如下内容复制进去&#xff0c;并配置到Creator中&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <style-scheme version"1.0" name"One Dark"><style name"Tex…

吴恩达机器学习 第三课 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…

超越YOLOv8,飞桨推出精度最高的实时检测器RT-DETR!

众所周知&#xff0c;实时目标检测( Real-Time Object Detection )一直由 YOLO 系列模型主导。 飞桨在去年 3 月份推出了高精度通用目标检测模型 PP-YOLOE &#xff0c;同年在 PP-YOLOE 的基础上提出了 PP-YOLOE 。后者在训练收敛速度、下游任务泛化能力以及高性能部署能力方面…

2. 数据结构分析即索引库的crud

1. 数据库脚本 DROP TABLE IF EXISTS tb_hotel; CREATE TABLE tb_hotel (id bigint(0) NOT NULL,name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT COMMENT 酒店名称,address varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_090…

【c2】编译预处理,gdb,makefile,文件,多线程,动静态库

文章目录 1.编译预处理&#xff1a;C源程序 - 编译预处理【#开头指令和特殊符号进行处理&#xff0c;删除程序中注释和多余空白行】- 编译2.gdb调试&#xff1a;多进/线程中无法用3.makefile文件&#xff1a;make是一个解释makefile中指令的命令工具4.文件&#xff1a;fprint/f…

常见的七大排序

目录 前言 冒泡排序 选择排序 插入排序 堆排序 希尔排序 快排 归并排序 前言 本文介绍七种常见的排序方式&#xff1a;冒泡排序&#xff0c;选择排序&#xff0c;插入排序&#xff0c;堆排序&#xff0c;希尔排序&#xff0c;快排&#xff0c;归并排序 冒泡排序 将每2…

Rsync未授权访问-vulfocus

1.原理 Rsync是linux上文件传输的协议&#xff0c;如果有返回直接可以看到&#xff0c;部分主机使用协议的时候不会加密码&#xff0c;就容易造成未授权访问漏洞 2.复现 打开vulfocus.io,搜索rsync关键字&#xff0c;打开环境 在自己的主机上去连接远程服务器&#xff1a; r…

linux高级编程(1)

linux操作系统编程: 实现一个 用户程序 (1).库函数 --来实现 (2).系统调用 也就是说&#xff0c;程序要进行系统调用的话&#xff0c;有直接和间接&#xff08;通过库函数&#xff09;两种方式 linux里面对文件的处理: 思想: 一切皆文件 everything is file&…

轻松上手MYSQL:MYSQL事务隔离级别的奇幻之旅

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》《MYSQL》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 ✨欢迎加入探索MYSQL索引数据结构之旅✨ &#x1f44b; 大家好&#xff01;文本学习…

国产AI算力训练大模型技术实践

ChatGPT引领AI大模型热潮&#xff0c;国内外模型如雨后春笋&#xff0c;掀起新一轮科技浪潮。然而&#xff0c;国内大模型研发推广亦面临不小挑战。面对机遇与挑战&#xff0c;我们需保持清醒&#xff0c;持续推进技术创新与应用落地。 为应对挑战&#xff0c;我们需从战略高度…

【Linux详解】冯诺依曼架构 | 操作系统设计 | 斯坦福经典项目Pintos

目录 一. 冯诺依曼体系结构 (Von Neumann Architecture) 注意事项 存储器的意义&#xff1a;缓冲 数据流动示例 二. 操作系统 (Operating System) 操作系统的概念 操作系统的定位与目的 操作系统的管理 系统调用和库函数 操作系统的管理&#xff1a; sum 三. 系统调…

matplotlib之常见图像种类

Matplotlib 是一个用于绘制图表和数据可视化的 Python 库。它支持多种不同类型的图形&#xff0c;以满足各种数据可视化需求。以下是一些 Matplotlib 支持的主要图形种类&#xff1a; 折线图&#xff08;Line Plot&#xff09;&#xff1a; 用于显示数据随时间或其他连续变量的…

【web2】jquary,bootstrap,vue

文章目录 1.jquary&#xff1a;选择器1.1 jquery框架引入&#xff1a;$("mydiv") 当成id选择器1.2 jquery版本/对象&#xff1a;$(js对象) -> jquery对象1.3 jquery的页面加载事件&#xff1a;$ 想象成 window.onload 1.4 jquery的基本选择器&#xff1a;$()里内容…

大模型参数高效微调学习笔记

大模型参数高效微调学习笔记 github地址 billbill链接 1.分类 图中有五个大类&#xff1a; selective&#xff08;选择性微调&#xff09;&#xff1a;BitFit&#xff0c;Attention Tuningsoft prompts&#xff08;提示微调&#xff09;&#xff1a;Prompt-tuning&#xff0c…

Android 自定义软键盘实现 数字九宫格

最近项目在对接美团外卖功能 实现外面小哥凭取货码取货 对接完功能后 用户反馈 弹出的软键盘 很难输入 数字太小了 大概是下面这种显示方式 需求 组长说 要不搞一个自定义软键盘吧 数字搞大点 方便外卖员输入数字 我设置了输入EditText的输入格式为Number 还是不行 那就开…

文件夹或文件已在另一程序中打开,找句柄发现是explorer.exe如何解决

1.找到句柄&#xff1a;ctrl alt del打开任务资源管理器 2.注意是选择CPU -> 关联的句柄&#xff0c;而不是概述 如果发现只有explorer.exe&#xff0c;那肯定是不对的&#xff0c;我们先shfit一个一个删除&#xff0c;发现哪个删不掉&#xff0c;再在这里找句柄&#xff0c…

使用MyBatis Generator自动代码生成器简化Java持久层开发

在Web开发中&#xff0c;数据访问层&#xff08;DAO层&#xff09;的编码工作往往重复且繁琐&#xff0c;尤其是在处理数据库表与Java对象之间的映射时。MyBatis Generator是一款强大的代码生成工具&#xff0c;它能自动生成DAO接口、Mapper XML文件和实体类&#xff0c;极大地…