upload-Labs靶场“11-15”关通关教程
君衍.
- 一、第十一关 %00截断GET上传
- 1、源码分析
- 2、%00截断GET上传
- 二、第十二关 %00截断POST上传
- 1、源码分析
- 2、%00截断POST上传
- 三、第十三关 文件头检测绕过
- 1、源码分析
- 2、文件头检测绕过
- 四、第十四关 图片检测绕过上传
- 1、源码分析
- 2、图片马绕过上传
- 五、第十五关 图片检测绕过上传
- 1、源码分析
- 2、图片马绕过上传
upload-Labs靶场“1-5”关通关教程
一、第十一关 %00截断GET上传
1、源码分析
$is_upload = false;
$msg = null;
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类型文件!";}
}
添加注释解读:
$is_upload = false;
$msg = null;
# 检查是否有名为 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'];# 构建目标文件路径 $img_path,使用 rand(10, 99) 生成两位随机数和当前日期时间$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;# 使用 move_uploaded_file($temp_file, $img_path) 将上传的文件移动到目标路径if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = '上传出错!';}} else{$msg = "只允许上传.jpg|.png|.gif类型文件!";}
}
代码中使用白名单限制上传的文件后缀名,只允许指定的图片格式。但是
$_GET['save_path']
服务器接受客户端的值,这个值可被客户端修改。
2、%00截断GET上传
这里我们便将上传参数更改:
更改掉之后就会将1.jpg覆盖给1.php通过%00进行截断,即为1.php%001.jpg变为1.php:
然后访问执行即可。
二、第十二关 %00截断POST上传
1、源码分析
$is_upload = false;
$msg = null;
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 = $_POST['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类型文件!";}
}
添加注释解读代码:
$is_upload = false;
$msg = null;
# 检查是否有名为 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'];# 构建目标文件路径 $img_path,使用 rand(10, 99) 生成两位随机数和当前日期时间$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;# 这里使用 $_POST['save_path'] 构建目标文件路径,而不是之前的 $_GET['save_path']# 将上传的文件移动到目标路径if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传失败";}} else {$msg = "只允许上传.jpg|.png|.gif类型文件!";}
}
这段代码同样是白名单限制后缀名,$_POST['save_path']
是接收客户端提交的值,客户端可任意修改。所以会产生安全漏洞。
2、%00截断POST上传
这里我们同十一关一样,通过抓包修改参数,使用%00进行截断文件名,在GET传参中是可以使用的,但是这里是POST,所以我们使用decode编码:
将%00进行编码:
我们可以看到这里上传成功,然后我们访问图像链接来执行:
即可完成上传。
三、第十三关 文件头检测绕过
1、源码分析
function getReailFileType($filename){$file = fopen($filename, "rb");$bin = fread($file, 2); //只读2字节fclose($file);$strInfo = @unpack("C2chars", $bin); $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); $fileType = ''; switch($typeCode){ case 255216: $fileType = 'jpg';break;case 13780: $fileType = 'png';break; case 7173: $fileType = 'gif';break;default: $fileType = 'unknown';} return $fileType;
}$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$temp_file = $_FILES['upload_file']['tmp_name'];$file_type = getReailFileType($temp_file);if($file_type == 'unknown'){$msg = "文件未知,上传失败!";}else{$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}
添加注释解读以上代码:
# 用于获取文件的真实类型
function getReailFileType($filename){# 打开文件并读取前两个字节$file = fopen($filename, "rb");$bin = fread($file, 2); //只读2字节fclose($file);# 使用 unpack 函数将二进制数据解析为数组 $strInfo# 每个字节被解析为一个无符号字符(C),总共解析两个字节$strInfo = @unpack("C2chars", $bin); # 将解析后的两个字节拼接成一个整数,存储在 $typeCode 中$typeCode = intval($strInfo['chars1'].$strInfo['chars2']); # 初始化变量 $fileType 为空字符串$fileType = '';# 根据 $typeCode 的值执行不同的操作 switch($typeCode){ case 255216: $fileType = 'jpg';break;case 13780: $fileType = 'png';break; case 7173: $fileType = 'gif';break;default: $fileType = 'unknown';} return $fileType;
}$is_upload = false;
$msg = null;
# 检查是否接收到名为 submit 的 POST 请求
if(isset($_POST['submit'])){# 获取上传文件的临时文件路径$temp_file = $_FILES['upload_file']['tmp_name'];# 调用之前定义的 getReailFileType 函数获取上传文件的真实类型$file_type = getReailFileType($temp_file);# 检查文件类型是否为 'unknown'if($file_type == 'unknown'){$msg = "文件未知,上传失败!";}else{# 构建目标文件路径,包括上传路径、随机生成的文件名和文件扩展名$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;# 将临时文件移动到目标路径if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}
上传时候会检测头文件,不同的文件,头文件也不尽相同。常见的文件上传图片头检测 它检测图片是两个字节的长度,如果不是图片的格式,会禁止上传。
常见的文件头
JPEG (jpg),文件头:FFD8FF
PNG (png),文件头:89504E47
GIF (gif),文件头:47494638
TIFF (tif),文件头:49492A00
Windows Bitmap (bmp),文件头:424D
2、文件头检测绕过
首先我们创建图片马:
copy 1.gif/b+1.php shell.gif
copy 图片文件/b + 敏感文本文件 web.jpg
将 php 文件附加在gif图片上,直接上传即可
直接上传这里利用文件包含漏洞来执行:
复制文件链接,然后利用文件上传漏洞访问执行:
http://192.168.217.130/up/include.php?file=http://192.168.217.130/up/upload/1620240301170724.gif
我们即可看到执行成功。
当然,我们也可以直接加上GIF89a
我们上传一个木马,同时进行抓包:
改为:
放通后进行访问执行:
即可看到执行成功。
四、第十四关 图片检测绕过上传
1、源码分析
function isImage($filename){$types = '.jpeg|.png|.gif';if(file_exists($filename)){$info = getimagesize($filename);$ext = image_type_to_extension($info[2]);if(stripos($types,$ext)>=0){return $ext;}else{return false;}}else{return false;}
}$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$temp_file = $_FILES['upload_file']['tmp_name'];$res = isImage($temp_file);if(!$res){$msg = "文件未知,上传失败!";}else{$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}
使用注释解读代码:
# 检查文件是否为图片
function isImage($filename){# 定义了允许上传的图片文件类型$types = '.jpeg|.png|.gif';# 检查指定的文件是否存在if(file_exists($filename)){# 获取文件的基本信息,包括图片的宽度、高度以及图像类型等$info = getimagesize($filename);# 将图像类型转换为对应的文件扩展名$ext = image_type_to_extension($info[2]);# 用 stripos 函数检查文件扩展名是否在允许的类型列表中if(stripos($types,$ext)>=0){return $ext;}else{return false;}}else{return false;}
}$is_upload = false;
$msg = null;
# 检查是否接收到名为 submit 的 POST 请求
if(isset($_POST['submit'])){# 获取上传文件的临时文件路径$temp_file = $_FILES['upload_file']['tmp_name'];# 调用 isImage 函数检查上传文件是否为图片$res = isImage($temp_file);# 如果上传文件不是图片输出if(!$res){$msg = "文件未知,上传失败!";}else{# 构建目标文件路径,包括上传路径、随机生成的文件名和文件扩展名$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res;# 将临时文件移动到目标路径if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}
2、图片马绕过上传
源码中使用getimagesize
来获取图片的大小,如果头文件不是图片直接报错,所以我们可以直接使用图片马绕过检测。
然后直接使用文件包含漏洞访问执行:
即可看到成功上传并执行。
五、第十五关 图片检测绕过上传
1、源码分析
function isImage($filename){//需要开启php_exif模块$image_type = exif_imagetype($filename);switch ($image_type) {case IMAGETYPE_GIF:return "gif";break;case IMAGETYPE_JPEG:return "jpg";break;case IMAGETYPE_PNG:return "png";break; default:return false;break;}
}$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$temp_file = $_FILES['upload_file']['tmp_name'];$res = isImage($temp_file);if(!$res){$msg = "文件未知,上传失败!";}else{$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}
添加注释解读以上代码:
function isImage($filename){// 需要开启php_exif模块$image_type = exif_imagetype($filename); // 获取图片的类型switch ($image_type) { // 根据图片类型执行不同的操作case IMAGETYPE_GIF:return "gif"; // 如果是 GIF 类型的图片,返回 "gif"break;case IMAGETYPE_JPEG:return "jpg"; // 如果是 JPEG 类型的图片,返回 "jpg"break;case IMAGETYPE_PNG:return "png"; // 如果是 PNG 类型的图片,返回 "png"break; default:return false; // 如果不是上述类型的图片,则返回 falsebreak;}
}$is_upload = false; // 初始化变量,用于表示文件是否上传成功,默认为 false
$msg = null; // 初始化变量,用于存储错误消息,默认为 nullif(isset($_POST['submit'])){ // 检查是否接收到名为 'submit' 的 POST 请求,表示用户提交了表单$temp_file = $_FILES['upload_file']['tmp_name']; // 获取上传文件的临时文件路径$res = isImage($temp_file); // 调用 isImage 函数检查上传文件是否为图片if(!$res){ // 如果上传文件不是图片,则执行以下操作$msg = "文件未知,上传失败!"; // 将错误消息设置为 "文件未知,上传失败!"}else{ // 如果上传文件是图片,则执行以下操作$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res; // 构建目标文件路径,包括上传路径、随机生成的文件名和文件扩展名if(move_uploaded_file($temp_file,$img_path)){ // 将临时文件移动到目标路径,如果移动成功,则执行以下操作$is_upload = true; // 设置文件上传状态为完成} else { // 如果移动文件失败,则执行以下操作$msg = "上传出错!"; // 将错误消息设置为 "上传出错!"}}
}
2、图片马绕过上传
第十五关同样进行判断是否为图片,所以同十四关相同:
然后直接使用文件包含漏洞访问执行:
即可看到成功上传并执行。
相关文章:

upload-Labs靶场“11-15”关通关教程
君衍. 一、第十一关 %00截断GET上传1、源码分析2、%00截断GET上传 二、第十二关 %00截断POST上传1、源码分析2、%00截断POST上传 三、第十三关 文件头检测绕过1、源码分析2、文件头检测绕过 四、第十四关 图片检测绕过上传1、源码分析2、图片马绕过上传 五、第十五关 图片检测绕…...
linux-rpm命令
rpm命令管理程序包:安装、升级、卸载、查询和校验 1、忽略依赖关系安装/卸载包 安装:rpm -Uvh 软件包名 --nodeps 卸载:rpm -e 软件包名 --nodes!!!!慎用!!!…...
如何利用python实现自己的modbus-tcp库
如果你想使用纯Socket编程来实现Modbus TCP通讯,而不是依赖于Modbus库,你需要理解Modbus TCP协议的细节,并能够手动构建和解析Modbus消息。以下是一个简单的示例,展示了如何使用Python的socket库来实现Modbus TCP通讯: 了解Modbus TCP协议: Modbus TCP协议使用TCP作为底层…...

linux系统-----------搭建LNMP 架构
PHP(Hypertext Preprocessor 超文本预处理器)是通用服务器端脚本编程语言,主要用于web开发实现动态web页面,也是最早实现将脚本嵌入HTML源码文档中的服务器端脚本语言之一。同时,php还提供了一个命令行接口,因此,其也可…...
C++中boost库的安装及使用(Windows)
Boost库的安装及使用 引言使用现有的boost库安装及使用引言 C++开发中经常会用到boost库,本文记录一下Windows上boost在visual studio2019上的使用。 Boost库是一个跨平台的C++库集合,旨在为C++开发者提供一系列高质量的通用功能。不同的Visual Studio(VS)版本并不要求安…...

CPP编程-CPP11中的内存管理策略模型与名称空间管理探幽(时隔一年,再谈C++抽象内存模型)
CPP编程-CPP11中的内存管理策略模型与名称空间管理探幽 CPP的四大内存分区模型 在 C 中,**内存分区是一种模型,用于描述程序运行时内存的逻辑组织方式,但在底层操作系统中,并不存在严格意义上的内存分区。**操作系统通常将内存分…...
springboot项目整合minio实现文件的分布式存储
minio是一款分布式存储系统,上一篇详细介绍了minio在windows环境下的搭建集群并通过nginx实现负载均衡,这里简单介绍下springboot项目整合minio并实现文件的上传下载删除等操作。 一、依赖的引入 1.1、maven项目 <dependency><groupId>io…...

微信小程序开发学习笔记《19》uni-app框架-配置小程序分包与轮播图跳转
微信小程序开发学习笔记《19》uni-app框架-配置小程序分包与轮播图跳转 博主正在学习微信小程序开发,希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读uni-app对应官方文档 一、配置小程序分包 分包可以减少小程序首次启动时的加载时间 为此&#…...

Python内置模块
目录 什么是模块 模块分类 通过模块创建者分类 系统内置模块 第三方模块 在线安装 离线安装 模块导入 math和random模块介绍 math模块 random模块 什么是模块 在我们编写程序时,需要导入包。例如随机数的产生,需要import random。import XXX&…...

WordPress建站入门教程:小皮面板phpstudy如何安装PHP和切换php版本?
小皮面板phpstudy支持的PHP版本有很多,包括5.2.17、5.3.29、5.4.45、5.5.9、5.6.9、7.0.9、7.1.9、7.2.9、7.3.4、7.3.9、7.4.3、8.0.2、8.2.9。那么我们如何安装其他的php版本和切换网站的php版本呢?只需要简单几步即可,具体如下:…...
用友 NC saveDoc.ajax 任意文件上传漏洞复现
0x01 产品简介 用友NC是一款企业级ERP软件。作为一种信息化管理工具,用友NC提供了一系列业务管理模块,包括财务会计、采购管理、销售管理、物料管理、生产计划和人力资源管理等,帮助企业实现数字化转型和高效管理。 0x02 漏洞概述 用友 NC saveDoc.ajax接口处存在任意文件…...

如何使用达摩盘
目录 1.定义 2.功能:圈人群、画像洞察、同步到站内渠道投放; 1.定义 是阿里妈妈基于商业化营销场景打造的人群精细化运营定向中台,涵盖消费行为、兴趣偏好、地理位置等海量数据标签,为商家提供个性化人群圈选,识别店…...

网络编程的学习
思维导图 多路复用代码练习 select完成TCP并发服务器 #include<myhead.h> #define SER_IP "192.168.125.73" //服务器IP #define SER_PORT 8888 //服务器端口号int main(int argc, const char *argv[]) {//1、创建用于监听的套接字int sfd -1;s…...

【Mining Data】收集数据(使用 Python 挖掘 Twitter 数据)
@[TOC](【Mining Data】收集数据(使用 Python 挖掘 Twitter 数据)) 具体步骤 第一步是注册您的应用程序。特别是,您需要将浏览器指向 http://apps.twitter.com,登录 Twitter(如果您尚未登录)并注册新应用程序。您现在可以为您的应用程序选择名称和描述(例如“Mining Demo”…...

2024京津冀光伏展
2024年京津冀光伏展是一个专门展示京津冀地区光伏产业发展情况的展览会。光伏产业是指利用太阳能进行发电的产业,它在可再生能源领域具有重要的地位。京津冀地区是中国重要的经济区域,也是光伏产业的发展热点地区之一。 2024年京津冀光伏展将展示京津冀地…...
在C#中使用Linq
在C#中使用Linq 前言一、基本查询操作二、高级查询操作三、数据库查询四、文件和 XML 查询五、总结 前言 LINQ(Language Integrated Query)是 C# 中一种强大的查询语言集成特性,它使得在编程语言级别对数据进行查询和操作变得更加简单和直观…...

Swing程序设计(11)动作事件监听器,焦点事件监听器
文章目录 前言一、事件监听器是什么?二、详细展开 1.动作事件监听器2.焦点事件监听器总结 前言 如果你是坚持从Swing程序第一篇看到了这里,恭喜你,Swing程序设计简单地落下了帷幕,关于Swing程序更深的了解,可以自行学习…...

Python 开发图形界面程序
用 Python 语言开发图形界面的程序,有2种选择: Tkinter 基于Tk的Python库,这是Python官方采用的标准库,优点是作为Python标准库、稳定、发布程序较小,缺点是控件相对较少。 PySide2/PySide6 基于Qt 的Python库&#x…...

百度搜索引擎SEO优化方法
随着互联网的不断发展,搜索引擎已经成为人们获取信息、产品和服务的主要途径之一。而在中国,百度作为最大的搜索引擎,其影响力不可忽视。了解并掌握百度SEO关键词优化方法,对于提升网站在搜索引擎中的排名至关重要。 关键词选择&a…...

一文了解docker与k8s
随着 k8s 作为容器编排解决方案变得越来越流行,有些人开始拿 Docker 和 k8s 进行对比,不禁问道:Docker 不香吗? k8s 是 kubernetes 的缩写,8 代表中间的八个字符。 其实 Docker 和 k8s 并非直接的竞争对手两者相互依存…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...