ctf show web入门98

这是一道经典的 PHP 变量覆盖(Variable Coverage)与三元运算符特性的 CTF 题目。代码看似杂乱,但核心考点在于理解 PHP 的变量引用、三元运算符的优先级以及如何让代码走向输出 flag 的分支。

以下是详细的解题思路和分析:

  1. 核心源码分析
    我们逐行拆解最关键的 4 行 PHP 代码:
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 ? (GET?(_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 行:如果满足条件,POST。第16行:如果满足条件,_GET 变为 _COOKIE 的引用。因为第 15 行的关系,此时 _POST 也变成了 _COOKIE 的引用。

第 17 行:同理,如果满足条件,最终 GET、_GET、GET、_POST、_COOKIE 都会通过引用的链条指向 _SERVER。

  1. 逆推解题步骤

我们的最终目标是让第 18 行的 highlight_file 输出 $flag:

php 复制代码
highlight_file($_GET['HTTP_FLAG']=='flag' ? $flag : __FILE__);

所以,必须满足的最终条件是:$_GET'HTTP_FLAG' == 'flag'。

为了达到这个目标,我们需要从后往前逆推每一步的条件:

步骤三:突破第 17 行

php 复制代码
$_GET['flag']=='flag' ? $_GET=&$_SERVER : 'flag';

目标:我们希望进入 KaTeX parse error: Expected 'EOF', got '&' at position 8: _GET = &̲_SERVER 这一步。

条件:需要当前的 GET′flag′==′flag′。结果:一旦成功,_GET'flag' == 'flag'。 结果:一旦成功,GET′flag′==′flag′。结果:一旦成功,_GET 就会指向 _SERVER 数组。而在 _SERVER 数组中,通常只要我们发送一个自定义的 HTTP 请求头 HTTP_FLAG: flag,PHP 就会自动将其解析为 $_SERVER'HTTP_FLAG' = 'flag'。这正好完美契合了最终第 18 行的要求!

步骤二:突破第 16 行

php 复制代码
$_GET['flag']=='flag' ? $_GET=&$_COOKIE : 'flag';

目标:为了让第 17 行的 _GET\['flag'\] 依然等于 'flag',我们需要在这一步让 _GET 变为 COOKIE的引用,并且在COOKIE中传入flag=flag。条件:进入这一步前,_COOKIE 的引用,并且在 COOKIE 中传入 flag=flag。 条件:进入这一步前,COOKIE的引用,并且在COOKIE中传入flag=flag。条件:进入这一步前,_GET'flag' 必须等于 'flag'。

步骤一:起点(第 15 行)

php 复制代码
$_GET ? $_GET=&$_POST : 'flag';

目标:开启这个链条。我们需要发送一个 GET 请求,让 _GET 变为 _POST 的引用。

条件:带上任意 GET 参数(为了后面几行能判断,直接带上 ?flag=flag 即可)。

  1. 最终 Payload 构造

根据上面的逆推,我们需要同时在 GET、POST、COOKIE、HTTP Headers 中传入对应的参数,形成一个完美的传参链条:

GET 参数:?flag=flag

作用:触发第 15 行,使 _GET 变为 _POST 的引用。同时让第 16 行的 $_GET'flag'=='flag' 成立。

POST 参数:flag=flag

作用:此时 _GET 已经是 POST的引用了。第16行成立后,_POST 的引用了。第 16 行成立后,POST的引用了。第16行成立后,_GET(即当前的 _POST)变为 _COOKIE 的引用。为了让第 17 行的 _GET'flag'=='flag' 成立,我们需要 POST 里也有 flag=flag。

COOKIE 参数:HTTP_FLAG=flag

!在这里插入图片描述(https://i-blog.csdnimg.cn/direct/7f60cf735b374e1491029c467fb5e01e.png

作用:第 17 行成立后,_GET 彻底变成了 _SERVER 的引用。

HTTP 请求头(Headers):添加 HTTP_FLAG: flag(或者 Http-Flag: flag,PHP 解析后会变成 HTTP_FLAG)

作用:让 SERVER′HTTPFLAG′==′flag′成立,从而触发highlightfile(_SERVER'HTTP_FLAG' == 'flag' 成立,从而触发 highlight_file(SERVER′HTTPFLAG′==′flag′成立,从而触发highlightfile(flag)。

flag为:ctfshow{7391f0f0-d866-49ba-a8cf-d28586bdb98e}

相关推荐
卷帘依旧6 分钟前
useImperativeHandle的作用
前端
卷帘依旧13 分钟前
Hooks在Fiber上的存储原理
前端
you458016 分钟前
学成在线--day02 CMS前端开发(含Vue基础知识得回顾)
前端·javascript·vue.js
qeen8720 分钟前
【C++】类与对象之类的默认成员函数(二)
android·c语言·开发语言·c++·笔记·学习
xiaofeichaichai23 分钟前
虚拟 DOM
前端·javascript·vue.js
故渊at25 分钟前
第二板块:Android 四大组件标准化学理 | 第九篇:BroadcastReceiver 事件分发与有序广播
android·gitee·broadcast·广播·动态注册·静态注册
2401_8784545327 分钟前
前端高频得手写题
前端
m0_7360348528 分钟前
存储基础和虚拟化
笔记
JohnnyDeng941 小时前
【Android】Room 数据库高级用法与性能调优:从查询瓶颈到毫秒级响应
android·性能优化·kotlin·room
初一初十1 小时前
vue3实现的纯前端护肤品商城网站
前端·javascript·vue.js·前端框架