upload-labs通关笔记-第13关 文件上传之白名单POST法

news2025/5/22 22:56:12

目录

一、白名单过滤

二、%00截断

1.截断原理

2、截断条件

(1)PHP版本 < 5.3.4

(2)magic_quotes_gpc配置为Off

(3)代码逻辑存在缺陷

三、源码分析

1、代码审计

(1)文件存储依赖字符串截断

(2)路径拼接可控

2、GET型和POST型区别

3、攻击思路

四、渗透实战

1、构建脚本test13.jpg

2、配置php服务

(1)安装php5.3.4以下的php版本

(2)切换php5.3.4以下的php版本

(3)关闭magic_quotes_gpc配置

(4)重启Apache服务

3、打开靶场

4、bp开启拦截

5、点击上传

6、bp拦截

7、POST参数增加test13.php%00

8、手动URL解码

9、发包并获取脚本地址

10、访问脚本


本文通过《upload-labs靶场通关笔记系列》来进行upload-labs靶场的渗透实战,本文讲解upload-labs靶场第13关白名单POST法渗透实战。

一、白名单过滤

在文件上传功能中,为了保障Web服务安全,通常会对上传的文件采用文件类型过滤机制。其中白名单机制是一种较为安全的做法,它会明确规定允许上传的文件类型,只有符合白名单列表的文件才能被上传,其他类型的文件则会被拒绝。例如,一个图片上传功能可能只允许上传  .jpg、 png、 .gif等类型的文件。黑名单过滤方法和白名单的过滤方法的区别具体如下图所示。

对比项目白名单黑名单
定义明确规定允许上传的文件类型列表,只有在白名单内的文件类型才允许上传。列出禁止上传的文件类型列表,除黑名单内的文件类型外,其他类型文件允许上传。
安全性通常安全性较高,因为只允许已知的安全文件类型上传,能有效防止大多数恶意脚本上传。安全性相对较低,因为需要不断更新和完善黑名单,以防止新出现的恶意文件类型绕过检测。
误判可能性较低,只要文件类型在白名单中,一般不会被误判为不合规文件。较高,可能会因为黑名单设置不全面或对某些特殊情况考虑不足,导致合法文件被误判为非法文件。
绕过难度相对较难绕过,除非攻击者能找到白名单机制的安全风险,如文件类型检查不严格、路径拼接问题等。相对容易绕过,攻击者可以通过各种方法,如更改文件后缀名大小写、添加特殊字符、利用系统特性(如 Windows 下的点绕过、空格绕过、::$DATA 绕过等)来尝试绕过黑名单检测。

二、%00截断

1.截断原理

%00截断是一种利用字符串处理特性和编程语言安全风险的攻击手段,%00截断的原理如下:空字符\0(URL 编码为%00)被定义为字符串结束符,程序处理字符串时一旦遇到该字符,便会认定字符串到此结束。一般来说就是这一个特定字符起截断作用。0x00,%00,/00之类的截断,都是一样的,只是不同表示而已。\0 代表空字符,在 URL 编码中,其对应的十六进制值是 00,所以按照 URL 编码规则会被编码为 %00。

字符ASCII 码值十六进制表示URL 编码表示
\000x00%00

如果程序在处理文件名或文件路径这类涉及用户输入的环节,没有对输入进行严格过滤与验证,就极易引发%00截断攻击。攻击者可构造类似test13.php%00.jpg的文件名,在程序拼接文件保存路径时,%00会使后续内容被截断,最终以test13.php保存文件,进而绕过文件类型检查等安全机制,造成安全隐患。

2、截断条件

(1)PHP版本 < 5.3.4

  • PHP 5.3.4之前:默认会解析%00(空字节)为字符串终止符从而导致截断风险。

  • PHP 5.3.4及之后:修复了%00自动截断的问题。

