0x00 题目分析

跳跳虎,主要是要找到程序的执行路径,然后转换成能看的东西

0x01 解

无壳,直接上IDA

超多if,上面还有超多while,实际上就是进行判断,如果条件满足,那么就不break,而是执行下面的程序

没什么技术含量,主要是一个个跳着看,IDA选中条件之后就会黄色高亮,一个个看就好了

这个main_crypto里面也是和main函数一样的跳

为了保护大脑不从头顶跳出去,我选择直接解释一下这个main_crypto

这玩意的重点在于标注出来的enc

它将进行一些位运算,然后将结果存入temp中,这个temp是一个密码表

将input数组中的值作为索引在密码表中找对应的值然后放回input内

相当于一个映射

加密过程我转为python了,可能比较好看一点(只是方便理解,不能运行的)

1
2
3
4
5
6
7
len1 = 32
i = 0
input = []
for i in range(256):
enc = ~(len1 ^ i)
for i in range(len1):
input[i] = enc[input[i]]

解密就是逆运算,在main函数最下面可以找到这个crypto_flag的数组,里面就是通过映射搞出来的加密信息,根据这个crypto_flag的结果去表里面找index就是flag了

非常奇怪的是,它的flag长度是32字节,但是作为len丢进去计算表并不正确,所以在解密的时候我选择进行爆破,不停换表查看结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import struct


def read_int_array(file_name):
with open(file_name, 'rb') as f:
data = f.read()
return struct.unpack('c' * (len(data) // 1), data)


a = read_int_array('./crypto_flag.txt')
enc = []
for i in a:
enc.append(int.from_bytes(i, byteorder='little', signed=False))

for j in range(100):
input = []
table = []
for i in range(256):
table.append(~(j ^ i) & 0xff)
for i in range(32):
input.append(table.index(enc[i]))
if (chr(input[0]) == 'D'):
print(j)
else:
continue
for i in range(32):
print(chr(input[i]), end="")
print()
# DASCTF{good_the_re_is_easyhhhh}Â

最后爆出来长度是61才能得出flag,不是很懂为啥(