这是一道经典的 PHP 变量覆盖Variable Coverage与三元运算符特性的 CTF 题目。代码看似杂乱但核心考点在于理解 PHP 的变量引用、三元运算符的优先级以及如何让代码走向输出 flag 的分支。以下是详细的解题思路和分析核心源码分析我们逐行拆解最关键的 4 行 PHP 代码14:include(flag.php);15:$_GET?$_GET$_POST:flag;16:$_GET[flag]flag?$_GET$_COOKIE:flag;17:$_GET[flag]flag?$_GET$_SERVER:flag;18:highlight_file($_GET[HTTP_FLAG]flag?$flag:__FILE__);注图片中的 Notice 提示第 15, 16, 17 行报错是因为我们没有通过 GET、COOKIE 或 SERVER 传参导致对应的键值未定义。关键点一PHP 三元运算符的缺陷在 PHP 中三元运算符 ? : 是从左向右left-associative结合的而且在这个题目的特殊写法中它其实充当了一个条件分支。例如第 15 行GET?(_GET ? (G​ET?(_GET $_POST) : ‘flag’;意思是如果 $_GET 数组不为空即我们发起了 GET 请求那么就会执行KaTeX parse error: Expected EOF, got at position 8: _GET ̲_POST将 $_GET 变为KaTeX parse error: Expected EOF, got at position 23: …引用。 关键点二引用传递̲的连环套第 15 行一旦我们发送了任意 GET 参数$_GET 就变成了 $_POST 的引用。此时修改 $_GET 就等于修改POST。第16行如果满足条件_POST。 第 16 行如果满足条件P​OST。第16行如果满足条件_GET 变为 $_COOKIE 的引用。因为第 15 行的关系此时 $_POST 也变成了 $_COOKIE 的引用。第 17 行同理如果满足条件最终GET、_GET、G​ET、_POST、$_COOKIE 都会通过引用的链条指向 $_SERVER。2. 逆推解题步骤我们的最终目标是让第 18 行的 highlight_file 输出 $flaghighlight_file($_GET[HTTP_FLAG]flag?$flag:__FILE__);所以必须满足的最终条件是$_GET[‘HTTP_FLAG’] ‘flag’。为了达到这个目标我们需要从后往前逆推每一步的条件步骤三突破第 17 行$_GET[flag]flag?$_GET$_SERVER:flag;目标我们希望进入KaTeX parse error: Expected EOF, got at position 8: _GET ̲_SERVER 这一步。条件需要当前的GET[′flag′]′flag′。结果一旦成功_GET[flag] flag。 结果一旦成功G​ET[′flag′]′flag′。结果一旦成功_GET 就会指向 $_SERVER 数组。而在 $_SERVER 数组中通常只要我们发送一个自定义的 HTTP 请求头 HTTP_FLAG: flagPHP 就会自动将其解析为 $_SERVER[‘HTTP_FLAG’] ‘flag’。这正好完美契合了最终第 18 行的要求步骤二突破第 16 行$_GET[flag]flag?$_GET$_COOKIE:flag;目标为了让第 17 行的 $_GET[‘flag’] 依然等于 ‘flag’我们需要在这一步让 $_GET 变为COOKIE的引用并且在COOKIE中传入flagflag。条件进入这一步前_COOKIE 的引用并且在 COOKIE 中传入 flagflag。 条件进入这一步前C​OOKIE的引用并且在COOKIE中传入flagflag。条件进入这一步前_GET[‘flag’] 必须等于 ‘flag’。步骤一起点第 15 行$_GET?$_GET$_POST:flag;目标开启这个链条。我们需要发送一个 GET 请求让 $_GET 变为 $_POST 的引用。条件带上任意 GET 参数为了后面几行能判断直接带上 ?flagflag 即可。3. 最终 Payload 构造根据上面的逆推我们需要同时在 GET、POST、COOKIE、HTTP Headers 中传入对应的参数形成一个完美的传参链条GET 参数?flagflag作用触发第 15 行使 $_GET 变为 $_POST 的引用。同时让第 16 行的 $_GET[‘flag’]‘flag’ 成立。POST 参数flagflag作用此时 $_GET 已经是POST的引用了。第16行成立后_POST 的引用了。第 16 行成立后P​OST的引用了。第16行成立后_GET即当前的 $_POST变为 $_COOKIE 的引用。为了让第 17 行的 $_GET[‘flag’]‘flag’ 成立我们需要 POST 里也有 flagflag。COOKIE 参数HTTP_FLAGflag![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7f60cf735b374e1491029c467fb5e01e.png作用第 17 行成立后$_GET 彻底变成了 $_SERVER 的引用。HTTP 请求头Headers添加 HTTP_FLAG: flag或者 Http-Flag: flagPHP 解析后会变成 HTTP_FLAG作用让SERVER[′HTTPFLAG′]′flag′成立从而触发highlightfile(_SERVER[HTTP_FLAG] flag 成立从而触发 highlight_file(S​ERVER[′HTTPF​LAG′]′flag′成立从而触发highlightf​ile(flag)。flag为ctfshow{7391f0f0-d866-49ba-a8cf-d28586bdb98e}