array(5) { ["chapterid"]=> string(8) "49409203" ["articleid"]=> string(7) "7300050" ["chaptername"]=> string(8) "第10章" ["content"]=> string(11189) "七月十九号,周六。上午八点四十五分。
工科楼B座三楼的312教室被临时改造成了CTF选拔赛的赛场。教室不大,最多容纳三十人,但今天只来了二十一个——二十三份报名里有两人没出现。课桌被重新排列成六列,每列间隔一米,每张桌上贴着一张A4纸,上面写着参赛者的姓名和学号。A4纸的角翘起来,被空调的出风口吹得一翘一翘的。
312的空调是去年新装的,但温控面板锁在二十六度,不让调。七月中旬的苏州,二十六度的空调跟没开差不多,只是把三十七度降到了"不那么致命"的程度。教室里已经有了一股混合着汗味、笔记本电脑散热口的热风和隔壁食堂飘过来的油烟味。
林墨站在讲台旁边,手里拿着一份打印的题目清单。他出的三道题已经部署到了实验室的CTF平台——一个运行在Docker里的轻量级靶场,每道题一个独立的容器,flag格式统一为`SUSTCTF{...}`。平台展示页面是苏晚晴用一个下午写出来的,黑白配色,左上角是一只像素风的渡鸦图标——方远行的旧ID标志。苏晚晴觉得用这个做校队logo比较合适。林墨没意见。
"九点开始,十二点结束。"苏晚晴站在门口签到台旁边,对陆续进来的参赛者说,"三个小时,三道题。按解题数量和用时排名。前五名进入校队。"
她的声音不大,但教室里的人都在听。签到台上放着一份名单和一盒签字笔,她每核对一个人就在名单上画一个勾,动作很快,不寒暄。
参赛者们陆续坐下。大部分人带着自己的笔记本电脑,少数人用的是学校的台式机——312教室后面有一排 Dell 台式机,开机慢,风扇响,但总比没有强。有一个男生把自带的机械键盘接在台式机上,青轴的咔嗒声在安静的教室里格外刺耳。旁边的人看了他一眼,他没注意到。
林墨扫了一圈。他最关注的三个人已经到了。
赵一鸣坐在最后一排靠窗的位置。他今天穿了一件干净的白色T恤——跟上次那件"I VOID WARRANTIES"相比算是正式了。左手腕上的绷带拆了,露出一道还在愈合的伤口,粉红色的肉芽组织从缝合线之间探出来。他面前摊着笔记本电脑,屏幕上已经开好了三个终端窗口。桌角放着一瓶没开封的矿泉水,瓶身上凝着水珠。
陈逸飞坐在第二排中间。他是二十一个人里唯一看起来完全不紧张的人——靠在椅背上,双手交叉放在脑后,半闭着眼睛。他的笔记本电脑是合上的,放在桌上,甚至没有拿出来。旁边的人都在检查工具、调试环境,他像是在等公交车。
周可然坐在第一排最左边。她比林墨预想的更安静——短发齐耳,圆框眼镜,穿一件浅灰色的棉麻衬衫,袖口扣得整整齐齐。她面前放着一台MacBook,屏幕开着,但上面只有一个空白的终端窗口。她没有像其他人那样提前准备工具,只是坐在那里,安安静静地等。
九点整。苏晚晴关上教室门,走到讲台前。
"比赛开始。平台地址已经发到各位的校园邮箱。三道题分别是Web、Misc和Pwn方向。flag提交在平台上完成,实时排名可以在平台首页看到。允许使用任何公开工具和资料,但不允许相互交流。"
投影幕布上的倒计时开始走字。三个小时。
林墨靠在教室后墙,双手抱在胸前。二十一台屏幕同时亮起来,有的打开浏览器输入平台地址,有的直接在终端里curl。青轴键盘的咔嗒声变得更密集了,夹杂着笔记本自带键盘更轻的嗒嗒声。空调出风口的白噪音铺在底下,像一层底鼓。
---
第一道题,Web方向。
题目叫"留言板的秘密"。靶场是一个简单的PHP留言板系统,界面做得像2005年的老网站——彩色渐变背景,表格布局,Guestbook风格。表面上只是一个可以发帖和查看帖子的留言板,但flag藏在一个需要绕过三层防护才能到达的地方:第一层是弱密码的登录页,第二层是存在SQL注入漏洞的评论查询接口,第三层是被禁用的命令执行函数。
林墨出这道题的思路是引导参赛者走"SQL注入 → 导出管理员密码哈希 → 破解登录 → 利用后台文件上传 → 绕过disable_functions执行命令 → 读取flag"。但他故意做了一个干扰项:留言板前端有一个明显的XSS漏洞,看起来像是"标准攻击路径"。被XSS带偏的人会浪费大量时间在一个没有产出的方向上。
大部分参赛者在十五分钟内完成了第一层弱密码爆破——密码是`admin123`,用Burp Suite或者hydra跑字典三分钟就能出来。但到了第二层,只有六个人在三十分钟内识别出了SQL注入点。
赵一鸣是第一个突破SQL注入层的。
他的手法让林墨微微抬了一下眉毛——赵一鸣没有用sqlmap这种自动化工具,而是手工构造注入语句。终端窗口里,union select的列数判断、数据库版本探测、表名枚举一气呵成,整个过程不到四分钟。手指在键盘上敲得很快,但不是那种乱锤式的快,是有节奏的,像打鼓——每一下都落在点上。这不是刷了三百道Pwn题的人典型的技能树,说明赵一鸣在Web方向上也有底子。
但他犯了第一个错误。
导出管理员密码哈希之后,赵一鸣没有离线破解,而是直接在在线彩虹表网站上查了哈希值。这个操作本身没问题——但他用的网站需要登录,他在查询过程中把靶场的内网IP地址暴露在了第三方平台的请求日志里。CTF比赛的靶场环境通常是隔离的,把内网信息泄露到外网是实战中的大忌。
林墨在笔记本上记了一笔:技术速度快,操作纪律差。
四十分钟后,赵一鸣完成了Web题,拿到了flag。他是全场第一个解出这道题的人。但他的排名优势只维持了不到两分钟——因为陈逸飞也提交了。
林墨走到陈逸飞身后看了一眼他的屏幕。
陈逸飞的操作方式跟其他所有人都不同:他没有用Burp Suite,没有用sqlmap,甚至没有用浏览器。他全程在一个终端窗口里用curl命令手动构造HTTP请求,用Python的一行脚本做响应解析。每一步都精确地落在要害上,没有多余的动作,没有试探。
更让林墨在意的是,陈逸飞在解出flag之后做了一件其他人都没做的事:他把靶场容器的源代码下载了下来,在本地快速审计了一遍,然后删除了三个他认为"可能导致提权"的冗余代码段。
这个操作本身没有任何比赛价值——删了也不会加分,不减分,不影响flag。没人会在比赛中做这种事。
林墨自己会。但他是出题人,他了解每行代码的来龙去脉。
他在加固靶场。
一个参赛者在比赛中加固题目环境——这说明他不仅仅是在解题,他还在想"如果这是真实系统,该怎么防御"。这种思维方式在本科生里几乎看不到,在职业渗透测试工程师里倒是常见。
林墨在笔记本上又记了一笔:思路不局限于攻击,有防御视角。
周可然没有做Web题。她直接跳过了第一道题,打开了第二道Misc方向的隐写题。
---
第二道题,Misc方向。
题目叫"消失的信号"。附件是一段五秒钟的WAV音频文件,听起来像是普通的白噪声,但flag被隐藏在音频的频谱图中——用音频编辑软件打开频谱图,就能看到flag被以文字形式"画"在了高频区域。这是CTF里最经典的音频隐写套路之一,难度不高,但需要有基本的隐写意识。
周可然打开音频文件后没有用Audacity。她用Python写了一段不到二十行的代码,调用了numpy和matplotlib,直接把音频数据做了FFT变换,画出了频谱图。代码从写到运行用了不到三分钟。她的手指在MacBook的键盘上敲得很轻,跟赵一鸣那种打鼓式的力度完全不同——更像是在弹钢琴,每个键只碰一下就抬起来。
flag在频谱图上清晰可见。周可然提交了答案。
然后她做了一件让林墨意外的事——她没有停在这道题上,而是把自己写的FFT脚本保存下来,改了几行参数,运行了一遍。频谱图重新画出来,这一次她看的是更宽频段的频率分布。她在低频区域发现了一个林墨出题时没有刻意放置、但确实存在的噪声模式。
"这道题的音频文件不是纯净录音。"周可然自言自语。声音很轻,轻到只有前排的人能听到。"原始信号被叠加了一个低频载波。出题人可能没有注意到。"
林墨在旁边听到了这句话。说实话——他确实没有注意到。他制作题目时是从一段标准白噪声里截取的,但那段白噪声本身可能包含了某个他没意识到的底层信号。周可然用三分钟不仅解出了题目,还发现了题目自身的瑕疵。
林墨在笔记本上记了第三笔:学术功底极强,细节捕捉能力突出。
赵一鸣在Misc题上遇到了麻烦。他打开了Audacity,看了频谱图,看到了高频区域的flag文字——但他没有直接提交。他开始分析这段flag文字的编码方式,怀疑flag本身还有一层加密。实际上没有,flag是明文的。但赵一鸣花了十五分钟试图"解密"一个本来就没有加密的东西。
这是他的第二个问题:过度分析。在简单的地方投入了不该有的复杂性,在应该果断的地方犹豫了。
陈逸飞在做Misc题时又走了不同的路。他没有用Audacity也没有写代码——他直接用Sox命令行工具把音频转成了频谱图图片,然后用ImageMagick做了一次对比度增强,flag就出来了。全程不到两分钟。整个操作在终端里完成,没有打开任何图形界面。
到第二道题结束时,排名前三是:陈逸飞(两题全解,总用时二十七分钟)、赵一鸣(两题全解,总用时五十八分钟)、周可然(一题已解,用时四分钟,正在做第三题)。
剩下十八个人里,有四个人解出了一道题,其余还在挣扎。教室后排有个男生已经开始打哈欠了。青轴键盘的咔嗒声稀疏了一些——有人放弃了Web题,转去看Misc,有人开始翻手机查资料。
林墨站在后墙,视线在三个重点观察对象之间来回移动。苏晚晴走到他旁边,手里拿着一瓶没开封的矿泉水。
"赵一鸣的Misc题浪费了十五分钟。"她低声说。
"我知道。"
"陈逸飞没出汗。"
林墨看了她一眼。苏晚晴的意思不是字面意义上的没出汗——教室里二十多个人都出汗了。她说的是陈逸飞的状态:他的呼吸频率没有变化,坐姿没有调整过,连键盘上的手指都没有多余的动作。他在做这些题的时候,身体没有经历任何紧张反应。
这不是淡定。这是做过太多次了。" ["create_time"]=> string(10) "1785963693" }