PHP extract函数如何被利用?
TOPIC SOURCE
新版NewBugKu-Web1-对方不想和你说话并扔了一段代码Writeup
在审计旧版 PHP 项目时,安全研究员常会在入口函数里碰到 extract(),它把数组键名转成变量名,键值直接写入对应的变量空间。若数组来源于用户输入,攻击者只需构造特定键,即可在脚本执行前注入任意变量。
extract的工作原理
假设有如下代码:
$data = $_GET;
extract($data, EXTR_SKIP);
if (isset($admin)) {
// 只有 $admin 为 true 时才会执行敏感操作
include $config;
}
当 $_GET 包含 admin=1 时,extract() 会在当前符号表里创建 $admin,进而绕过权限检查。更危险的是,如果后续代码依赖未初始化的变量进行文件路径拼接,攻击者可以借助同一机制直接控制 include 的目标。
典型攻击路径
- 利用
extract($_REQUEST),在 URL 中加入file=../../etc/passwd,导致include $file读取系统敏感文件。 - 在同一请求里同时注入
admin=1与file=.../shell.php,完成提权加后门上传。 - 结合
extract()与compact(),把用户提供的键名写进日志或错误信息,进一步泄露内部路径。
实际案例中,某开源 CMS 的插件在处理表单数据时直接调用 extract($_POST),而后台模板文件随后使用未过滤的 $template 进行 include。攻击者只需提交 template=../../upload/backdoor.php,即可让服务器执行任意 PHP 代码,最终获得系统权限。
防御要点
安全团队在代码审计时,应该把所有来源于外部请求的数组列入黑名单,禁止直接传入 extract()。如果必须使用,务必配合 EXTR_PREFIX_ALL 或显式过滤键名,确保不会产生冲突的全局变量。此外,文件包含操作应始终采用白名单路径,切忌把用户可控变量直接拼接进 include。

参与讨论
extract($_GET) 还敢这么用,心真大
之前搞过老项目,看到 extract 直接头皮发麻
求问 EXTR_SKIP 能防住 file=xxx 这种吗?
太危险了吧这也,直接 include 用户输入?
吃瓜.jpg 一个函数搞崩整个系统
我擦,原来还能这样传 shell,学废了
防御那块说白名单路径,但很多老系统根本没这意识啊
hhh 又是 $_REQUEST 背锅的一天
这玩意儿不就是变量注入的后门吗?
感觉现在还有人这么写代码?233
那个 CMS 插件是不是某老牌论坛的?🤔
extract + include 简直是送权限大礼包😂