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

目录

一、白名单过滤

二、%00截断

1、%00截断原理

2、空字符

3、截断条件

(1)PHP版本 < 5.3.4

(2)magic_quotes_gpc配置为Off

(3)代码逻辑存在缺陷

三、源码分析

1、代码审计

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

(2)路径拼接可控

2、攻击思路

四、渗透实战

1、构建脚本test12.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、GET参数增加test12.php%00

8、发包并获取脚本地址

10、访问脚本


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

一、白名单过滤

在文件上传功能中,白名单过滤的核心思想是"只允许明确许可的,其他一律禁止",这与黑名单的"禁止已知危险的"形成鲜明对比。文件上传白名单过滤是一种严格的安全机制,它通过预先定义一组允许上传的文件扩展名(如jpg、png、pdf等),系统仅接受符合白名单的文件类型,其他所有类型一律拒绝。相比黑名单过滤,白名单采用"默认禁止"原则,从根本上杜绝了攻击者通过双写、大小写变异、特殊扩展名等手法绕过防御的可能性,显著提高了安全性。黑名单过滤方法和白名单的过滤方法的区别具体如下图所示。

对比维度白名单机制黑名单机制
安全原则只允许明确许可的文件类型(默认拒绝所有)仅禁止已知危险文件类型(默认允许所有)
安全性★★★★★(难以绕过)★★☆☆☆(易被双写/大小写等手法绕过)
典型实现in_array(strtolower(ext), ['jpg','png'])

str_ireplace(['php','jsp'], "", filename)

in_array(strtolower(ext), ['php','phtml'])

维护成本需随业务需求更新白名单需持续追踪新增危险扩展名
防御效果能防御未知攻击类型仅能防御已知攻击类型
常见绕过方式很难绕过双写(.pphphp)、大小写(.PhP)、空字节等
适用场景严格管控的稳定业务(如头像上传)需支持动态扩展名的特殊场景

二、%00截断

1、%00截断原理

%00截断是一种利用字符串处理特性和编程语言安全性风险的攻击手段,%00截断的原理如下:

  • 字符编码与字符串结束符:在许多编程语言中,\0(在 URL 编码中表示为%00)被用作字符串的结束符。当程序处理字符串时,遇到\0就会认为字符串在此处结束。
  • 文件名或路径处理安全问题:如果程序在处理文件名或文件路径时,没有对用户输入进行严格的过滤和验证,就可能导致%00截断攻击。例如,攻击者上传一个名为test12.php%00.jpg的文件,程序在拼接文件保存路径时,可能会将%00之后的内容截断,实际保存的文件路径就变成了test12.php,从而绕过了文件类型检查等安全机制。

2、空字符

在很多编程语言中,字符串是以字符数组的形式存储的,并且以\0(ASCII 码值为 0)作为字符串的结束标志。当程序对字符串进行处理时,遇到\0就会认为字符串到此结束。%00截断主要利用的是 ASCII 码为 0 的空字符\0(在 URL 中表示为%00)来实现字符串截断,一般来说就是这一个特定字符起截断作用。0x00,%00,/00之类的截断,都是一样的,只是不同表示而已。

字符ASCII 码值十六进制表示URL 编码表示作用
\000x00%00%00截断攻击中,用于截断字符串,使服务器将其后面的字符忽略,从而达到绕过文件类型检查等目的

3、截断条件

