PHP extract函数如何被利用?

12 人参与

在审计旧版 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=1file=.../shell.php,完成提权加后门上传。
  • 结合 extract()compact(),把用户提供的键名写进日志或错误信息,进一步泄露内部路径。

实际案例中,某开源 CMS 的插件在处理表单数据时直接调用 extract($_POST),而后台模板文件随后使用未过滤的 $template 进行 include。攻击者只需提交 template=../../upload/backdoor.php,即可让服务器执行任意 PHP 代码,最终获得系统权限。

防御要点

安全团队在代码审计时,应该把所有来源于外部请求的数组列入黑名单,禁止直接传入 extract()。如果必须使用,务必配合 EXTR_PREFIX_ALL 或显式过滤键名,确保不会产生冲突的全局变量。此外,文件包含操作应始终采用白名单路径,切忌把用户可控变量直接拼接进 include

参与讨论

12 条评论
  • 幻影随风

    extract($_GET) 还敢这么用,心真大

    回复
  • 暗黑算法师

    之前搞过老项目,看到 extract 直接头皮发麻

    回复
  • 蜚兽过泽

    求问 EXTR_SKIP 能防住 file=xxx 这种吗?

    回复
  • 书房沉思

    太危险了吧这也,直接 include 用户输入?

    回复
  • 暮色如囚

    吃瓜.jpg 一个函数搞崩整个系统

    回复
  • 杏花

    我擦,原来还能这样传 shell,学废了

    回复
  • 书桌旁的绿植

    防御那块说白名单路径,但很多老系统根本没这意识啊

    回复
  • 星眸微光

    hhh 又是 $_REQUEST 背锅的一天

    回复
  • 电子牧者

    这玩意儿不就是变量注入的后门吗?

    回复
  • 炽炎骑士

    感觉现在还有人这么写代码?233

    回复
  • 嘚啵喵

    那个 CMS 插件是不是某老牌论坛的?🤔

    回复
  • 经络通

    extract + include 简直是送权限大礼包😂

    回复