(2)magic_quotes_gpc配置为Off

  • magic_quotes_gpc能自动对来自GET、POST和COOKIE的数据转义,在单引号、双引号、反斜杠和空字符等前加反斜杠,旨在防止 SQL 注入,保障数据库操作安全。当它为Off,用户输入数据不再自动转义,攻击者输入的%00字符可直接传入程序。
  • 若程序处理文件上传或字符串时未额外过滤%00,当magic_quotes_gpc为Off时%00不会被转义为\%00,这会导致系统容易被用于%00截断攻击,攻击者构造的evil.php%00.jpg文件名可绕过文件类型检查。

(3)代码逻辑存在缺陷

  • 未过滤%00:代码直接使用用户输入拼接路径,未做空字节过滤。

  • 未规范化路径:未使用basename()realpath()等函数处理文件名,导致%00被保留。

三、源码分析

1、代码审计

对upload-labs 第13关的源码进行审计,相对于第3-11关卡的黑名单过滤,本关卡与12关一样,变为了白名单过滤,仅允许文件后缀名为“jpg,png和gif”三种后缀的文件上传,具体如下所示。

 对比第12关卡,区别仅仅是save_path由GET参数变为了POST型参数,其中第12关的代码对比如下所示,两者的区别就是红框所示参数的传入方式变化。

经过详细注释的代码如下所示,相对于12关卡,只是参数的传递方式发生变化,由GET方法变为POST方法。

<?php
// 初始化上传状态和消息变量
$is_upload = false;  // 用于标记文件是否上传成功,初始为false
$msg = null;        // 用于存储上传过程中的提示信息,初始为null

// 检查是否提交了上传表单
if(isset($_POST['submit'])){
    // 定义允许上传的文件扩展名白名单
    $ext_arr = array('jpg','png','gif');
    
    // 获取上传文件的扩展名
    // strrpos()查找文件名中最后一个"."的位置
    // substr()从"."后一位开始截取,得到文件扩展名
    $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'];
        
        // 构建最终存储路径和文件名
        // 包含:用户指定的保存路径 + 随机数(10-99) + 当前日期时间 + 原扩展名
        $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        // 移动临时文件到最终位置
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;  // 上传成功,设置状态为true
        } else {
            $msg = "上传失败";  // 移动文件失败时的提示
        }
    } else {
        // 文件类型不在白名单中的提示
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}
?>

分析代码可知存在的白名单%00截断POST型安全风险,具体原因如下所示。

(1)文件存储依赖字符串截断

上传的文件存储过程使用了move_uploaded_file()的C底层函数,它遇到%00(\0)会截断字符串。

(2)路径拼接可控

攻击者能控制文件保存路径或文件名的一部分(如通过$_POST的save_path参数传入)。 \0(在 URL 编码中表示为 %00)被视为字符串的结束符。

此代码在拼接文件保存路径时,使用了 $_POST['save_path'] 从 URL 的POST参数中获取保存路径,并且没有对这个参数进行严格的过滤和验证。

2、GET型和POST型区别

GET请求

  • 参数通过URL明文传输,如:/upload.php?filename=evil.php%00.jpg

  • 浏览器会自动对%00进行URL解码,变成空字节\x00

POST请求

在使用POST方法传递%00字符时,他不会像GET型参数一样自动将%00进行URL界面,故而POST法进行%00 截断攻击时,需要手动进行URL 解码将其还原成原始的 %00 字符。如果使用burpsuite进行操作,那么需要使用Convertselection——>选择URL——>选择URL-decode才能达到攻击目的。

3、攻击思路

在文件上传功能中,如果程序只是简单地通过检查文件名的后缀来验证文件类型,而没有对整个文件名进行严格的安全检查,那么上传的路径可以GET型渗透方法一样进行截断绕过,将save_path由../upload/改为../upload/test13.php%00,但是这样做POST方法却没法像GET方法一样绕过服务器的文件上传过滤机制,这是因为GET方式的%00会自动被服务器进行URL解码成空字符,而POST方式需要先自己手动使用工具进行URL解码,然后再发送报文,具体步骤如下所示。

  • 攻击者构造POST参数传入的save_path包含%00的特殊文件名(如"test13.php%00")

