De1CTF Re partial

Posted by Qfrost on 2020-05-04
Estimated Reading Time 4 Minutes
Words 1.2k In Total
Viewed Times

太难了太难了!re1从早上9点开题以来一直做做到凌晨2点才做出来 QwQ

跪求官方WP能详细点

parser

真 一题做一天系列…考点是表达式解析(递归嵌套算法+CPP特性),先分段RC4,然后+代表AES,_代表DES。题目改了导入表,开了PIE,并静态编译了,所有函数都要通过动调跟进去才能知道做了什么。因为大量混淆,再加上有递归嵌套,所以动调跟的时候一定要重命名函数和做批注,不然真的会晕的

main函数结构:在进入关键函数(sub_4D18)之前,程序完成了对输入字符串格式检查,解剖并按照符号进行分组。
advance
跟入以后就会发现内容逐渐变态 눈_눈
advance
advance

往里跟会发现混淆的非常厉害,比较好的方法是重命名并着种注意调用函数时参数的传递。因为C++特性,会使输入被复制来复制去,不适合对输入进行内存断点追码。然后关键函数中主要采用3种算法,RC4、AES、DES,然后进行词法分析。输入的字符串中,遇到“+”则进行AES加密,遇到“_”进行DES加密,在此之前,每个分组都进行RC4加密。AES和DES的模式均为CBC,iv和key均为De1CTF。然后分析到这里还有剩下一个问题就是结合顺序是从左往右还是从右往左,多次动调发现结合顺序是从右往左,也就是右边是最先算的。

然后就是漫长的猜谜语。经过和 Bayerischen 长达数个小时的人工爆破,得到flag,分析过程如下
对cipher直接进行两波AES解密,可得
91983DA9B13A31EF0472B502073B68DDBDDB3CC17D0B0B0B0B0B0B0B0B0B0B0B607ADEA582E83F505B76FCB2E564E53A
中间那堆0xB一定是padding了。
前五字节rc4解出“h3ll0”,5-21字节送进DES,将解密结果的前五字节送入RC4解得(w0rld),后五字节解得(l3x3r)。
这样就还剩下最后16字节,这里取用最初的AES解密结果去掉padding后送DES解密再RC4得4nd_p4r53r
advance

FLw

这题就更他妈离谱,出题人这个姿势是真的骚,三行垃圾代码实现IDA的交叉引用死循环(call和call里面的代码来自同一个地方,在call内的add实现了对ret地址的修改),从而IDA 7.0载入直接就死机,真就“调试器漏洞反调术”?

1
2
3
4
.text:00EE548E 0D0 call    $+5
.text:00EE5493 0D4 add [esp+0D0h+var_D0], 5
.text:00EE5497 0D4 retn
.text:00EE5497 sub_EE5470 endp ; sp-analysis failed

OD载入后很奇怪,发现PE头有个错,修改PE头
advance

幸好有大师傅发现IDA6.8不吃这操作,动调跟进去可以看到逻辑在SEH里,关键函数是 sub_DE5620,而且最后有一条恶意抬栈的指令,将其nop掉可以用IDA 6.8正常反编译
advance

很明显是个vm,硬撸指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
v77是个指针数组,分别保存
v77[0]:栈底指针
v77[1]:栈顶指针
v77[2]:tmp (就是一个变量)
v77[3]:栈
v77[4]:数组 7(一个保存数据的数组)
v77[5]:opcode table
v77[6]:input

0x14 0 取下一条指令压栈,cnt += 2
0x20 12 将栈底元素取出放入数组[下一条opcode]
0x2A 22 以下一条opcode为索引将数组中的元素push入栈
0x2B 23 以栈底元素作为数组索引,取该值入栈
0x2C 24 先取出栈底元素,将现栈底元素放入 数组[刚刚取出的元素],pop栈底
0x30 28 tmp = (栈底元素 + tmp<<8) & 0xFF
0x31 29 将 tmp % 下一条opcode 入栈; tmp = tmp // 下一条opcode
0x33 31 取走栈底两个元素,相加后入栈
0x34 32 先取走一个栈底元素,然后再取走栈底元素,与刚刚弹出的元素相减后放入栈顶(取走栈底两个元素,相减后入栈)
0x35 33 取栈底两元素相乘后入栈
0x3A 38 cin
0x40 44 若栈底元素不为0,opcode_cnt -= 下一条opcode
0x41 45 input全部从栈顶一字节一字节入栈
0xFF 235 取走栈底元素,检查是否为0,不为0就exit

然后跟着操作码走,第一次加密的算法应该是base58,但对栈的布局很奇怪,最后没有做出来

赛后反思

这次比赛,深刻体会到了自己有多菜QwQ,巨佬们都是开题后两三个小时内就一血,我17个小时才勉强做出一个。

和一个大师傅聊了赛后感悟,大师傅认为二进制/逆向都在朝着自动化解题的方向发展,人工解题在速度上不可能比得过有自动化脚本辅助来的快。所以接下来我觉得我也应该向着自动化的方向进行学习

最后,打一个广告

Nepnep诚招web,re,pwn,misc,crypto,区块链,想打ctf的acmer,渗透,mobile

详情请联系HR:QQ1048180452

advance