CTF中常见的文件上传限制绕过方法
CTF论剑场-文件包含
在CTF的Web安全赛道里,文件上传漏洞的攻防演练堪称一场“猫鼠游戏”。防守方设下层层过滤,攻击方则绞尽脑汁寻找那一条缝隙。这其中的门道,远不止修改一个Content-Type那么简单。这篇文章将抛开基础,直击CTF实战中那些真正刁钻、有效的文件上传限制绕过方法。
绕过黑名单:不仅仅是大小写
黑名单过滤是最常见的防御手段,但它的脆弱性也最显而易见。除了经典的.php、.phtml变.Php、.PHP5这种大小写把戏,真正的挑战在于利用服务器配置的“特性”。
- 解析漏洞利用:这是黑名单的经典克星。在老旧版本的IIS中,
shell.php;.jpg或shell.php:.jpg可能被解析为PHP文件。Apache的解析漏洞(如test.php.xxx,只要xxx不在MIME列表中,就可能被解析为.php)更是屡试不爽。 - 特殊后缀挖掘:防守方可能只禁了
.php,却忘了.pht、.phtml、.phps,甚至是.inc(当服务器配置错误,将其当作PHP解析时)。Nginx搭配PHP-FPM的特定配置下,.jpg后面加上/.php(如shell.jpg/.php)可能触发解析,这招在CTF里可没少出现。 - 双写与嵌套:如果过滤逻辑是简单地删除掉“php”字符串,那么
shell.pphphp在删除中间匹配的“php”后,剩下的字符组合起来正好是.php,完美绕过。
白名单的“铁壁”如何钻洞?
相比黑名单,白名单(只允许.jpg、.png等)看似固若金汤,实则仍有破绽。这里的核心思路不再是“伪装”,而是“结合”与“构造”。
最典型的是文件头欺骗(Magic Bytes)。你上传一个文件,内容开头是GIF89a或FF D8 FF E0(JPEG的文件头),后面跟着完整的PHP代码。前端或简单的MIME检测会认为这是一张图片,而Apache/PHP在解析时,会从<?php标签开始执行,忽略前面的字节。这要求服务器不进行内容渲染检测。
更高级的场景是条件竞争。服务器有时会先将文件上传到临时目录,再检查其合法性,不合法则删除。攻击者可以疯狂并发上传一个包含恶意代码的“图片”,在它被删除前的一瞬间,通过另一个请求(比如文件包含漏洞)去访问并执行它。这考验的是手速和脚本自动化能力,在CTF中极具戏剧性。
Content-Type的把戏与超越
把application/octet-stream改成image/jpeg是入门第一课。但实战中,防守方可能从数据包的多处下手。
你需要检查整个HTTP请求:filename参数、name参数,甚至是否存在多个multipart边界。有些题目会检查filename的后缀,却忽略文件内容部分之前的Content-Disposition里的文件名。或者,你可以尝试在filename参数中插入换行符%0a,这可能会破坏后端解析器的正则匹配,导致其截取到错误的后缀。
终极思维:组合漏洞的艺术
单独的文件上传防御越来越完善,真正的突破口往往在于漏洞组合。这才是CTF题目的精髓所在。
例如,题目严格限制了只能上传.txt文件。别急着放弃,先看看有没有文件包含漏洞。如果有,那么你上传的shell.txt,通过包含漏洞include($_GET[‘file’]),就能以PHP代码的形式执行。更隐蔽的是日志注入,如果能控制User-Agent等头部信息,并将其写入日志文件(如/var/log/apache2/access.log),再结合文件包含去执行这个日志文件,一条全新的攻击链就形成了。
再比如,利用.htaccess文件。如果服务器允许上传.htaccess,你就可以重写解析规则:AddType application/x-httpd-php .jpg。这样一来,之后上传的所有.jpg文件都会被当作PHP执行。这招一旦成功,便是绝杀。
文件上传的攻防,本质上是对Web服务器、中间件、编程语言特性乃至开发者思维盲区的极致理解。每一次成功的绕过,都不是机械地套用姿势,而是基于对流量、对代码、对系统行为的深刻洞察。下次当你卡在一道上传题时,不妨问问自己:我看到的限制,真的覆盖了所有攻击面吗?

参与讨论
暂无评论,快来发表你的观点吧!