发布于2026-07-05 阅读(0)
扫一扫,手机访问
PHP 7.4 里的文件包含漏洞,不是“会不会出问题”的讨论题,而是“漏洞到底藏在哪、怎么防得住”的现实问题。默认配置下 allow_url_include 确实关了,但本地文件包含(LFI)照样高发——尤其是开发者在 include 或 require 里直接拼接用户输入时,basename() 用错、realpath() 漏校验、白名单考虑不周,只要有一环失守,/etc/passwd 就能被读走。
PHP 7.4 并没有修补逻辑层面的缺陷,只是收紧了部分默认配置。攻击者现在根本不依赖远程包含,而是专攻本地路径穿越和伪协议利用。常见误区是以为加了 .php 后缀就万事大吉,结果 ../ 照样能绕过目录限制,%00 截断在低版本遗留环境里仍然有效(虽然 PHP 7.4 默认禁用了 magic_quotes_gpc,但某些老容器或自编译环境可能还残留)。更要命的是:日志、Session、临时上传文件这些“非预期文件”,在 Docker 或云环境中路径和权限已经变了,可很多开发者还按传统思路来测试。
include($_GET['page'] . '.php') → 攻击者传 ?page=../../../../var/log/apache2/access.log%00,如果服务器 PHP 版本或配置不当,仍然可能截断并包含日志。/var/log/apache2/access.log 通常是 /dev/stdout 的软链,include() 会报 failed to open stream: Permission denied——但这不代表漏洞不存在,只是利用路径变了。php://filter 依然完全支持:?page=php://filter/convert.base64-encode/resource=index.php 直接源码泄露,不需要任何文件写入权限。只靠 in_array() 判断 $_GET['page'] 是否在数组里,等于给攻击者留后门——因为根本没约束文件的真实位置。PHP 7.4 的 realpath() 行为更严格了,但要是先拼路径再调用,照样可能被绕过。
include('pages/' . $_GET['page'] . '.php');,就算 $_GET['page'] 值是 about,攻击者也能构造 about%00../config(取决于底层 libc 和 PHP 编译选项)。$whitelist = ['home' => '/var/www/html/pages/home.php', 'about' => '/var/www/html/pages/about.php'];。if (isset($whitelist[$page])) { include($whitelist[$page]); }。realpath($path) 预先计算一次并缓存,确保它确实落在 /var/www/html/ 下——防止 symlink 绕过。PHP 7.4 默认允许 php://filter 和 data://,它们不依赖文件系统,而是内存级解析,即使关闭 allow_url_fopen 也没用。这是 LFI 转 RCE 的关键跳板,尤其在没法写 shell 的场景里特别致命。
php://filter 用于读取并编码任意 PHP 文件:include('php://filter/convert.base64-encode/resource=config.php'); → 返回 base64 编码后的源码。data:// 可以直接执行代码:include('data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+'); → 解码后执行 。$path = $_GET['page']; if (preg_match('/^php://|data:///i', $path)) { die('Forbidden'); }。://。realpath() 在 PHP 7.4 中对符号链接和越界路径处理更严谨了,但它本身不阻止包含——只是返回规范路径。必须配合 open_basedir 才能从运行时层面锁死访问范围。
realpath($user_input) 后判断是否以 /var/www/html 开头,仍然可能被 /var/www/html/../etc/passwd 绕过(如果 realpath() 返回的是 /etc/passwd,而你忘了二次校验)。$abs = realpath($user_input); if ($abs === false || strpos($abs, '/var/www/html') !== 0) { die(); } include($abs);。php.ini 中设置 open_basedir = /var/www/html:/tmp,这样即使代码漏判,PHP 运行时也会拒绝访问 /etc 下的任何文件。open_basedir 不影响 php:// 和 data://,所以协议拦截仍然不能省略。PHP 7.4 的文件包含漏洞防御,核心不在于函数版本新旧,而在于路径控制是否形成了闭环——白名单必须带绝对路径、realpath 要验证结果、open_basedir 要启用、伪协议要显式拒绝。四个环节缺一不可,少一个,攻击者就能找到突破口。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8