(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 注入等攻击,确保数据在数据库操作中的安全性。
  • 当magic_quotes_gpc为Off时,对用户输入的数据不再进行自动转义处理。这意味着攻击者输入的%00字符可以直接传递到程序中,而不会被转义为\%00。如果程序在处理文件上传或其他涉及字符串处理的功能时,没有对%00进行额外的过滤,就更容易被利用来进行%00截断攻击。例如,在前面提到的文件上传代码中,如果magic_quotes_gpc为Off,攻击者构造的evil.php%00.jpg文件名可以直接被程序接收,进而可能导致文件类型检查被绕过。

(3)代码逻辑存在缺陷

  • 未过滤%00:代码直接使用$_FILES['file']['name']或用户输入拼接路径,未做空字节过滤。

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

三、源码分析

1、代码审计

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

经过详细注释的代码如下所示。

<?php
// 初始化变量,用于标记文件是否上传成功,初始值为 false
$is_upload = false;
// 初始化变量,用于存储上传过程中的提示信息,初始值为 null
$msg = null;// 检查是否通过 POST 方式提交了名为 submit 的表单数据
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'];// 拼接上传文件在目标目录中的完整路径// $_GET['save_path'] 从 URL 的 GET 参数中获取保存路径// rand(10, 99) 生成一个 10 到 99 之间的随机数// date("YmdHis") 获取当前的日期和时间,格式为年月日时分秒// 最后拼接上文件扩展名$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;// 尝试将临时文件移动到目标目录if(move_uploaded_file($temp_file,$img_path)){// 如果移动成功,将 $is_upload 标记为 true$is_upload = true;} else {// 如果移动失败,设置提示信息为上传出错$msg = '上传出错!';}} else{// 如果文件扩展名不在允许的列表中,设置提示信息为只允许上传特定类型的文件$msg = "只允许上传.jpg|.png|.gif类型文件!";}
}
?>

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

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

文件存储的过程使用了move_uploaded_file()这个C底层函数:PHP的文件操作函数(如move_uploaded_file()底层是C语言实现,会按\0截断字符串。

(2)路径拼接可控

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

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

2、攻击思路

在文件上传功能中,如果程序只是简单地通过检查文件名的后缀来验证文件类型,而没有对整个文件名进行严格的安全检查。假设上传的图片名为$_FILES['upload_file']['name']=test12.jpg,save_path为“../upload/”。

  • 攻击者构造$_GET参数传入的save_path包含脚本名与%00拼接的特殊文件名。

save_path:../upload/test12.php%00
  • 前端验证看到的是".jpg"扩展名,file_ext为“jpg”,可以通过检查

$_FILES['upload_file']['name']:test12.jpg
file_ext:jpg
  • 由于$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;得知图片的路径为“test12.php%00”与“/”和“rand(10, 99).date("YmdHis").”和".jpg"的结合。假设rand(10, 99).date("YmdHis")的输出为8820250428,那么

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

img_path:../upload/test12.php

四、渗透实战

1、构建脚本test12.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、打开靶场

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

4、bp开启拦截

5、点击上传

6、bp拦截

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

这时候注意,虽然这个报文为POST报文,但是savepath确实在GET参数中,具体如下所示。

POST /upload-labs/Pass-12/index.php?save_path=../upload/ HTTP/1.1

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

POST /upload-labs/Pass-12/index.php?save_path=../upload/test12.php%00 HTTP/1.1

7、GET参数增加test12.php%00

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

8、发包并获取脚本地址

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

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

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

http://127.0.0.1/upload-labs/upload/test12.php /9620211121160947.jpg

但由于%00截断,可将test12.php之后的内容截断,因此上传的脚本url地址变为:

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

以本实验为例我们上传文件时修改的文件名../upload/test12.php%00

上传成功后的路径和文件名为upload/test12.php /9620211121160947.jpg

很明显图片被上传到upload目录中且test12.php被重命名为test12.php /9620211121160947.jpg

但由于%00截断,可将test12.php之后的内容截断,所以最后得到的文件名为test12.php

10、访问脚本

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

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

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

相关文章

Node.js数据抓取技术实战示例

Node.js常用的库有哪些呢&#xff1f;比如axios或者node-fetch用来发送HTTP请求&#xff0c;cheerio用来解析HTML&#xff0c;如果是动态网页的话可能需要puppeteer这样的无头浏览器。这些工具的组合应该能满足大部分需求。 然后&#xff0c;可能遇到的难点在哪里&#xff1f;…

数据结构(3)线性表-链表-单链表

我们学习过顺序表时&#xff0c;一旦对头部或中间的数据进行处理&#xff0c;由于物理结构的连续性&#xff0c;为了不覆盖&#xff0c;都得移&#xff0c;就导致时间复杂度为O&#xff08;n&#xff09;&#xff0c;还有一个潜在的问题就是扩容&#xff0c;假如我们扩容前是10…

【Unity】DOTween的常用函数解释

DOTween插件常用函数解释 1.DOTween.To&#xff08;通用变化动画&#xff09; 解释&#xff1a;将某一个值在一定的时间内变化到另一个值&#xff08;通用的函数&#xff09;&#xff0c;可用于大部分的动画变化 使用示例&#xff1a; using UnityEngine; using DG.Tweenin…

数据结构测试模拟题(1)

1、约瑟夫问题 #include<bits/stdc.h> using namespace std; const int N25; int e[N],ne[N],head-1,idx1; int n,m; void add_to_head(int x){e[idx]x;ne[idx]head;headidx; } void add(int k,int x){e[idx]x;ne[idx]ne[k];ne[k]idx; } int main(){cin>>n>>…

Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)

