出题团队简介
赛题设计思路
本题算法延续了KCTF2022-春季赛-第八题迷雾散去的设计方法:
1、题目设计为双进程模式,算法的校验分别放在两个进程中,并通过管道通信且父子进程使用相互ptrace防调试处理;
2、管道通信读写及部分操作如: open/read/getpid等系统调用通过中断svc指令实现;
5、增加防frida检查;
反汇编器 负责解析输入二进制文件,输出函数指令和数据流
解释器 负责对vm指令和数据流进行解释执行
链接器 负责将vmachine嵌入新二进制文件中,并对地址相关的指令做重定位
.text:000016C2 19 4C LDR R4, =(__stack_chk_guard_ptr - 0x16CC)
.text:000016C4 C3 B0 SUB SP, SP, #0x10C
.text:000016C6 01 AE ADD R6, SP, #0x120+var_11C
.text:000016C8 7C 44 ADD R4, PC
.text:000016CA 24 68 LDR R4, [R4]
…
.text:00001728 A0 38 00 00 off_1728 DCD __stack_chk_guard_ptr - 0x16CC
.text:00006000 19 4C LDR R4, =(__stack_chk_guard_ptr - 0x16CC)
.text:00006002 C3 B0 SUB SP, SP, #0x10C
.text:00006004 01 AE ADD R6, SP, #0x120+var_11C
.text:00006006 7C 44 ADD R4, PC
.text:00006008 24 68 LDR R4, [R4]
…
.text:0000606C A0 38 00 00 off_1728 DCD __stack_chk_guard_ptr - 0x16CC
LABEL_BASE:
.word 0x62220000
LABEL_DISP:
.word 0x3280
PUSH {R0-R15}
LDR R0, LABEL_BASE
LDR R1, LABEL_DISP
ADD R0, R1
STR R0, [SP, #0x3C]
POP {R0-R12}
ADD SP, #0xC
LDR PC, [SP, #-4]
赛题解析
本赛题解析由看雪论坛会员 mb_mgodlfyn 给出:
但是把代码混淆作为CTF题目考点来出的话,如果没有较为成熟的开源项目可以利用,个人感觉对攻击方是有些为难的。因为CTF的初衷是Hack for FUN,其次是技术交流。硬刚VMP的过程往往不太FUN,而从技术分享的角度看,此题的混淆强度4天时间如果从零开始写自动化工具基本也不大可能。
当然,防守方也许会考虑到攻击方有自己的私藏武器。但是如果思考一下这个问题可以发现,如果以SATURN论文的工作量作为参考,可以想象实现这样一个去混淆框架至少要全力投入数月(甚至考虑前期对VMProtect的逆向分析,时间周期会更长),经过不断的迭代才能有一些初步的效果,可能只有本职工作在此的人才能有足够的精力投入其中。
而且,即使有了这样的工具,用来解题肯定也要做针对性适配,而这又是一个深坑:单凭一道题目搞清楚代码混淆方式就要花费大量时间,何况还要修改原有的工具,再重新测试,4天时间恐怕也不太现实。另外,考虑到计算机行业的技术开放程度,虽然业界最强的工具不一定开源,但基本上开源界总会有相同功能的工具,而且至少可以做到能用的程度(可以对比IDA和Ghidra)。
但是现在似乎还没有发现高调售卖的商业化VMP去混淆工具,而且现有的几个开源的VMP去混淆工具效果还不是非常好。不过,随着时间发展,还有能够相信未来会出现成熟的工具的。(其他CTF比赛也出现过以代码混淆作为考点的题目,不过题目为了考虑时限内的可解性(而不是为了单纯测试混淆的强度是否足够高到无人能解;如果真是这样的目的就应该搞付费悬赏,和SRC平台一样),强度往往被有意降低,重点在于展示思路,于是很好的兼顾了难度和技术交流)
不妨回顾下近几届KCTF所有以代码混淆为主要考点的题目,似乎没有一个人是真的靠自己写的自动化去混淆工具还原出原始逻辑进而解出题目的,基本上都是靠动态调试、trace跟踪、人为观察等方式,靠堆体力找出逻辑,而且,也没有任意一个出题人公开自己写的自动化去混淆工具,这样无论攻击方还是防守方,从技术交流的角度总感觉缺少了一点灵魂(p.s. 不过很多基于动态调试的解题方法也非常硬核而且能学到很多知识)。
而且这种工具对安全行业具有颠覆性的意义,即使闭源高价售卖也是有巨大市场的)(此外,回想自己作为某比赛出题人时,负责人给的硬性要求就是必须自己以做题人的视角解一遍确保可解性和做题体验,而且对于代码混淆的使用有严格的限制,必须保证自己有合理的解法(比如,有成熟工具可利用,或者从零开始能在赛期内写出工具,或者有足够的线索提示能够完全绕开混淆);而且到最后往往会发现,某些题目即使开源给做题者都不会降低难度)。
所以,基于以上推理,只能合理假设既然用了VMP来出题,那么就默认了出题人是希望攻击方寻找捷径,而不是硬刚代码混淆,因为对于本题的混淆强度从零开始的话4天的时间基本上不可能写出自动化的工具。
回到本题,对本人来说正常做是不可能做出来了,也只能想一想其他的路。
根据公开的serial可知合法的serial长64字节,每个字符取值[0-9A-F],实际上hexdecode后是32字节。
jadx逆向apk,发现java层什么都没有,只是把name和serial都传给so然后接受一个字符串并显示出来。
Android Studio 开一台 arm 架构的虚拟机,x64dbg 调试 qemu-system-armel.exe
000002892A9CE570 00 00 00 00 00 00 00 00 13 00 00 00 AB 00 00 00 ............«...
000002892A9CE580 02 EB FF FF A9 15 00 00 E7 97 8C 92 84 96 8C 92 .ëÿÿ©...ç.......
000002892A9CE590 E8 96 8C 92 50 00 00 00 23 00 00 00 10 C1 7B A2 è...P...#....Á{¢
000002892A9CE5A0 EE DF DE 0E B8 CB 7B A2 00 00 00 00 1C 96 8C 92 îßÞ.¸Ë{¢........
000002892A9CE5B0 15 FC 7D A2 9D 60 7C A2 D4 FF 7D A2 00 00 00 00 .ü}¢.`|¢Ôÿ}¢....
000002892A9CE5C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002892A9CE5D0 00 00 00 00 00 00 00 00 00 00 00 00 2C 3F 7C A2 ............,?|¢
000002892A9CE5E0 01 00 00 00 E8 96 8C 92 E7 97 8C 92 23 C1 7B A2 ....è...ç...#Á{¢
000002892A9CE5F0 E7 97 8C 92 00 00 00 00 E8 96 8C 92 50 00 00 00 ç.......è...P...
000002892A9CE600 FC 56 00 00 00 30 7B A2 FC 86 7B A2 23 00 00 00 üV...0{¢ü.{¢#...
000002892A9CE610 E8 96 8C 92 04 00 00 00 79 3F 7C A2 FC 86 7B A2 è.......y?|¢ü.{¢
000002892A9CE620 20 00 00 00 84 96 8C 92 5C 96 8C 92 49 49 7B A2 .......\...II{¢
000002892A9CE630 A9 15 00 00 00 00 00 00 00 00 00 00 20 0A 00 00 ©........... ...
000002892A9CE640 22 00 00 00 30 00 00 00 EF FE DD 00 30 C1 7B A2 "...0...ïþÝ.0Á{¢
(初始serial是64个0;行标头表示改变serial的第几位,列标头表示改变为哪个值)
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 DB86 DB76 DB66 DB56 DBC6 DBB6 DBA6 DB96 DB06 DAF6 DAE6 DAD6 DB46 DB36 DB26 DB16
1 DB86 DB85 DB88 DB87 DB82 DB81 DB84 DB83 DB7E DB7D DB80 DB7F DB7A DB79 DB7C DB7B
2 DB86 DB76 DBA6 DB96 DB46 DB36 DB66 DB56 DC06 DBF6 DC26 DC16 DBC6 DBB6 DBE6 DBD6
3 86 85 84 83 8A 89 88 87 7E 7D 7C 7B 82 81 80 7F
4 B8 B7 BA B9 BC BB BE BD C0 BF C2 C1 C4 C3 C6 C5
5 86 85 84 83 8A 89 88 87 8E 8D 8C 8B 92 91 90 8F
6 B8 B7 BA B9 B4 B3 B6 B5 C0 BF C2 C1 BC BB BE BD
7 86 85 84 83 82 81 80 7F 7E 7D 7C 7B 7A 79 78 77
42A4ECA0 // 这是使得 0x2892A9CE580 取值最大的输入
(BD5B135F) // 这是使得 0x2892A9CE580 取值最小的输入
0 1 2 3 4 5 6 7 8 9 A B C D E F
8 B8 B7 BA B9 BC BB BE BD B0 AF B2 B1 B4 B3 B6 B5
9 86 87 88 89 8A 8B 8C 8D 7E 7F 80 81 82 83 84 85
10 B8 B9 BC C0 C4 C7
11 86 8A 8B 89 7E 7C 82
12 B8 B7 B6 B5 BC B9 B0 AD B4 B1
13 86 82 7E 7A 77
14 B8 BC BF B0 B3 B4
15 86 8A 89 7E 7D 7C 7B 82
67F54074
(980ABF8B)
0 1 2 3 4 5 6 7 8 9 A B C D E F
16 B8 B5 BC C0 C4
17 86 89 82 7E 81 7A 7D
18 B8 B7 B9 BC C0 C4 C3 C6 C5
19 86 82 83 84 8E 8F 91 8A
20 B8 B7 BA B5 B0 AC AB AD
21 86 89 8A 8E 92 95
22 B8 B9 B7 B4 B0 B1 AE AC AD AA
23 86 8A 8D 7E
C3EB2F17
(3C14D0E8)
0 1 2 3 4 5 6 7 8 9 A B C D E F
24 B8 BC BF B0 B4
25 86 82 81 83 8E 90 8A
26 B8 B5 C0 C4 C1
27 86 82 83 8E 90 91 8A
28 B8 B4 B0 AC A9
29 86 8A 89 8C 8B 7E 7D
30 B8 BB BC C0 C4 C5 C6 C7
31 86 85 89 90 91 94 93
7ACB06FE
(8534F901)
0 1 2 3 4 5 6 7 8 9 A B C D E F
32 B8 B9 B5 B2 B3 AE AA AB
33 86 87 89 83 80 7A 7C 7D
34 B8 BD BF B0 B2 B7
35 86 83 80 8F 8C 89
36 B8 B3 AE A9
37 86 8B 7C
38 B8 BD AE B3
39 86 84 83 89 8C 92 8F
1379055C
(EC86FAA3)
0 1 2 3 4 5 6 7 8 9 A B C D E F
40 B8 B6 BD BE C5 C3
41 86 8A 89 88 7C 7B 7F
42 B8 BD C2 C7
43 86 82 83 85 90 91 8D
44 B8 BA B3 B2 AC AB AD
45 86 88 81 80 79 7B
46 B8 B9 B5 AE AA AB
47 86 87 83 7C 78 79
D4FB2211
0 1 2 3 4 5 6 7 8 9 A B C D E F
48 B8 B5 BB BE C4 C2 C1
49 86 89 83 80 7A 7D
50 B8 B4 B5 C2 C3 BF
51 86 84 8B 8C 93 91
52 B8 B3 B1 C0 BE B9
53 86 8B 8D 7E 80 85
54 B8 BC BB B0 AE AD B1
55 86 8B 90 92 95
C3BD874F
0 1 2 3 4 5 6 7 8 9 A B C D E F
56 B8 B3 C2
57 86 84 8B 8C 93 91
58 B8 B4 B5 B2 C1 BE BF BB
59 86 85 88 89 8D 90 94 93
60 B8 B9 B6 B5 AE AA AB
61 86 81 7C 77
62 B8 B9 B5 AE AA AB
63 86 84 8B 8C 93 91
AD9E101D
name: KCTF
serial: 42A4ECA067F54074C3EB2F177ACB06FE1379055CD4FB2211C3BD874FAD9E101D
球分享
球点赞
球在看