题解、Writeup、游记和碎碎念
这次 DEFCON CTF,是传统的线下赛,我们有选手负责在线下配网,同时还招揽了一群海外选手去充人数。我由于近期在长三角旅游,于是选择到杭州大本营参赛。
乘坐火车由上海前往杭州。出站时竟然只看了看手机上有一坨绿的就行,没有看核酸,也没让做核酸。
看了看 router_pi 一题,由于主要是别人在逆向,我就基本划水。糊了个 ping 的 exp 之后,感觉无事可做,干脆就跑去睡觉了。
早上醒来得知,没有作业,于是继续睡觉。
睡觉。
看 corewar_ni 这道 KoH 题目。前期主要在逆向。
逆完之后,大概可以得出题目逻辑是,有一个 vm,内存一共 0x4000
。每个位置有一条指令,有加减乘除、条件跳转、fork 等指令。主场的程序被放在 0x0
,客场的被放在 0x2000+offset
。当某个程序遇到非法指令时,他就输了(似乎还有别的胜负条件,没逆清楚)。超过总指令数上限就平局。16 个队伍两两比赛,根据每一场的结果来判分。
大多数指令会限制你操作的内存必须在 pc 所在的 0x2000
范围内,以及在跳转时也如此限制。但是 0x1
这个 mov 指令留了一个后门,可以让主场的程序去写 0x2000
~ 0x2009
的内存。以及 0x8
这个条件跳转指令也有后门,可以让 pc 在整个 0x4000
的范围内 +1。
利用这两个 bug,可以从主场把恶意代码放到客场去,并且跳过去执行。恶意代码再把客场的代码改为非法,从而赢得这一场。
接下来就是骂主办方的时间了。
主办方提前给出了每一轮的 offset
,于是可以据此在每一轮提交对应程序。
最开始,大家交的代码都是 0x11
,这是个不会增加 pc
的 nop
,也就是死循环。我们在快到 offset=3
的某一轮发现了第一个 bug,于是写了一个利用程序提交。然后这一轮就再也没有出结果。
过了一段时间,我们发现了第二个 bug,写出了程序并且加了一些混淆。这个程序是针对 0x11
的死循环搞事的,并且内部写死了 offset
,也就是只会去覆盖一条指令。
在每一轮,我们提交这一轮的 offset
对应的程序。在 15 分钟后,终于出了一轮的结果,发现并没有像预期一样拿分。又等了几轮,还是没拿分。
我们猜测可能需要提交下一轮的 offset
才对,于是据此操作,然后 15 分钟后还是没分。
然后又把上一轮和下下轮之类的都试了一遍,总之都没有分。
甚至把主办方的人叫过来讲了做法,得到了肯定的答复,并且问清楚了 offset
到底应该是哪一轮之后,还是没有分。
于是弃疗了。
这时候,perfect root 和 MMM 交了一个对所有 offset
都有效的解,于是抄了过来。
MMM 的解除了去篡改别人的,大概还会在自己这边开几个线程自我复制,以此来防止被吞噬。
在最后一段时间,我写了一个类似的东西,并且通过调参(比如从哪开始覆盖,按什么方式覆盖)精确的干掉了 MMM,稍微上了一波分。这个被抄之后,我改了改,然后通过调参精确的干掉了自己和 MMM。
最后,骂主办方的一天结束了。
睡觉。睡醒起来听说 corewar_n2 这题非常刺激。
这题和 corewar 的结构类似,但是 vm 变成了 x86。
由于大家都 patch 了 corewar_n2 的输出 flag 功能,于是我们(指杭州这边搞这题的人,其他地方的人大概在尝试别的做法,以及抄作业)找他内存里有没有 flag。然后发现,主场的栈里面有。于是写了个客场程序去覆盖主场的代码,让他把栈里的东西 pop 出来。
写完之后测试,发现大家要么连不上,要么把内存里的 flag 都干掉了,要么直接是个假 flag。
然后主办方的平台还有问题,tick 迟迟不更新,写完这个 exp 是 tick 191,最后结束的时候好像都只有 tick 196,而且还是不得己提前结束的。
不过这和我也没有关系了,反正我中途就跑去睡觉了。
不如 i 春秋。
日期: 2022-08-15