DEFCON CTF 2020 游(线上)记 July 3, 2020 本次 DEFCON CTF,因为疫情原因,便进入了“SAFE MODE”,也就是线上举办。而为了“照顾”到所有地区的参赛者,他们也没有按照正常的时间来办,而是把整个比赛分为了四个“shift”,每个 shift 长为 8 小时,每两个 shift 之间间隔 9 小时,另外在每个 shift 开始之前,会有 1 小时的准备时间。第一个 shift 从北京时间 8 月 7 日晚 8 点开始。稍有常识的读者都能算出,主办方照顾到了所有人,让大家都有两个 shift 在凌晨。 本文为了方便描述,也使用 shift 1~4(准备时间也算入下一个 shift 中),而非之前一些文章中的 DayX,来指代大致时间。另外,为了方便描述 shift 之间,以及比赛开始前的时间,可能也会用到 shift X.5 的描述。 # shift 0.5 比赛前几天去了上海玩,这一天去逛 bw。不过由于配网的锅也丢给了我,所以就在 bw 现场配网。一边看表演一边敲命令,实在是有点草。 主办方赛前称,离他们的基础设施最近的 AWS 区域是 us-west,然而 AWS 没有叫这个的区( 于是我在 us-west-1 和 us-west-2 各开了一台,然后测试用教育网中转 openvpn。(虽然主办方给的 wireguard,但是好像他只让一个客户端连,于是我就用 openvpn 给大家中转了) 配到能用之后,用 iperf3 测了测速,能有 150Mbps,基本还行。 # shift 1 开场时,在 us-west-1 ping 主办方的 vpn endpoint,延迟高达 1ms,看来主办方的全套设施应该也都在 AWS 上吧。 这个 shift 的大多数时间都在路上跑,于是没怎么看题。 中途,刘大爷说下载文件只能 1Mpbs,于是赶紧测试了一下,发现确实如此。把 openvpn 改成 tcp 模式之后也只有 20Mpbs 左右,调了一些别的参数也没啥用,只好将就用。。 # shift 1.5 赶去和大家回合。 # shift 2 开场时,看了看 21 点和之前的某道 pwn,然后发现都不会。 不久之后,放了一道新题,pinboooll。这题给了一个 binary,里面有许多条件判断,每个条件判断通过了可以有一些加分。这些条件判断看起来确实颇有几分三维弹球的味道——有一个状态变量,类似于弹球在整个界面中的位置,当比较靠左时可以用左边的挡板弹,靠右时用右边的挡板弹;另外还有一些时候会触发任务,然后拿到一些“Jackpot”,这些 Jackpot 自然也有额外加分。 binary 最开始会要求给出一个文件名,当这个文件中的不同字符数有 5 个,就成功发射弹球。弹球的初始状态是随机的,不过种子是确定的。 但是,初始状态下,所有操作都执行不了,在研究了好久之后,我发现可以用程序不识别的操作,来避免退出,并获得每轮的加分。 继续逆了两个小时,有人发现可以用 .. 当那个文件名,不在一开始就发射。之后可以操纵一下随机数,跳出这个难受的状态。 跳出这个状态之后,(这篇文章本来是在 8 月份开始写的,但是写到这时咕了,11 月才继续写,很多细节记不清了,接下来的部分大概会简略很多)能做的事情就很多了,但是得分还是很困难。 我尝试着手动构造输入,这持续了整个 shift 的后半段,而排名一直时上时下,最后这个 shift 结束了。 # shift 2.5 继续研究这个 pinboooll。我打算写个脚本,去自动枚举得哪些分,然后构造满足条件的输入。我和大雄合作,他搞算得分的部分,我搞构造输入的部分。肝到凌晨几点时,写的差不多了。但是这时我们发现,这一坨策略好像用处并不是很大。 这个 pinboooll 里面,有一个 secret,猜中就可以得 5000 分(可能记错了,说不定是 2000),还能重复得分,也就是可以直接猜几十次,直到输入长度限制为止。leak 出这个 secret 的脚本倒是之前就写好了。但是我在写构造输入脚本的时候,是按照这个 secret 只能用一次处理的,没想到可以搞这么多分。于是这一堆可能就算是白写了(其实也没完全白写)。 最后,这个输入可以得十万多分,这是什么概念呢,shift 2 结束时最高分还只有三千多。 # shift 3 跑了 leak secret 的脚本,然后得了十万多分,这题暂时第一。实在肝不下去了,睡觉。 一觉醒来,shift 3 已经过去了一大半。此时 pinboooll 的排行榜上,最高分已经二十多万还是三十多万。继续搞了搞,没发现有啥能搞的,正巧此时有一道新题 sloootmachine,我就去凑热闹了。 这一题是一个白盒 aes,具体来说,就是选手互相写一个 aes 加密器,然后你要找出别人的加密器的 key。这题主要是刘大爷在做,我只是去划水,并且直到最后也没有成功输出。(不过我这里写的代码倒是在后面 THUCTF 出题和 TCTF 决赛用到了,这也是另外两个故事了) # shift 3.5 吃饭,划水(sloootmachine)。 # shift 4 划水(sloootmachine)。 不过没多久,这题就下了,于是去看 ropshipai。这题是去年 ropship 的加强版,这次需要写个神经网络来搞。但是他程序有明显的栈溢出。 之前看到这道题,并没有什么好的想法,这时再来看,我就研究这个栈溢出。虽然明显溢出了,但是实际上并不好利用,我搞了好久终于可以往栈上放足够长的数据并且跳过去。 rop 这部分是 M4x 在搞,然后他也调了好久,最后发现,这个程序有 seccomp,实际啥都干不了。 比赛结束,gg。 # shift 4.5 回酒店睡觉。 一觉醒来,已经两点过了,酒店都来催退房了。然后本来订的晚上的机票还 tm 被取消了,航空公司给换了个第二天的。 看到时间勉强够,买了个 3 点过的火车票,赶上了。 颓了一下午,回到了家。