This page looks best with JavaScript enabled

BJD3rd&NepCTF出题反思

 ·  ☕ 5 min read · 👀... views

连续参加了两个月的DASCTF出题,感觉有不少收获与心得,也对当前CTF Re方向的发展趋势有了一个较为深入的思考与认识。

BScript

BScript是我第一次出题,应颖奇师傅的邀请,将它投到了BJD3rd比赛中,根据问卷来看,这题好评度颇高。这题的思路来源与年初的某次比赛,那道题也是一个可执行文件的嵌套,出题人先用汇编编译了一个超小的汇编语言程序,并将其每一个字节都拆出来放到一个ELF中,每个ELF只有一个整数输入和一个判断,做题者需要提取出所有文件中的那个正确的整数以组装成一个新的文件。因为每次只输入一个数,同时又是ELF文件,就可以使用Pwntools进行爆破,从而得到所有的字节码,而我当时做这题的时候是通过IDAPython和直接的字节码识别if来提取的数据,赛后才知道可以直接用Pwntools进行爆破获得,从而就萌生了一种只能用IDAPython等自动化脚本的方式进行解这类题目的出题想法,因而出了这道BScript

BScript我先编译了一个PE,然后将其随机拆分成32/64个字节,共三种情况,将他们依次存放在804个PE文件中。因为是PE,每次输入的量不固定且比较大,不存在爆破获取全部字节码的情况,因而要求做题者需要用自动化的方式批量识别每一个文件分别对应哪种情况并自动的提取出字节码,最终组装成一个完整的程序。

从今年的比赛来看,我相信自动化的Re解题绝对会是未来的一种发展趋势,我个人也在朝着这个方向进行研究,同时在近期的一些比赛中,自动化的工具已经充分展示了它们的威力,为我的解题节省了大量的时间。因而,在未来的出题中,我也会向着更偏向于对做题者自动化脚本编写能力的考察。

DDoll

DDoll是刚刚结束的 HNUSEC X Nepnep DASCTF 中的一题。这题的评价与上一道BScript截然相反,甚至有带哥12分钟就拿下了一血눈_눈,对于这种情况,我自己也确实是没有想到,因为这题也花了我很多的精力。

DDoll的主要考点是Tls反调试和一定量的混淆。从我的观察来看,新生代的REer们,都太过于依赖IDA了(包括我自己)。IDA虽然堪称地表最强工具,但是其在动态调试方面其实还是有诸多问题的,比如会捕捉一些不必要的异常,比如对于一些新式语言编译产物动调时会断不下来。因而这道题,我的各项反调试与混淆,专门针对的就是IDA。

这题首先在Tls函数中获取了PEB.NtGlobalFlag的值并将其保存在一个初值为0x70的全局变量里,在后面的加密RC4算法中,将这个变量丢进去异或。这就导致了如果被调试器附加,该全局变量的值就会变成0x70,导致加密结果出错,而没有被附加该全局变量会被重新赋值为0,0与任何数异或,结果不变,该算法仍为标准RC4加密算法,这也满足了安恒对Re题不可自创算法的要求。然后我对用于比较的密文进行了双向加密,强迫做题者动调。同时这题我掺杂了不少混淆,还夹杂了一些花指令,对于IDA的伪代码有很大程度的干扰,因此这题使用IDA做是非常不合适的。从目前提交上来的题解来看,大部分解出来的人也都是使用OD的,这也满足了我的预期。

但同样的,因为使用OD,就不存在反调试这个概念了,从他们的题解来看,几乎都是没看出反调试直接就莽出来了,导致了这题最后的解答量远远超出了我的预期。确实的,如果这题没有了Tls,那就是很平常普通的一道题了,那一点点混淆和花指令根本起不到什么保护,双向加密只要动调到比较处dump出数据就可以了,这也确实是我的失误。

反思

首先,先来反思一下这两次比赛中我出现的问题吧。最严重的问题就是这两次比赛我都忘了静态编译。因为我本身很少使用vs,一般都是gcc加个参数完成静态编译,vs编译后自带了很多函数,我就以为vs是自动静态编译了….然后这次DDoll因为双向加密,又是动态编译,导致一些师傅运行不了程序(别骂了别骂了,出题人已经挨打了QAQ

然后要来反思一下NepCTF这次Re被人AK的原因。作为Re审题,这个问题我责无旁贷,这次的Re都太常规了,都是一些出现过好多次的类型了,完全就和新生赛没区别了,甚至我看题解中有个Misc师傅来做Re把ReAK了。这里向各位师傅们道歉了,这次实在是太匆忙了,期末师傅们考试多、比赛多,好多师傅都是卡着ddl交的题,导致了题目骚操作接不上、难度上不去。对于本次比赛Re太多简单,队内也做了很多批评与反思。12月还会有一次队赛,这次我们将用6个月时间精心准备,严格审题,到时候一定给师傅们更好的体验。

最后来说一下我通过这两次Re出题而对CTF Re发展趋势的总体看法吧。现在Re难题已经很难出了,常见的操作已经被玩烂了,普通的技巧已经完全满足不了日益变强的REers了。C++、Python逆向已经被玩烂了(这次的pyCharm和DDoll被打烂就是血淋淋的教训),控制流平坦化也有angr一把梭可以直接秒,vm也已经出现太多太多次了,熟练的带哥们几乎一眼就能看出opcode对应什么操作。这就使得Re难题陷入一个比较尴尬的趋势。我个人觉得,接下来的Re难题有这么几个发展趋势:

  1. 算法加难 整些混和算法,比如De1CTF那个分段混和加密,然后可以弄些爆破算法,比如掺杂点哈希爆破之类的

  2. 新式语言 小众化语言逆向,比如rust、go、.NET这些,然后最好将他们和汇编结合起来,比如第五空间这个ManageCode

  3. 新架构 之前新架构Pwn出现的比较多,新架构Re一般只会在Defcon这种国际赛才会出现,但就近期比赛来看,已经有mips Re出现了,未来,新架构的Re应该也会常态化

  4. 更贴近真实 CTF赛题肯定都会越来越贴近真实的软件,比如近期的GKCTF已经出现真实的病毒分析了。我觉得在Re难题已经很难出现新的骚操作这样的大环境下,真实的病毒分析、驱动分析、软件破解也会越来越多

以上都是一些个人的看法和反思,如果觉得我有说的不对也欢迎与我讨论。这次DASCTF Re的失误确实太严重,我们一定会在12月还师傅们更好的体验。

Share on

Qfrost
WRITTEN BY
Qfrost
CTFer, Anti-Cheater, LLVM Committer