文章目录 Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)需求方法1:使用Helm覆盖值方法2: 在Lens中临时修改Deployment配置步骤 1: 创建 Docker Registry Secret步骤 2: 在 Deployment 中引用 Secret参考资料Helm配置之为特定Deployment配置特定Docker仓库(覆…

BERT 作为Transformer的Encoder 为什么采用可学习的位置编码

摘要 BERT 在位置编码上与原始 Transformer 论文中的 sin/cos 公式不同&#xff0c;选择了可学习&#xff08;learned&#xff09;的位置嵌入方案。本文将从 Transformer 原始位置编码选项入手&#xff0c;分析 BERT 选择 learned positional embeddings 的四大核心原因&#x…

【Linux 学习计划】-- gcc、g++、动静态库链接

目录 什么是gcc、g gcc、g 相关操作详解 预处理、编译、汇编、链接来源 动静态链接是什么 结语 什么是gcc、g gcc、g其实就是编译器&#xff0c;是帮助我们从.c或者.cc&#xff0c;.cpp文件编译成可执行程序的 其中&#xff0c;我们如果要编译c语言文件的话&#xff0c;…

前端读取本地项目中 public/a.xlsx 文件中的数据 vue3

前端读取本地项目中 public/a.xlsx 文件中的数据 vue3 项目中需要在 Vue3 项目中读取 public/a.xlsx 文件&#xff0c;可以使用 fetch API 来获取文件内容 一、安装 xlsx 首先&#xff0c;你需要安装 xlsx 库&#xff1a; npm install xlsx二、在需要用的页面里引入xlsx im…

MySQL:to many connections连接数过多

当你遇到 MySQL: Too many connections 错误时&#xff0c;意味着当前连接数已达到 MySQL 配置的最大限制。这通常是由于并发连接过多或连接未正确关闭导致的。 一、查看当前连接数 查看 MySQL 当前允许的最大连接数 SHOW VARIABLES LIKE max_connections;查看当前使用的最大…

2024年热门AI趋势及回顾

人工智能的崛起 2024 年可能会被铭记为人工智能不再是一种技术新奇事物&#xff0c;而是成为现实的一年。微软、Salesforce 和 Intuit 等巨头将人工智能融入主流企业解决方案&#xff1b;从文案写作到数据分析&#xff0c;专门的人工智能应用程序和服务如雨后春笋般涌现&#…

LangFlow技术深度解析:可视化编排LangChain应用的新范式 -(2)流编辑器系统

Flow Editor System | langflow-ai/langflow | DeepWiki 流编辑器系统 相关源文件 流编辑器系统是 Langflow 的核心交互式组件&#xff0c;允许用户直观地创建、编辑和管理 LLM 驱动的应用程序。它提供了一个直观的画布&#xff0c;用户可以在其中添加节点、将其与边缘连接并…

驱动-定时-秒-字符设备

文章目录 目的相关资料参考实验驱动程序-timer_dev.c编译文件-Makefile测试程序-timer.c分析 加载驱动-运行测试程序总结 目的 通过定时器timer_list、字符设备、规避竞争关系-原子操作&#xff0c;综合运用 实现一个程序&#xff0c;加深之前知识的理解。 实现字符设备驱动框…

[Java实战]Spring Boot整合Kafka:高吞吐量消息系统实战(二十七)

[Java实战]Spring Boot整合Kafka&#xff1a;高吞吐量消息系统实战&#xff08;二十七&#xff09; 一、引言 Apache Kafka作为一款高吞吐量、低延迟的分布式消息队列系统&#xff0c;广泛应用于实时数据处理、日志收集和事件驱动架构。结合Spring Boot的自动化配置能力&…

Kotlin Multiplatform--04:经验总结(持续更新)

Kotlin Multiplatform--04&#xff1a;经验总结&#xff08;持续更新&#xff09; 引言 引言 本章用来记载笔者开发过程中的一些经验总结 一、Ktor设置Header 在官方文档中&#xff0c;想要设置Header的示例代码如下&#xff1a; client.get("https://ktor.io&qu…

在 Ubuntu 系统中,将 JAR 包安装为服务

在 Ubuntu 系统中&#xff0c;将 JAR 包安装为服务可以通过 systemd 来实现。以下是详细的操作步骤&#xff1a; 准备工作 确保 JAR 文件路径和 Java 运行时环境已准备好。验证 Java 是否可用&#xff1a; java -version创建 systemd 服务文件 systemd 的服务文件通常位于 …

电商项目-商品微服务-品牌管理微服务开发

一、功能分析 品牌管理微服务包括&#xff1a; &#xff08;1&#xff09;查询全部列表数据 &#xff08;2&#xff09;根据ID查询实体数据 &#xff08;3&#xff09;增加 &#xff08;4&#xff09;修改 &#xff08;5&#xff09;删除 &#xff08;6&#xff09;分页…

Spring Boot开发—— 整合Lucene构建轻量级毫秒级响应的全文检索引擎

文章目录 一、为什么选择 Lucene?轻量级搜索的底层密码二、核心原理:Lucene 的倒排索引2.1 倒排索引:速度之源2.2 段合并优化策略三、Spring Boot集成Lucene实战3.1 依赖配置3.2 实体与索引设计3.3 核心索引服务(含异常处理)3.4 使用示例(测试类)四、高级优化技巧4.1 索…

SpringBootDay1|面试题

目录 一、springboot框架 1、什么是springboot 2、Spring Boot的主要优点 3、springboot核心注解 4、定义banner&#xff08;springboot的logo&#xff09; 5、springboot配置文件 6、springboot 整合 jdbc 二、面试题 1&#xff09;springmvc的作用 ​编辑 2&#x…

jQuery Ajax中dataType 和 content-type 参数的作用详解

jQuery Ajax中dataType与contentType参数解析 一、核心概念对比 参数作用对象数据类型默认值dataType响应数据预期接收的数据格式jQuery自动判断&#xff08;根据响应头MIME类型&#xff09;contentType请求数据发送数据的编码格式application/x-www-form-urlencoded 二、da…

几款常用的虚拟串口模拟器

几款常用的虚拟串口模拟器&#xff08;Virtual Serial Port Emulator&#xff09;&#xff0c;适用于 Windows 系统&#xff0c;可用于开发和调试串口通信应用&#xff1a; 1. com0com (开源免费) 特点&#xff1a; 完全开源免费&#xff0c;无功能限制。 可创建多个虚拟串口…