upload-labs通关笔记-第20关 文件上传之杠点绕过
系列目录
upload-labs通关笔记-第1关 文件上传之前端绕过(3种渗透方法)
upload-labs通关笔记-第2关 文件上传之MIME绕过-CSDN博客
upload-labs通关笔记-第3关 文件上传之黑名单绕过-CSDN博客
upload-labs通关笔记-第4关 文件上传之.htacess绕过-CSDN博客
upload-labs通关笔记-第5关 文件上传之.ini绕过-CSDN博客
upload-labs通关笔记-第6关 文件上传之大小写绕过-CSDN博客
upload-labs通关笔记-第7关 文件上传之空格绕过-CSDN博客
upload-labs通关笔记-第8关 文件上传之点绕过-CSDN博客
upload-labs通关笔记-第9关 文件上传之::$data绕过-CSDN博客
upload-labs通关笔记-第10关 文件上传之点多重过滤(空格点绕过)
upload-labs通关笔记-第11关 文件上传之双写绕过-CSDN博客
upload-labs通关笔记-第12关 文件上传之白名单GET法绕过
upload-labs通关笔记-第13关 文件上传之白名单POST法绕过
upload-labs通关笔记-第14关 文件上传之图片马文件头绕过
upload-labs通关笔记-第15关 文件上传之图片马getimagesize绕过
upload-labs通关笔记-第16关 文件上传之图片马exif_imagetype绕过
upload-labs通关笔记-第17关文件上传之二次渲染-CSDN博客
upload-labs通关笔记-第18关文件上传之条件竞争-CSDN博客
upload-labs通关笔记-第19关文件上传之条件竞争-CSDN博客
upload-labs通关笔记-第20关 文件上传之杠点绕过-CSDN博客
upload-labs通关笔记-第21关 文件上传之数组绕过-CSDN博客
目录
一、pathinfo函数
二、move_uploaded_file函数
三、代码审计
1、流程分析
2、渗透思路
(1)方法一
(2)方法二
A.类 Unix 系统示例
B.Windows 系统示例
四、渗透实战
1、制作脚本test20.php
2、浏览图片
3、bp开启拦截
4、点击上传
5、bp拦截
6、save_name文件名修改
7、发包并获取脚本地址
8、访问脚本
本文通过《upload-labs靶场通关笔记系列》来进行upload-labs靶场的渗透实战,本文讲解upload-labs靶场第20关图片马之杠点绕过渗透实战。
一、pathinfo函数
pathinfo是 PHP 中的一个内置函数,其作用是返回文件路径的信息。借助这个函数,你能够提取出文件路径里的不同部分,像目录名、文件名、扩展名等。
pathinfo(string $path, int $options = PATHINFO_ALL): mixed
(1)参数说明
参数 | 类型 | 说明 |
---|---|---|
$path | string | 要解析的文件路径 |
$options | int | 可选参数,指定返回的信息部分 |
(2)返回值
-
当不指定
$options
时,返回包含所有信息的关联数组 -
当指定
$options
时,返回指定部分的字符串
(3)使用示例
假设path为/var/html/www/test20.php,那么使用示例如下所示。
// 只获取目录名
echo pathinfo($path, PATHINFO_DIRNAME); // 输出:/var/html/www/// 只获取文件名(带扩展名)
echo pathinfo($path, PATHINFO_BASENAME); // 输出:test20.php// 只获取文件扩展名
echo pathinfo($path, PATHINFO_EXTENSION); // 输出:php// 只获取文件名(不带扩展名)
echo pathinfo($path, PATHINFO_FILENAME); // 输出:test20
二、move_uploaded_file函数
move_uploaded_file是 PHP 中的一个重要函数,主要用于将通过 HTTP POST 上传的临时文件移动到指定的目标位置。在处理文件上传时,它起到了关键作用。
move_uploaded_file ( string $from , string $to ) : bool
(1)参数说明
$from
:这是必需的参数,代表上传文件在服务器上的临时存储路径。通常,我们可以从$_FILES
数组中获取这个临时文件的路径,例如$_FILES['upload_file']['tmp_name']
。$to
:同样是必需参数,指定了文件要被移动到的目标路径,也就是文件最终保存的位置。这个路径需要包含文件名。
(2)返回值
如果文件成功从临时位置移动到指定的目标位置,函数返回 true
;反之,如果移动过程中出现问题,比如目标路径不可写、临时文件不存在等,函数将返回 false
。
(3)安全性
move_uploaded_file是 PHP 中用于处理文件上传的函数,其安全性主要体现验证文件是否为合法上传文件,move_uploaded_file会检查指定的文件是否是通过 HTTP POST 上传的合法文件,这可以防止攻击者尝试移动服务器上已有的文件(如 /etc/passwd
)或通过其他方式创建的文件。
三、代码审计
打开靶场第20关,本关卡又恢复为通过后缀过滤黑名单的检测方法,具体源码如下所示。
这段代码实现了一个简单的文件上传功能,并且对上传的文件类型进行了限制,详细版注释如下所示。
// 初始化上传状态标志,默认设置为 false,表示文件未成功上传
$is_upload = false;
// 初始化消息变量,用于存储上传过程中的提示信息,初始值为 null
$msg = null;// 检查是否通过 POST 方式提交了名为 submit 的表单数据
if (isset($_POST['submit'])) {// 检查指定的上传目录是否存在if (file_exists(UPLOAD_PATH)) {// 定义一个数组,包含不允许上传的文件扩展名$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");// 从 POST 数据中获取用户指定的保存文件名$file_name = $_POST['save_name'];// 使用 pathinfo 函数提取文件名中的扩展名$file_ext = pathinfo($file_name, PATHINFO_EXTENSION);// 检查提取的文件扩展名是否不在禁止上传的扩展名数组中if (!in_array($file_ext, $deny_ext)) {// 获取上传文件在服务器上的临时存储路径$temp_file = $_FILES['upload_file']['tmp_name'];// 拼接上传文件的完整保存路径,包括上传目录和文件名$img_path = UPLOAD_PATH . '/' . $file_name;// 尝试将临时文件移动到指定的保存路径if (move_uploaded_file($temp_file, $img_path)) {// 如果移动成功,将上传状态标志设置为 true$is_upload = true;} else {// 如果移动失败,设置提示消息,表明上传出错$msg = '上传出错!';}} else {// 如果文件扩展名在禁止上传的数组中,设置提示消息,禁止保存该类型文件$msg = '禁止保存为该类型文件!';}} else {// 如果上传目录不存在,设置提示消息,告知用户手动创建该目录$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}
1、流程分析
- 初始化变量:设置上传状态标志
$is_upload
为false
,并初始化消息变量$msg
为null
。 - 检查表单提交:当用户通过 POST 方式提交名为
submit
的表单时,开始处理上传逻辑。 - 检查上传目录:检查指定的上传目录
UPLOAD_PATH
是否存在。如果不存在,提示用户手动创建该目录。 - 文件类型检查:定义一个包含不允许上传的文件扩展名的数组
$deny_ext
。从用户指定的保存文件名中通过pathinfo($path, PATHINFO_EXTENSION)函数提取扩展名,并检查该扩展名是否在禁止列表中。如果在禁止列表中,提示用户禁止保存该类型文件。
$file_name = $_POST['save_name'];
$file_ext = pathinfo($file_name, PATHINFO_EXTENSION);
- 文件上传:如果文件扩展名不在禁止列表中,获取上传文件的临时存储路径,并使用move_uploaded_file函数将其移动到指定的保存路径。如果移动成功,将上传状态标志设置为
true
;否则,提示用户上传出错。
$temp_file = $_FILES['upload_file']['tmp_name'];// 获取上传文件在服务器上的临时存储路径
$img_path = UPLOAD_PATH . '/' . $file_name; // 拼接上传文件完整保存路径,包括上传目录和文件名
if (move_uploaded_file($temp_file, $img_path)){// 尝试将临时文件移动到指定的保存路径$is_upload = true;// 如果移动成功,将上传状态标志设置为 true
} else {$msg = '上传出错!';// 如果移动失败,设置提示消息,表明上传出错
}
2、渗透思路
(1)方法一
黑名单未检查大小写、没有尾部去空,没有尾部去点,也没有尾部去::$data等处理逻辑,故而可以使用upload-labs靶场的第6关卡、第7关卡、第8关卡和第九关的渗透方法绕过。假设计划上次脚本test.php,那么渗透方法包括如下方法
- 大小写变体:将文件save_name名重命名为"test.pHP"
- 文件名尾部增加空格:bp改包,将save_name文件名改为"test.php "
- 文件名尾部增加点:bp改包,将save_name文件名改为"test.php."
- 文件名尾部增加::$data:bp改包,将save_name文件名改为"test.php::$data"
(2)方法二
- 修改save_name为test.php/.此时调用pathinfo会认为后缀名为空,非黑名单后缀,绕过了黑名单检查,具体如下所示。
$file_name = $_POST['save_name'];
$file_ext = pathinfo($file_name, PATHINFO_EXTENSION);
- 文件名为test.php/.由于函数move_uploaded_file会忽略/.故而上传后的文件名为test.php从而渗透成功
// 获取上传文件在服务器上的临时存储路径$temp_file = $_FILES['upload_file']['tmp_name'];// 拼接上传文件的完整保存路径,包括上传目录和文件名$img_path = UPLOAD_PATH . '/' . $file_name;// 尝试将临时文件移动到指定的保存路径if (move_uploaded_file($temp_file, $img_path)){$is_upload = true;// 如果移动成功,将上传状态标志设置为 true} else {$msg = '上传出错!';// 如果移动失败,设置提示消息,表明上传出错}
A.类 Unix 系统示例
在类 Unix 系统(如 Linux、macOS)和 Windows 系统中,都存在特定的路径解析规则。单个点号(.)在路径中代表当前目录。所以当路径里包含 /. 时,系统会把它理解为当前目录,从而在路径解析过程中 “忽略” 它。 在类 Unix 系统的 shell 中,下面这些路径是等价的:
/path/to/dir/.
/path/to/dir
当你使用 cd /path/to/dir/.
和 cd /path/to/dir
时,效果是一样的,都会进入 /path/to/dir
目录。
B.Windows 系统示例
Windows 系统在路径解析上也有类似规则。例如,在命令提示符中输入 cd C:\Users\Admin\.
和 cd C:\Users\Admin
,最终都会进入 C:\Users\Admin
目录。
四、渗透实战
1、制作脚本test20.php
<?
phpphpinfo();
?>
2、浏览图片
进入靶场20关,选择test20.php,注意下面保存名称默认为upload-19.jpg,具体如下所示。
3、bp开启拦截
4、点击上传
5、bp拦截
bp捕获到上传报文,下图红框的部分涉及到两个文件名,其中根据源码分析我们指导save_name即为需要修改的文件名upload-19.jpg,需要将"upload-19.jpg"后缀改为"upload-20.php/.",修改之前文件名为"upload-19.jpg",如下所示
6、save_name文件名修改
upload-19.jpg改为"upload-20.php/.",修改后效果如下所示。
7、发包并获取脚本地址
将bp的inception设置为off,此时修改后的报文发送成功。
回到靶场的Pass20关卡,图片已经上传成功,在图片处右键复制图片地址。
右键图片获取图片地址,如下所示获取到图片URL。
http://127.0.0.1/upload-labs/upload/upload-20.php/
8、访问脚本
如下所示访问上传脚本获取到服务器的php信息,证明文件上传成功。
相关文章:

upload-labs通关笔记-第20关 文件上传之杠点绕过
系列目录 upload-labs通关笔记-第1关 文件上传之前端绕过(3种渗透方法) upload-labs通关笔记-第2关 文件上传之MIME绕过-CSDN博客 upload-labs通关笔记-第3关 文件上传之黑名单绕过-CSDN博客 upload-labs通关笔记-第4关 文件上传之.htacess绕过-CSDN…...

Vscode +Keil Assistant编译报错处理
Vscode Keil Assistant编译报错处理 1.报错图片内容 所在位置 行:1 字符: 25 chcp.com 65001 -Command & c:\Users\92170.vscode\extensions\cl.keil-a … ~ 不允许使用与号(&)。& 运算符是为将来使用而保留的;请用双引号将与号引起来(“&”)&…...
记录python在excel中添加一列新的列
思路是,先将需要添加为新的列存储到一个暂时的列表中,然后用到以下函数来存储 data_.loc[:, "新列的名字"] save_list_ 上面的save_list_就是暂时存储了信息的列表了。 以下是我的代码,供以后快速回忆。 schools_data {"98…...
WebRTC:实时通信的未来之路
WebRTC:实时通信的未来之路 目录 WebRTC:实时通信的未来之路一、背景介绍二、使用方式三、前途展望 一、背景介绍 随着互联网的飞速发展,实时音视频通信需求日益增长。传统的音视频通信多依赖于专有协议和插件(如Flash、ActiveX等…...
探索产品经理的MVP:从概念到实践
在产品开发的世界里,MVP(Minimum Viable Product,最小可行产品)是一个至关重要的概念。它不仅帮助团队快速验证假设,还能降低失败风险,为后续的产品迭代奠定坚实的基础。本文将深入探讨MVP的概念、重要性及…...
用python实现中国象棋
一.象棋规则 象棋是二人对弈的棋类游戏,棋盘由 9 条竖线和 10 条横线交叉构成,中间 “河界” 分楚汉,两端 “九宫” 各 9 个交叉点。棋子分红黑,各 16 枚,含 7 兵种。 1.棋子走法 1.1 红方棋子 帅:1 个…...
GO 语言基础3 struct 结构体
更多个人笔记见: github个人笔记仓库 gitee 个人笔记仓库 个人学习,学习过程中还会不断补充~ (后续会更新在github上) 文章目录 strcut结构体基本例子传入数值和指针的区别初始化方法汇总结构体特点结构体方法定义基于…...

VSCode C/C++ 开发环境完整配置及一些扩展用途(自用)update:2025/3/31
这里主要记录了一些与配置相关的内容。由于网上教程众多,部分解决方法并不能完全契合我遇到的问题,因此我选择以自己偏好的方式,对 VSCode 进行完整的配置,并记录在使用过程中遇到的问题及解决方案。后续内容也会持续更新和完善。…...
iOS 上线前的性能与稳定性检查流程实录:开发者的“最后一公里”(含 KeyMob 应用经验)
一个 iOS 项目写完功能、跑完测试,离上线只差一步了——但很多问题恰恰就在“这最后一公里”暴露:某些设备发热严重,部分流程偶发卡顿,某些崩溃只有长时间运行后才出现。 今天我分享的是我在多个 iOS 项目上线前实际执行过的性能…...

Docker系列(二):开机自启动与基础配置、镜像加速器优化与疑难排查指南
引言 docker 的快速部署与高效运行依赖于两大核心环节:基础环境搭建与镜像生态优化。本期博文从零开始,系统讲解 docker 服务的管理配置与镜像加速实践。第一部分聚焦 docker 服务的安装、权限控制与自启动设置,确保环境稳定可用;…...

a16z:AI带来了全新的9种开发软件的模式
非常有启发的9条新兴模式,推荐给已经上手 vibeCoding 的读者们。 开发者正在将 AI 从简单的工具转变为构建软件的新基础。许多核心概念,如版本控制、模板、文档,甚至用户的定义,都在被重新思考。代理(Agent)…...
20.迭代器模式:思考与解读
原文地址:迭代器模式:思考与解读 更多内容请关注:深入思考与解读设计模式 引言 在软件开发中,尤其是在处理集合数据时,你是否曾经遇到过这样的问题:你需要遍历一个集合(如数组、列表、集合等)…...
Java 学习笔记:注解、泛型与 IO 流
目录 课程目标 Java 注解(Annotation) 1. 概念与作用 2. 自定义注解示例 3. JDK 内置注解 4.注释 Java 泛型(Generics) 1. 基本语法 2. 通配符与上下限 3. 常见应用场景 Java IO 流 1. 流的分类1.File文件类 2. 字节流与字符流 3. 经典示例:文件拷贝 总结与…...

在 Excel 使用macro————仙盟创梦IDE
Dim filePath As StringDim fileContent As StringDim lines() As StringDim dataArray() As StringDim lineCount As LongDim maxCols As LongDim i As Long, j As Long 文件路径filePath "" 检查文件是否存在If Dir(filePath) "" ThenMsgBox "文件…...
【MySQL】08.视图
视图就是一个由查询到的内容定义的虚拟表。它和真实的表一样,视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表,基表的数据变化也会影响到视图。 1. 基本使用 mysql> select * from user; -------------------- | id | age | name …...

鸿蒙devEco studio如何创建模拟器
官网原文链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-emulator-create 操作步骤 点击菜单栏的Tools > Device Manager,点击右下角的Edit设置模拟器实例的存储路径Local Emulator Location,Mac默认存储在~/…...

鸿蒙路由参数传递
页面test.ets 代码如下: import router from ohos.router Entry Component struct Test {State message: string Hello WorldState username: string huState password: string 1build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWe…...

springboot 控制层调用业务逻辑层,注入报错,无法自动装配 解决办法
报错: 解决:愿意是业务逻辑层,即service层的具体实现类没有加注解Service导致的,加上解决了!!...

MySQL:11_事务
事务 一.CURD不加控制,会有什么问题? 二.什么是事务? 事务就是一组DML语句组成,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部失败,是一个整体。MySQL提供一种机制…...

Linux中的文件系统和软硬连接
磁盘的访问方式 CHS(柱面,磁头,扇区) 法(磁盘硬件查找): 确定柱面(C) 磁头臂移动到对应的柱面位置。例如,柱面号为 5,则磁头移动到第 5 个磁道组…...
并发容器(Collections)
一、并发安全问题根源 1. List(如ArrayList) 问题表现:多线程同时调用add、remove等方法时,可能抛出ConcurrentModificationException或导致数据不一致。根本原因: 非原子性操作:如add操作的流程…...
SPA模式下的es6如何加快宿主页的显示速度
SPA的模式下,宿主页是首先加载的页面,会需要一些主要的组件,如element-plus,easyui,devextreme,ant-design等,这些组件及其依赖组件,文件多,代码量大,可能导致…...
windows powershell 判断 进程号是否存在
在 Windows PowerShell 中,你可以使用多种方法来检查一个特定的进程号(PID)是否存在。以下是几种常用的方法: 方法1:使用 Get-Process 命令 你可以尝试获取具有特定 PID 的进程。如果该进程存在,Get-Proce…...
c# 解码 encodeURIComponent
在C#中,如果你需要解码由encodeURIComponent方法编码的URL,你可以使用System.Web命名空间中的HttpUtility.UrlDecode方法。这个方法可以处理由JavaScript的encodeURIComponent方法编码的字符串。 首先,确保你的项目中引用了System.Web命名空…...

Spring AI:Java开发者的AI开发新利器
目录 一、引言 二、Spring AI 是什么 三、核心功能与特性 3.1 统一的 API 抽象 3.2 丰富的模型支持 3.3 低代码集成 3.4 结构化数据输出 3.5 流式数据响应 四、应用场景 4.1 智能客服系统 4.2 图像识别应用 4.3 数据分析与预测 五、快速上手 5.1 环境搭建 5.2 创…...
Android System UI 深度解析:从架构演进到车载 / TV 场景的全维度定制
Android System UI 是 Android 操作系统的核心组件,负责管理设备的系统级用户界面和交互逻辑。它通过状态栏、导航栏、通知面板、快速设置等功能,为用户提供与系统功能直接交互的入口,并与硬件、应用程序深度协同,构建完整的用户体验。以下是其核心架构、功能演进及定制化能…...

Spring Cloud Sleuth与Zipkin深度整合指南:微服务链路追踪实战
上篇文章简单介绍了SpringCloud系列熔断器:Sentinel的搭建及基本用法,今天继续讲解下SpringCloud的微服务链路追踪:Zipkin的使用!在分享之前继续回顾下本次SpringCloud的专题要讲的内容: 前置知识说明 在开始本教程前…...
React从基础入门到高级实战:React 基础入门 - 列表渲染与条件渲染
列表渲染与条件渲染 在 React 开发中,列表渲染 和 条件渲染 是处理动态数据和用户交互的基础技术。通过列表渲染,你可以根据数据动态生成 UI 元素;而条件渲染则让你根据特定条件展示不同的内容。这两个技能在实际项目中非常常见,…...
在 stm32 中 volatile unsigned signed 分别有什么作用,分别在什么场景下使用?
在STM32开发中, plaintext 复制 volatile 、 plaintext 复制 unsigned 和 plaintext 复制 signed 是三个关键的关键字,它们的用途和场景如下: 1. plaintext 复制 volatile 关键字 作用: 禁止编译器优化ÿ…...
FreeBSD14.2因为爆内存而导致Xfce4视窗被卡,桌面变黑色,只能看到鼠标在窗体中心,鼠标无反应,键盘无反应
拿问题问AI pytest的时候因为内存不足导致xfce4卡住(xfce4相关进程被关闭),桌面变黑色,只能看到鼠标在窗体中心,鼠标无反应,键盘无反应,请问应该怎么办? pytest的时候因为内存不足导…...