CTF题目中常见的变量覆盖攻击手法
TOPIC SOURCE
对方不想和你说话并扔了一段代码
在CTF的逆向与二进制挑战里,变量覆盖往往像暗藏的暗门,一不留神就会被对手轻易打开。尤其是脚本语言的动态特性,使得攻击者可以借助几行代码把原本安全的逻辑改写成任意执行路径。
变量覆盖的常见场景
最典型的手法莫过于 extract() 与全局数组的直接写入。假设题目提供了如下代码:
$params = $_GET;
extract($params);
if ($auth == 'admin') {
include $config;
}
只要在URL里加入 ?auth=admin&config=/flag.txt,$auth 与 $config 便被覆盖,原本的权限检查瞬间失效,文件读取直接泄露。类似的技巧还有:
- 利用
register_globals(已废弃但在老旧环境仍可复现)把外部参数映射为全局变量。 - 直接写入
$GLOBALS数组,例如$GLOBALS['user'] = 'root';。 - 覆盖环境变量
$_ENV或$_SERVER,进而影响函数如getenv()、apache_getenv()。 - 在模板引擎中注入变量名,例如 Smarty 的
{$smarty.foreach},通过参数覆盖实现代码执行。
防御思路与案例回顾
面对这些手法,最直接的防御是最小化信任边界:不要盲目把外部数组交给 extract(),而是手动挑选键名并进行白名单校验。其次,禁用 register_globals、allow_url_include 等不安全的 php.ini 配置,并在代码审计时标记所有可能的全局写入点。
回看去年某高校的线上赛题,选手们通过覆盖 $file 变量成功读取了 /etc/passwd,而题目作者在事后修复时,仅在 include 前加入了 is_file($file) 检查,并将所有外部输入限制为固定目录。可见,一行防御代码往往能够扼杀整个攻击链。
变量覆盖不是偶然出现的漏洞,它是对“信任”假设的系统性挑战。

参与讨论
extract()真坑,我第一次做CTF就被这玩意阴了
auth=admin&config=/flag.txt 这种还能过?题目也太松了吧
register_globals都废弃多少年了还考,出题人怀旧?🤔
之前搞过这个,确实折腾了好久才明白变量覆盖点
要是include前加个basename是不是就安全了?
$GLOBALS直接写入这也行?PHP真是一言难尽
感觉还行,但今年比赛应该不会这么简单了
模板引擎那块没看懂,Smarty咋还能被参数覆盖?
又不是生产环境,CTF里玩变量覆盖挺合理的
太离谱了,$file没过滤直接读/etc/passwd?
那个高校赛题我记得!当时卡了我两小时😭
防御只加is_file够吗?路径穿越照样能打吧
这不就是去年那道题的套路?直接套用就出flag了
hhh 一看到extract就知道要出事
现在出题能不能别老用PHP了,换点新鲜的不行?
变量覆盖这种玩法还挺常见的,感觉像开了后门。
@ 深蓝幻梦 这后门开得还挺隐蔽
路径穿越确实能绕过is_file,得看目录限制严不严
@ 穿越时光的旅人 路径穿越这块儿得结合具体的目录限制来谈,限制不严就全完了