常规文件上传 – 传统上传
首先注意
无文件解析安全问题上,格式解析是一对一的(不能jpg解析php)
换句话来说有解析错误配置或后缀解析漏洞时才能实现格式差异解析
文件上传概念
文件上传安全指的是攻击者通过利用上传实现后门的写入连接后门进行权限控制的安全问题,对于如何确保这类安全问题,一般会从原生态功能中的文件内容,文件后缀,文件类型等方面判断,但是漏洞可能不仅在本身的代码验证逻辑中出现安全问题,也会在语言版本,语言函数,中间件,引用的第三方编辑器等存在缺陷地方配合利用。另外文件上传也有多个存储逻辑,不同的文件存储方案也会给攻击者带来不一样的挑战!
限制
- 无限制
任意上传,什么文件都能上传
- 有限制:
限制后缀格式(判断后缀名(黑白名单),MIME类型,文件头等)
测试环境安装 – upload-labs-docker
https://github.com/ffffffff0x/f8x
https://github.com/fuzzdb-project/fuzzdb
https://github.com/sqlsec/upload-labs-docker
限制绕过
前端JS验证
判断是否是前端验证
- 抓包监听,如果上传文件的时候还没有抓取到数据包,但是浏览器就提示文件类型不正确的话,那么这个多半就是前端校验了
- F12查看网络中js逻辑
绕过
- 本地修改表单后上传
源码在本地修改完后打开进行上传

- 抓包修改
抓包后将文件后缀改为 .php
然后把后门代码写入其中


最后发包即可上传
.htaccess(非常少)
.htaccess是apache中修改解析配置的文件
2个条件(缺一不可):目标服务器为apache服务器,并且要可以上传 .htaccess 文件
上传一个文件:.htaccess ,添加内容如下
作用:把png后缀的文件当做php来解析(在当前目录生效) — > 违背了格式解析的一对一关系
AddType application/x-httpd-php .png
然后上传一个带有后门的png后缀的文件,即可作为php解析
MIME类型
通过文件类型判断文件后缀
// 数据包字段内容
Content-Type:image/jpeg
后端通过判断数据包中Content-Type字段来识别是否符合上传要求
绕过方法:
上传后门php文件,抓包修改其Content-Type字段为符合要求的形式(image/png、image/jpeg)
文件头判断
通过文件头判断文件后缀
使用16进制编辑器(如010editer)查看文件,可以发现不同类型的文件头标识不一样
gif:GIF89a
png:PNG
zip:PK

绕过方法:
上传php后门文件(伪造文件头,文件首行加入GIF89a),抓包修改其类型和后缀
黑名单-过滤不严-双写绕过
获取文件后缀名判断文件后缀
- 1.黑名单检测上传文件后缀是不是在黑名单,在就拦截,否则就通过
- 2.白名单与黑名单相反
无递归(只过滤一次,没循环),然后把后缀关键词替换为空:

绕过方法:
双写绕过(看过滤是否有递归):上传 .pphphp
黑名单-过滤不严-大小写绕过

绕过方法:
大小写绕过(看函数),在windows服务器上才有效(Windows对大小写不敏感):
对于Linux系统而言,上传纯大写.PHP和纯小写.php才能被识别为php文件
str_replace()区分大小写,上传.Php,pHp等
str_ireplace()不区分大小写,大小写绕过无效
低版本GET-%00截断(太老了)
原理:PHP 内核是由 C 语言实现的,所以使用了 C 语言中的一些字符串处理函数。比如在连接字符串时候, 0 字节 (\x00) 将作为字符串结束符。所以在这个地方,攻击者只要在最后加入一个 0 字节,就能截断 file 变量之后的字符串
适用范围:
- php配置文件:magic_quotes_gpc = Off
- PHP 版本小于 5.3.4抓包查看回显信息–>看看php版本是否符合要求
自动解码一次
/var/www/html/upload/x.php%00

然后蚁剑直接连接x.php
低版本POST-%00截断(太老了)
00截断 是%00 解码结果
url上面(get请求)会自动解码一次
post请求则需要手动解码一次
./upload/x.php%00 对%00进行手工URL解码一次

然后蚁剑直接连接x.php
黑名单-过滤不严
黑名单过滤时,过滤不严,对同样可以解析为php文件的php3、php5等后缀文件没有进行过滤
工具:fuzz
抓包对上传的后缀进行Intruder爆破,使用fuzz字典进行攻击,按长度筛选结果发现php3和php5上传成功,且可被蚁剑连接
逻辑不严-条件竞争(代码审计居多)
逻辑缺陷:
- 错误逻辑:先上传,再判断
- 正确逻辑:先判断,后上传

攻击者上传了一个用来生成恶意 shell 的文件,在上传完成和安全检查完成并删除它的间隙,攻击者通过不断地发起访问请求的方法访问了该文件,该文件就会被执行,并且在服务器上生成一个恶意 shell 的文件。
访问即创建代码(访问了自动触发代码,自动新建一个1.php文件写入后门)
<?php fputs(fopen('1.php','w'),'<?php eval($_REQUEST[1]);?>');?>
上传不断发包


请求不断发包
这里的路径是正常上传一个图片推测出来的


成功访问到生成的木马文件:1.php,蚁剑成功连接


二次渲染(文件包含漏洞联动,少)
系统会对上传的图片等进行压缩、渲染等处理,只保留某些部分 –> 导致需要的后门代码被自动删去了
- GIF:渲染前后的两张 GIF,没有发生变化的数据库部分直接插入 Webshell 即可
- PNG:PNG 没有 GIF 那么简单,需要将数据写入到 PLTE 数据块 或者 IDAT 数据块
- JPG:JPG 也需要使用脚本将数据插入到特定的数据库,而且可能会不成功,所以需要多次尝试
先搞个正常图片,上传导出渲染后的图片
使用010等16进制编辑器对比保留部分,在保留部分添加后门代码