save_path:../upload/test13.php%00
  • 由于POST报文发出的%00不会被自动解码,故而使用bp工具将%00手动选择并使用Convertselection——>选择URL——>选择URL-decode进行解码后发送。

  • 前端验证看到的是".jpg"扩展名,file_ext为“jpg”,可以通过检查

  • $_FILES['upload_file']['name']:test13.jpg
    file_ext:jpg
  • 由于$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;得知图片的路径为“test13.php%00”与“/”和“rand(10, 99).date("YmdHis").”和".jpg"的结合。假设rand(10, 99).date("YmdHis")的输出为9920250429,于是上传文件的路径变为如下所示。

  • save_path:../upload/test13.php%00
    重命名后的图片:9920250429.jpg
    img_path:../upload/test13.php%00/9920250429.jpg
  • 后端move_uploaded_file()处理时,遇到%00即停止解析,实际存储文件名变为"test13.php"。

  • img_path:../upload/test13.php

四、渗透实战

1、构建脚本test13.jpg

注意此时文件的后缀为jpg,这是因为本关卡为白名单,故脚本的后缀需要与上传允许的后缀“jpg,png和gif”中的任意一个保持一致。

<?php
phpinfo();
?>

2、配置php服务

需要将php版本号切换到5.3.4以下,具体如下所示。

(1)安装php5.3.4以下的php版本

如果当前phpstudy没有安装5.3.4以下的版本,需要安装对应版本的php,如下所示。

(2)切换php5.3.4以下的php版本

网站-管理-php版本-选择php5.3.4以下的php版本,具体如下所示。

(3)关闭magic_quotes_gpc配置

打开phpstudy保存目录——>选择Extensions目录——>php目录——>选择php5.2.17nts版本——>找到php.ini文件,方法如下所示。

将magic_quotes_gpc值修改为off,修改前如下所示。

将magic_quotes_gpc值修改为off,修改后如下所示。

(4)重启Apache服务

修改后需要重启小皮的Apache服务,具体如下所示。

3、打开靶场

 打开靶场第13关,浏览选择该脚本,但不点击上传。

4、bp开启拦截

5、点击上传

6、bp拦截

bp捕获到上传报文,下图红框的部分即为需要修改的部分。

这时候注意,这个POST报文需要修改的是save_path的参数,如上图红框所示,具体如下所示。

../upload/

由于需要将savepath的"save_path=../upload/"后缀改为"save_path=../upload/test13.php%00",修改之前文件名为"test13.php",如下所示。 

../upload/test13.php%00

7、POST参数增加test13.php%00

将save_path改为"../upload/test13.php%00",修改后效果如下所示。

8、手动URL解码

GET方式的%00会被服务器进行URL解码成null空字符,而POST方式需要先自己进行URL解码成null后再发送报文,此时选中%00内容字段,然后点击右键选择Convertselection——>选择URL——>选择URL-decode,具体效果如下所示。

解码后效果如下所示,已经变为不可见的空字符。

9、发包并获取脚本地址

将bp的inception设置为off,此时修改后的报文发送成功。

回到靶场的Pass13关卡,图片已经上传成功,在图片处右键复制图片地址。

右键图片获取图片地址,如下所示获取到图片URL。

http://127.0.0.1/upload-labs/upload/test13.php /9920250421160947.jpg

但由于%00截断,可将test13.php之后的内容截断,因此上传的脚本url地址如下所示。

http://127.0.0.1/upload-labs/upload/test13.php

10、访问脚本

 如下所示访问test13.php脚本获取到服务器的php信息,证明文件上传成功。

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

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

相关文章

数据库健康监测器(BHM)实战:如何通过 HTML 报告识别潜在问题

在数据库运维中,健康监测是保障系统稳定性与性能的关键环节。通过 HTML 报告,开发者可以直观查看数据库的运行状态、资源使用情况与潜在风险。 本文将围绕 数据库健康监测器(Database Health Monitor, BHM) 的核心功能展开分析,结合 Prometheus + Grafana + MySQL Export…

