在你的文档中,文件类型绕过主要涉及两种方式:前端绕过和后端MIME类型绕过。它们的本质都是欺骗服务端对文件类型的判断。
一、前端绕过(客户端验证)
原理
前端通过JavaScript检查文件后缀名,但这段代码运行在你的浏览器中,你可以完全控制它的执行。
绕过方式(文档第5-8页)
| 方法 | 操作 |
|---|---|
| 禁用JS | 浏览器设置或插件(如Script Blocker Ultimate)直接关闭JS引擎 |
| 修改JS代码 | F12查看源代码,找到checkFile()函数,将return false改为return true,或直接删除校验逻辑 |
| 抓包改后缀 | 先用合法文件(如.jpg)通过前端校验,用BurpSuite截获请求后,将filename改为.php |
核心思路
让前端的校验逻辑失效,使恶意文件能被发送到服务器。
二、后端MIME类型绕过(Content-Type绕过)
原理
服务端通过检查HTTP请求头中的Content-Type(MIME类型)来判断文件类型。例如:
-
图片应为
image/jpeg、image/png -
PHP文件应为
application/octet-stream或application/x-httpd-php
如果服务端只检查这个头而不检查文件内容或后缀,就可以直接修改它来绕过。
绕过方式(文档第8-10页)
步骤:
-
准备一个
.php木马文件 -
用BurpSuite抓取上传请求
-
找到
Content-Type: application/octet-stream(或类似) -
将其改为
image/jpeg -
转发请求
示例(文档第10页):
text
Content-Type: application/octet-stream ← 原本是PHP的MIME 改为 ↓ Content-Type: image/jpeg ← 伪装成图片
为什么能绕过?
如果服务端代码是这样写的:
php
if($_FILES['file']['type'] == 'image/jpeg'){
// 允许上传
}
它只检查了HTTP头里的type字段,而没有检查文件的实际内容或后缀。改掉这个头,服务端就认为你上传的是一张JPEG图片。
三、两种绕过方式对比
| 对比项 | 前端绕过 | 后端MIME绕过 |
|---|---|---|
| 验证位置 | 浏览器(客户端) | 服务器(后端代码) |
| 验证依据 | 文件后缀名(JS检查) | HTTP头中的Content-Type |
| 绕过手段 | 禁用/修改JS,或抓包改后缀 | 抓包修改Content-Type |
| 是否需要抓包 | 不一定(禁用JS可直接上传) | 必须(需要修改HTTP请求头) |
| 防御方式 | 后端必须重新校验 | 不要信任MIME,结合后缀+内容检测 |
四、总结一句话
文件类型绕过的核心是:前端验证靠禁用JS绕过,后端MIME验证靠抓包改Content-Type绕过。两者都是因为服务端没有做足够严格的校验(如白名单后缀、文件内容检测),才给了攻击者可乘之机。
一、同解析后缀名(文档第11页)
原理
Apache、IIS等Web容器除了默认的.php外,还支持其他后缀名作为PHP解析,如:
-
.php3、.php4、.php5、.phtml、.pht
如果黑名单只封了.php,没封这些“亲戚后缀”,就可以直接上传shell.php5,服务器依然会当作PHP执行。
绕过条件
-
黑名单不完整,未覆盖所有可解析后缀
-
服务器配置了将这些后缀映射到PHP解析器
二、.htaccess文件绕过(文档第12-16页)
原理
.htaccess是Apache的目录配置文件。如果允许上传该文件,可以在其中写入配置指令,让任意后缀的文件都被当作PHP解析。
常用指令
apache
# 将.png文件当作PHP解析 AddType application/x-httpd-php .png # 强制当前目录下所有文件都当作PHP解析 SetHandler application/x-httpd-php
绕过步骤
-
先上传
.htaccess文件(内容如上) -
再上传一个包含木马的
shell.png -
访问
shell.png时,服务器会以PHP方式执行其中的代码
限制条件
-
必须是Apache环境
-
httpd.conf中AllowOverride不是None(通常为All) -
黑名单没有禁止
.htaccess文件上传
三、后缀大小写绕过(文档第16页)
原理
如果服务端在做黑名单匹配时没有统一转换成小写,直接用字符串比对,那么.pHp、.Php5、.pHT等大小写变种就可能绕过。
示例
黑名单:php、asp、jsp
上传文件:shell.pHp
代码中用in_array($ext, $blacklist),但$ext是原始大小写,'pHp'不等于'php',因此绕过。
绕过方式
手动修改文件名大小写,或用BurpSuite的Intruder模块进行大小写变种FUZZ测试。
四、文件后缀名加空格/点/下划线绕过(文档第16-17页)
原理
服务端在获取后缀时,如果没有做去除空格、去除点等操作,就会导致逻辑缺陷。
常见绕过方式
| 后缀写法 | 服务器实际存储 | 绕过原因 |
|---|---|---|
shell.php(末尾加空格) | shell.php | Windows系统会自动去掉末尾空格,但黑名单匹配时没去除,匹配不到 |
shell.php. | shell.php | Windows系统会自动去掉末尾的点 |
shell.php_ | shell.php | 某些系统会忽略下划线后的内容,或代码只判断到第一个点 |
代码缺陷示例
php
$ext = pathinfo($filename, PATHINFO_EXTENSION); // 获取后缀
if(in_array($ext, $blacklist)){ ... }
如果上传shell.php.,pathinfo会返回空字符串'',绕过黑名单,但Windows保存时自动去掉点,实际文件是shell.php。
五、Windows文件流绕过(::$DATA)(文档第18-20页)
原理
NTFS文件系统支持交换数据流(ADS)。当文件名后加::$DATA时,系统会将其视为数据流,最终保存时会去掉::$DATA,只保留前面的文件名。
绕过方式
上传时文件名写为:
text
shell.php::$DATA
服务端黑名单检查的是完整文件名shell.php::$DATA,后缀不是.php,因此放行。保存到服务器后,Windows会将其存储为shell.php。
限制条件
-
仅限Windows + NTFS文件系统
-
服务端没有对
::$DATA做过滤
六、双写绕过(文档第20-21页)
原理
服务端使用str_ireplace()或类似函数,将黑名单中的敏感字符串替换为空,但只替换一次且不递归。
示例代码
php
$filename = str_ireplace('php', '', $filename);
如果上传shell.pphphp:
-
第一次替换:中间的
php被删掉,变成shell.php -
因为只替换一次,不递归检查,最终得到
shell.php
绕过方式
构造文件名如:
-
shell.pphphp→ 删除中间的php→shell.php -
shell.asaspxpx→ 删除asp→shell.aspx
关键
-
只适用于黑名单替换成空的逻辑
-
需要知道黑名单关键词,进行双写嵌套
总结对比表
| 绕过方式 | 核心原理 | 适用环境 | 关键前提 |
|---|---|---|---|
| 同解析后缀 | 利用服务器支持的其他可执行后缀 | Apache/IIS | 黑名单不全 |
| .htaccess | 修改目录配置,强制解析任意后缀 | Apache | 允许上传.htaccess |
| 大小写绕过 | 匹配时未统一转小写 | 通用 | 代码未做大小写归一化 |
| 空格/点/下划线 | Windows系统特性 + 代码未trim | Windows | 服务端未做清理 |
| Windows文件流 | NTFS数据流特性 | Windows + NTFS | 服务端未过滤::$DATA |
| 双写绕过 | 单次替换导致的嵌套绕过 | 通用 | 使用str_ireplace单次替换 |
一句话总结
黑名单绕过的本质是:黑名单永远是不完整的,攻击者总能找到不在名单里的可执行后缀,或利用系统特性(Windows文件流、大小写、空格)以及代码逻辑缺陷(单次替换、未trim)来让恶意文件成功落地并被解析。
1093

被折叠的 条评论
为什么被折叠?