最后利用提示的文件包含执行图片后门代码


函数缺陷 – move_uploaded_file
强制命名造成的解析错误

move_uploaded_file() 是 PHP 中用于处理文件上传的函数,它的作用是将上传的临时文件移动到新的位置。
上述函数除了 PHP 5.3.4 以下的版本可以用 00 截断绕过,但如果最终保存的文件名可以由用户指定 (注意在数据包中能否自己命名)–> shell.php/.
也可以造成后门解析

最后的点被自动去掉了

代码审计-数组绕过
https://blog.csdn.net/qq_50854790/article/details/122352178
实战遇到的情况 – 新型上传(除权限)
执行权限
文件上传后存储目录不给执行权限。允许访问图片等内容,但403forbidden拒绝php等脚本文件执行
绕过条件:能控制上传文件存储目录,将其上传到其他目录(上传到其正常程序逻辑的目录,而非上传文件的目录,就不会有执行权限限制)
解码还原(常见 – 绕过不了 – 跑路)
数据做存储,解析固定(文件后缀名无关) –> 服务器就不存在上传的文件,只有其数据 –> webshell需要有其存在的路径才能连接
文件上传后利用编码传输解码还原
绕过:无法直接绕过
上传的图片等经过系统进行base64等编码操作,读取时再进行解码

文件 –> 编码 –> 数据 –> 解码 –> 文件
作用:便于存入数据库
<?php
// 处理文件上传
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
$file = $_FILES['file'];
$filename = $file['name'];
$tmpFilePath = $file['tmp_name'];
// 将文件转换为Base64编码
$base64Data = base64_encode(file_get_contents($tmpFilePath));
echo $base64Data;
//echo $base64Data;
// 显示图片
echo '<img src="data:image/jpeg;base64,' . $base64Data . '" alt="上传的图片">';
}
?>
固定协议:data:image/png;base64,base64一串数据 –> 永远当做图片去解析 – .php后门失效
相当与文件上传后没有后缀格式了,由什么解析 –> data:image协议
数据做存储,解析固定(文件后缀名无关)
文件上传后利用编码传输解码还原
分站存储(一般跑路)
上传服务器和存储服务器不是一台
upload.xiaodi8.com 上传
images.xiaodi8.com 存储
绕过:看分站存储的执行策略,是否给执行权限,否则也是无用 –> 如果拿下分站可以尝试迂回去尝试主战
OSS对象(无法直接绕过-跑路-云安全)
云存储 – 只有存储作用 – 自带执行权限控制
无论什么文件,访问就下载,并不会解析
Access控制-OSS对象存储-Bucket对象
应用场景
注册用户上传地方
可直接发现上传点
后台或其他管理页面
可直接发现上传点,虽说在后台,但可上传webshell接管服务器
JS或API接口的代码
找不到不到文件上传,但通过代码泄露了,如js泄露
可以通过自行构造上传表单实现上传
演示1:JS中构造上传页面

进行简单的js代码审计

然后构造一个文件上传的表单

最后再从自己构造的这个本地表单上传
问题:这个实验从本地构造上传页面上传显示网络连接404,但在服务器里写入这个页面就没问题……(js路径后面改了http://也是这样)
演示2:实战(不存在上传漏洞,只是找到隐藏上传点)
一个登录界面:常理讲要先登陆才有上传点(可能还没有),但是这个网站通过js代码泄露,发现了上传点

F12,发现加载了大量js代码
如何找到文件上传点 –> 在js中搜索相关关键字,如upload



所以,可以通过泄露的js代码自写一个上传表单进行上传
首先得会分析js
源码泄露或盲测文件
知道源码,进行白盒审计,分析代码,从而找到漏洞点
三方编辑器上传漏洞
看加载的js特征,找到编辑器版本信息
演示:ueditor
XML文件上传导致存储型XSS(低危)
漏洞复现:https://www.cnblogs.com/linglinglingling/p/18040866
实战中找不到上传点,但是,只要掌握了数据包的构造,就可以尝试上传
首先,通过js特征发现


然后开始构造上传

目标js位置:https://ynded.sgypos.com/js/ume/ueditor.all.min.js
本地js位置:http://192.168.10.200:7930/ueditor/ueditor.all.min.js
本地上传位置:http://192.168.10.200:7930/ueditor/php/controller.php?action=uploadimage
推断出目标上传位置:https://ynded.sgypos.com/js/ume/php/controller.php?action=uploadimage
然后对本地抓到的数据包进行修改相关地址参数信息
将uploadimage类型改为uploadfile,并修改文件后缀名为xml,写入xss语句
最后复制上xml代码即可触发xss
特定的源码审计漏洞
源码爆出过漏洞,使用此源码的网站也有这个漏洞
演示:通达OA文件上传漏洞
工具:OneFox集成工具箱-LiqunKit工具

拿到后门地址后可以直接连接
连接不上的情况:可能是工具写的后门有问题
解决办法:配置代理,强行让工具进程(任务管理器里看)走bp代理(联动Proxifier),进行抓包,修改其后门代码为支持的,然后就可以正常连接了
后门生成工具:哥斯拉

文件上传挖掘思路
网站是php就测试php后门,是jsp就测试jsp,一一对应

本节知识点
WEB攻防-文件上传-前端&黑白名单&MIME&文件头等
WEB攻防-文件上传-执行权限&解码还原&云存储&分站等
WEB攻防-文件上传-JS提取&特定漏洞&第三方编辑器