Oracle 11g 单实例使用+asm修改主机名导致ORA-29701 故障分析

解决 把服务器名修改为原来的&#xff0c;重启服务器。 故障 建表空间失败。 分析 查看告警日志 ORA-1119 signalled during: create tablespace splex datafile ‘DATA’ size 2000M… Tue May 20 18:04:28 2025 create tablespace splex datafile ‘DATA/option/dataf…

OpenCV CUDA模块图像过滤------用于创建一个最大值盒式滤波器(Max Box Filter)函数createBoxMaxFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 createBoxMaxFilter()函数创建的是一个 最大值滤波器&#xff08;Maximum Filter&#xff09;&#xff0c;它对图像中每个像素邻域内的像素值取最…

Redis数据库-消息队列

一、消息队列介绍 二、基于List结构模拟消息队列 总结&#xff1a; 三、基于PubSub实现消息队列 (1)PubSub介绍 PubSub是publish与subscribe两个单词的缩写&#xff0c;见明知意&#xff0c;PubSub就是发布与订阅的意思。 可以到Redis官网查看通配符的书写规则&#xff1a; …

破解充电安全难题:智能终端的多重防护体系构建

随着智能终端的普及&#xff0c;充电安全问题日益凸显。从电池过热到短路起火&#xff0c;充电过程中的安全隐患不仅威胁用户的生命财产安全&#xff0c;也制约了行业的发展。如何构建一套高效、可靠的多重防护体系&#xff0c;成为破解充电安全难题的关键。通过技术创新和系统…

apptrace 三大策略,助力电商 App 在 618 突围

随着 5 月 13 日 “618” 电商大促预售战的打响&#xff0c;各大平台纷纷祭出百亿补贴、消费券等大招&#xff0c;投入超百亿流量与数十亿现金&#xff0c;意图在这场年度商战中抢占先机。但这场流量争夺战远比想象中艰难&#xff0c;中国互联网络信息中心数据显示&#xff0c;…

SuperVINS:应对挑战性成像条件的实时视觉-惯性SLAM框架【全流程配置与测试!!!】【2025最新版!!!!】

一、项目背景及意义 SuperVINS是一个改进的视觉-惯性SLAM&#xff08;同时定位与地图构建&#xff09;框架&#xff0c;旨在解决在挑战性成像条件下的定位和地图构建问题。该项目基于经典的VINS-Fusion框架&#xff0c;但通过引入深度学习方法进行了显著改进。 视觉-惯性导航系…

Node-Red通过开疆智能Profinet转ModbusTCP采集西门子PLC数据配置案例

一、内容简介 本篇内容主要介绍Node-Red通过node-red-contrib-modbus插件与开疆智能ModbusTCP转Profinet设备进行通讯&#xff0c;这里Profinet转ModbusTCP网关作为从站设备&#xff0c;Node-Red作为主站分别从0地址开始读取10个线圈状态和10个保持寄存器&#xff0c;分别用Mo…

【性能测试】jvm监控

使用本地jvisualvm远程监控服务器 参考文章&#xff1a;https://blog.csdn.net/yeyuningzi/article/details/140261411 jvisualvm工具默认是监控本地jvm&#xff0c;如果需要监控远程就要修改配置参数 1、先查看是否打开 ps -ef|java 如果打开杀掉进程 2、进入项目服务路径下…

Uniapp开发鸿蒙应用时如何运行和调试项目

经过前几天的分享&#xff0c;大家应该应该对uniapp开发鸿蒙应用的开发语法有了一定的了解&#xff0c;可以进行一些简单的应用开发&#xff0c;今天分享一下在使用uniapp开发鸿蒙应用时怎么运行到鸿蒙设备&#xff0c;并且在开发中怎么调试程序。 运行 Uniapp项目支持运行到…

