如果在CTF新手群里喊一句“SWPUCTF 2021 新生赛的gift_F12”,大概率会收获一串“签到题还不会”的回复。说实话,这道题确实没有难度门槛,但它又偏偏是很多人在Web方向打通的第一个“小高潮”——那是你第一次真正意识到,网页里能藏东西的地方,远比想象中多。题名里那个“F12”已经把答案提示到了脸上,可为什么还有那么多人卡住?因为大家习惯了“右键查看源代码”这一招,却还没建立“用开发者工具系统性翻一遍页面”的思维。
这篇文章就把这道题从零开始完整拆给你看,包括每一步怎么操作、原理是什么、在哪些地方容易翻车、翻车之后怎么排查。如果你是刚接触CTF、准备在Web方向入门的选手,这篇题解可以帮你把“看网页”这个基本功彻底打牢。就算你已经刷过不少题,看完这篇也能从出题人视角重新理解一遍:为什么签到题也有它的价值。
1. 题目信息与核心考点拆解
1.1 签个到而已,为什么值得认真拆
很多选手觉得“新生赛”三个字就代表“没营养”,于是看到gift更是直接跳过。这个想法我觉得挺可惜的。CTF里的签到题承担着一个关键的引导功能:它用最简单的形式,逼你去掌握某种基础能力。Web方向的签到题十道里有八道都和信息泄露相关,而信息泄露最经典的入口,就是浏览器开发者工具。
这道题的名字拆开看就很有意思。“gift”说明它就是出题人送的分,“F12”则直接点出了解题工具。放到真实比赛场景里,新生赛的题目环境一般部署在比赛平台上,打开题目,你会看到一张很普通的网页,可能就一行字,或者一个完全空白的页面。大多数人第一反应是“这啥也没有”,而熟练的选手已经按下了F12。
1.2 核心考点画像:不只是会按快捷键
这道题名义上考“F12”,实际上的考点是“前端信息收集能力”。展开来说,包含下面几个具体的能力点:
| 能力点 | 具体表现 | 对应面板 |
|---|---|---|
| HTML结构阅读 | 能看懂标签、注释、属性 | Elements |
| 隐藏元素识别 | 能发现不可见区域的文本和内容 | Elements、Styles |
| JS代码定位 | 能意识到脚本里也可以藏数据 | Sources |
| 网络请求观察 | 能检查每个请求的响应体和响应头 | Network |
| 控制台信息获取 | 能看到脚本输出的调试信息 | Console |
| 编码识别与转换 | 能判断一串字符是否是Base64/URL编码等 | 任意工具 |
选择题不会错,但这六个能力点对新手来说,每一个都可能断一次线。最常见的断线点是:按了F12之后只会在Elements面板里瞎看,不会切到Sources和Network。后面我会逐个面板讲透。
1.3 出题人视角:礼物题也讲究“藏”的艺术
站在出题人的角度思考这道题会特别有意思。出题人想在“送分”和“太不像题”之间找一个平衡点,于是选择把flag藏在“你只要认真看就能发现”的地方。这个“地方”具体有多隐蔽?常见的位置无非这几类:
- HTML注释里:
<!-- flag{...} --> - 某个JavaScript变量里:
var gift = "flag{...}" - 隐藏元素里:
<div style="display:none">flag{...}</div> - CSS文件或JS文件的字符串里
- 响应头里:
X-Flag: flag{...} - 控制台输出里:
console.log("flag{...}")
gift_F12这道题,基本就是以上几种情况的组合。你在做这种题的时候,不妨换个身份:如果你是出题人,你会把礼物放在哪里?这样一想,答案的搜索范围就大大缩小了。
2. 从零开始完整解题流程(一步步手把手)
2.1 准备一个趁手的浏览器
做CTF Web题,第一步不是打开靶机,而是选好你的“解剖台”。我建议直接用Chrome或者Firefox。别用老旧的IE,也别用某些双核浏览器默认的兼容模式,因为这些内核在开发者工具的功能完整度上有差距,可能少一些好用的快捷功能。
打开题目地址后,浏览器的地址栏会加载目标页面。新手往往纠结“要不要装什么插件”“需不需要什么扫描工具”——这道题完全不需要,F12就是工具本身。你先确保页面加载完毕,然后做一件事:把鼠标放到页面上,右键,看看菜单里有没有“检查”或者“查看元素”这个选项。有的话就点一下,没有的话就直接按F12,效果一样。
2.2 第一步:按F12,打开那个“解剖台”
按F12之后,浏览器底部或右侧会弹出一个面板,这就是开发者工具。很多教程喜欢叫它“调试工具”,我更愿意把它理解成浏览器的“解剖台”。
你需要先认清它的顶栏有哪些页签。不同版本翻译可能略有差异,但功能对应关系基本一致:
- Elements(元素)
- Console(控制台)
- Sources(源代码/来源)
- Network(网络)
- Performance(性能)
- Application(应用/存储)
新手打开面板的第一反应往往是大喊“这什么东西”,然后关掉。千万别关,这道题的关键就在这几个面板里。如果你看到的面板顶栏里没有Sources或者Network,可以点那个双尖头“>>”展开更多页签。
2.3 第二步:去Elements里看DOM结构
点开Elements面板,你会看到页面的HTML结构被完整展开。它不是给你看“源码”,而是浏览器已经把HTML解析成了DOM树,每层嵌套关系一目了然。
这时候你要做的是抬头看页面、低头看面板,上下对照着找。特别注意下面几种“显眼又隐蔽”的存在:
第一是注释节点。在Elements面板里,HTML注释会显示成<div> ... </div> <!-- 这里是注释 -->的样子,通常带点灰色或绿色。CTF题很喜欢把flag直接写在注释里,因为注释在页面上看不到,但查看DOM结构时非常显眼。你需要逐条滚动检查所有注释。
第二是隐藏元素。有些标签带有style="display:none"或visibility:hidden的内联样式;有些class会引用一个有隐藏属性的CSS规则;还有些文字使用了和背景同色的字体。页面显示不出来,但在Elements面板里全部现形。
第三是自定义属性。有的出题人会在标签上写<div><!DOCTYPE html> <html> <head> <title>gift</title> </head> <body> <h1>欢迎来到礼物站</h1> <!-- flag{start_with_F12} --> <div id="hidden" style="display:none">flag{hidden_in_dom}</div> <script> var gift = "flag{js_variable}"; console.log("恭喜你发现了控制台,flag=" + gift); </script> </body> </html>
把这段代码放到一个静态站点里,打开页面的人如果不按F12,很可能只会看到一行欢迎语。按了F12之后,注释、隐藏节点、控制台输出,三处flag全暴露。做这个练习的意义不在于“出题”,而在于让你体会出题人藏flag时的思路:他要在“一眼可见”和“完全不可见”之间找平衡。你亲手布置一次,以后遇到类似页面就会有天然的方向感。
5.2 下一站:Web安全入门路线图
gift_F12这道题属于“信息收集”类。做完它之后,我建议你沿着这条路线继续爬:
- HTTP协议基础:状态码、请求方法、Header的含义。
- 改包与重放:学会用什么工具抓包、改包、重放请求。
- GET/POST参数操纵:修改参数值、增加参数、绕过前端校验。
- SQL注入:从报错注入、布尔盲注到时间盲注,每个流程搭建一个本地靶场练熟。
- XSS:反射型、存储型、DOM型,搞清楚输出点和执行环境。
- 文件上传漏洞:绕过后缀检查、MIME检查、内容校验。
- CSRF:理解请求伪造的成立条件。
- SSTI模板注入、简单反序列化等进阶方向。
顺序很重要。HTTP基础不牢,后面所有的注入题都会刷得莫名其妙。练习时优先用本地靶场容器,不要对未授权的真实站点动手,这是Web安全学习绝对不能逾越的底线。
练习量方面,我自己的体会是“每天一两道,比周末狂刷十道更有用”。刷题不是拼数量,而是拼每个点是否真正理解。遇到不会的题,先独立折腾半小时,不行再看题解,但看完一定要动手复现一遍。
5.3 我的一点点经验:签到题也要写WP
很多人连题目都懒得看就开始写题解,又有很多人刷完题毫不记录。这两种极端我都见过。我的建议是:签到题也要顺手写一份简短的记录。不用长,就记五样东西:
- 题目名
- 考点
- 解题的关键一步
- 踩到的坑
- 一句话总结
等你写了三五十篇,会发现自己形成了一种“安全直觉”:看到网页第一反应是打开F12,看到输入框第一反应是想想它提交给谁,看到参数第一反应是试试能不能改。这种直觉不是读了某本书就有的,而是靠一次次微小记录堆出来的。
回看这道gift_F12,它真正的价值不是那一个flag字符串,而是它帮你完成了Web方向最重要的一次启蒙:浏览器里没有任何绝对隐藏的信息,只要你敢按F12、愿意系统地翻一遍,答案就在那里。我自己的习惯也是这样,不管多复杂的站,打开之后先F12把Elements、Console、Sources、Network、Application这五个面板快速过一遍,再决定下一步动作。这个习惯,耗费的时间不过几十秒,却能帮我在信息收集阶段少走无数弯路。希望你从这道题开始,把这条肌肉记忆练成,后面的路会顺很多。