type
status
date
slug
summary
tags
category
icon
password
懂得都懂
文件上传
无非就是这几个步骤:
- 找到上传点
- 知道上传文件的路径
- 能运行上传的文件
前端
js类绕过
- 页面直接修改js上传文件方法(添加类型);
- 抓包改包,将上传的文件后缀进行修改(例如:info.php.jpg ⇒ info.php);
- 复制页面,重新构建新页面,获取方法,然后修改。
后端
黑名单绕过
Web系统可能会采用黑名单的方式进行过滤。而过滤的方式存在一定的缺陷,比如存在过滤的黑名单不全,未考虑大小写,以及要上传文件的名称存在敏感字符。基于黑名单验证:只针对黑名单中没有的后缀名,文件才能上传成功。使用黑名单过滤方式,肯定会存在缺陷;(对上传文件名称进行敏感字符清除)
很多语言都存在,有多个可以解析后缀。当目标站点采用黑名单时,往往包含不全面。
例如:
php
.htaccess解析
前提条件: Apache开启.htaccess文件功能
开启方法:
- 路径:Apache\conf\httpd.conf
- 修改代码(None改为ALL)
去掉注释
实际操作
- 编辑.htaccess文件
还有一种格式
- 上传.htaccess文件
- 上传一句话木马,木马文件以info.jpg命名
- 菜刀或蚁剑getshell
大小写绕过
后缀名黑名单设置不全,只对常见后缀过滤,可以利用大小写绕过。
例如:
0.o 🤨
点绕过
- Windows 系统下,文件后缀名最后一个点会被自动去除。
- Linux 系统下,文件后缀名最后一个点不会被自动去除
只能在Windows下利用
利用:
info.php.
::$DATA绕过
在Window系统下,如果上传的文件名为
a.php::$DATA
,它会在服务器上生成一个a.php
的文件,其中内容和所上传内容相同,并被解析。例如:
phpinfo.php::$DATA
Windows会自动去掉末尾的::$DATA
变成phpinfo.php
双后缀名绕过
文件上传过滤代码,会将文件名称进行敏感字符清除
例如:
如果上传的文件名为
info.php
,那么就将后缀名舍弃,变成info
利用:
- 对要上传的文件添加重复后缀名,如:
a.php ⇒ a.p
php
hp
- 服务器会把其中的php过滤掉,剩下的会重新拼成php
弊端:
如果系统使用递归循环过滤,那此方法失效
白名单绕过
MIME绕过,又叫HTTP请求头中的Content-Type属性绕过;【Response 、Request Headers都存在】
了解MIME
可能很多人不知道什么是MIME?不过没关系,那你一定听说过文件内容类型或者说通过抓包你一定听说过 Content-Type:text/html
这种类似的,其实,这就是MIME。下面再给大家简单说说吧!
MIME((Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式每个MIME类型由两部分组成,前面是数据的大类别,例如声音 audio、图象 Image等,后面定义具体的种类。
什么是Content-Type
要知道什么是Content-Type,首先要了解什么是Internet Media Type。Internet Media Type即互联网媒体类型,也叫做MIME类型,使用两部分标识符来确定一个类型。在HTTP协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息,意思就是说,Content-Type是Internet Media Type在HTTP协议中的别称。
Content-Type的格式
上面是Content-Type的格式,可以拆解为三个部分,分别是主类型(type)、子类型(subtype)和参数(parameter)。
主类型(type)
主类型可以是任意的字符串,比如text。如果是*号则代表所有类型。
/子类型(subtype)
子类型可以是任意的字符串,比如html。如果是*号则代表所有类型。
;参数(parameter)
参数是可选的,可以在Content-Type中加入一些特殊的参数,比如Accept请求头的参数,常见的有用于设置字符编码的charset参数。
Content-Type中常见的媒体格式类型:
以text开头的媒体格式类型:
text/html: HTML格式。
text/plain:纯文本格式。
text/xml: XML格式。
以image开头的媒体格式类型:
image/gif:gif图片格式。
image/jpeg:jpg图片格式。
image/png:png图片格式。
以application开头的媒体格式类型:
application/xhtml+xml:XHTML格式。
application/xml: XML数据格式。
application/atom+xml:Atom XML聚合格式 。
application/json: JSON数据格式。
application/pdf:pdf格式 。
application/msword: Word文档格式。
application/octet-stream: 二进制流数据(如常见的文件下载)。
application/x-www-form-urlencoded: 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)。
另外还有一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式。
MIME拦截代码样例:
MIME利用示例:
- 通过抓包的形式,修改Content-Type类型,将类型指定为:image/*
- Content-Type类型位于HTTP Request 中,要以网站为中心,request表示获取数据,response表示返回数据
%00截断
%00跟随url发送到服务器后被服务器解码,这时还没有传到验证函数,也就是说验证函数里接收到的不是%00字符,而是**%00解码后的内容,即解码成了0x00**。总之就是**%00被服务器解码为0x00发挥了截断作用**。
00截断的核心:
- 当一个字符串中存在空字符的时候,在被解析的时候会导致空字符后面的字符被丢弃
00截断原理:
也就是说,URL中
%00
所代表的ASCII值为0
示例:
https://test/upfiles/?filename=test.txt
,输出的是test.txt
https://test/upfiles/?filename=test.php
%00
.txt
,输出的是test.php
利用:
打开BurpSuite抓包工具,找到上传文件后缀名位置;
- **%00截断百分之百绕过前端校验;**例如:a.php%00.jpg
- 在上传文件后缀名处,直接用 %00 就可以了。示例:a.php%00.jpg
- 某些情况下,直接在文件名中加 %00 进行截断不生效无法起到相应的作用,因为 %00 会以字符串的形式解析了。(不认为是空(NULL)字符,认为只是普通拼接的字符串);
解决方法如下:
- 我们需要对 %00 做一个URL解码,也就是URL-decode;(在BurpSuite内选中%00右键convent selection——>URL——>URL-decode)
- 通过 burpsuite 修改 hex 值为 00 (URL decode)进行截断;
为什么两者用法不同?
- 这是因为 %00 截断在 GET 中被 url 解码之后是空字符。但是在 POST 中 %00 不会被 url 解码,所以只能通过 burpsuite 修改 hex 值为 00 (URL decode)进行截断。
如果是存在后端校验;%00截断只能绕过前端校验,达不到预想结果;
(待施工)
- 作者:sleepfat
- 链接:https://blog.sleepfat.top/hack-file-upload
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章