QT+RSVisa控制LXI仪器

1.下载并安装visa R&SVISA - Rohde & Schwarz China 2.安装后的目录说明 安装了64位visa会默认把32位的安装上&#xff1b; 64位库和头文件目录为&#xff1a;C:\Program Files\IVI Foundation 32位库和头文件目录为&#xff1a;C:\Program Files (x86)\IVI Foundation…

springboot3+vue3融合项目实战-大事件文章管理系统-文章分类也表查询(条件分页)

在pojo实体类中增加pagebean实体类 Data NoArgsConstructor AllArgsConstructor public class PageBean <T>{private Long total;//总条数private List<T> items;//当前页数据集合 }articlecontroller增加代码 GetMappingpublic Result<PageBean<Article&g…

Canvas进阶篇:鼠标交互动画

Canvas进阶篇&#xff1a;鼠标交互动画 前言获取鼠标坐标鼠标事件点击事件监听代码示例效果预览 拖动事件监听代码示例效果预览 结语 前言 在上一篇文章Canvas进阶篇&#xff1a;基本动画详解 中&#xff0c;我们讲述了在Canvas中实现动画的基本步骤和动画的绘制方法。本文将进…

【Node.js】Web开发框架

个人主页&#xff1a;Guiat 归属专栏&#xff1a;node.js 文章目录 1. Node.js Web框架概述1.1 Web框架的作用1.2 Node.js主要Web框架生态1.3 框架选择考虑因素 2. Express.js2.1 Express.js概述2.2 基本用法2.2.1 安装Express2.2.2 创建基本服务器 2.3 路由2.4 中间件2.5 请求…

使用Vite创建一个动态网页的前端项目

1. 引言 虽然现在的前端更新换代的速度很快&#xff0c;IDE和工具一批批的换&#xff0c;但是我们始终要理解一点基本的程序构建的思维&#xff0c;这些环境和工具都是为了帮助我们更快的发布程序。笔者还记得以前写前端代码的时候&#xff0c;只使用文本编辑器&#xff0c;然…

系统架构设计师案例分析题——web篇

软考高项系统架构设计师&#xff0c;其中的科二案例分析题为5选3&#xff0c;总分75达到45分即合格。本贴来归纳web设计题目中常见的知识点即细节&#xff1a; 目录 一.核心知识 1.常见英文名词 2.私有云 3.面向对象三模型 4.计网相关——TCP和UDP的差异 5.MQTT和AMQP协…

MySQL--day5--多表查询

&#xff08;以下内容全部来自上述课程&#xff09; 多表查询 1. 为什么要用多表查询 # 如果不用多表查询 #查询员工名为Abel的人在哪个城市工作? SELECT* FROM employees WHERE last_name Abel;SELECT * FROM departments WHERE department_id 80;SELECT * FROM locati…

leetcode hot100刷题日记——7.最大子数组和

class Solution { public:int maxSubArray(vector<int>& nums) {//方法一&#xff1a;动态规划//dp[i]表示以i下标结尾的数组的最大子数组和//那么在i0时&#xff0c;dp[0]nums[0]//之后要考虑的就是我们要不要把下一个数加进来&#xff0c;如果下一个数加进来会使结…

基于Spring Boot和Vue的在线考试系统架构设计与实现(源码+论文+部署讲解等)

源码项目获取联系 请文末卡片dd我获取更详细的演示视频 系统介绍 基于Spring Boot和Vue的在线考试系统。为学生和教师/管理员提供一个高效、便捷的在线学习、考试及管理平台。系统采用前后端分离的架构&#xff0c;后端基于成熟稳定的Spring Boot框架&#xff0c;负责数据处理…

Android 绘制折线图

用了一段时间的 Jetpack Compose ,感觉写 UI 的效率确实会提升不少 。 配合 AI 编程绘制了一个折线图。供大家学习参考! @Composable fun TemperatureChart() {val timeLabels = listOf("7:00", "8:00", "9:00", "10:00", "11:…