0x00 题目分析

比较可惜这题没在规定时间内做出来,被劫持摆了一道

0x01 解

无壳,直接上IDA

main函数相对比较简单,不难看懂,重点应该就是图中的sub_7A121C

跟进去可以发现是XXTEA算法,key就是byte_7AB048=[0x44, 0x41, 0x53, 0x21]

而sub_7AB000里面就是32字节长的东西

取一下enc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import struct


def read_int_array(file_name):
with open(file_name, 'rb') as f:
data = f.read()
return struct.unpack('<'+'i' * (len(data) // 4), data)


a = read_int_array('./enc.txt')
enc = []
for i in range(8):
enc.append(a[i])
for i in enc:
if i < 0:
i += 2**32
print(hex(i), end=", ")
# 0x9432244e, 0x5f60b399, 0xee847593, 0xdccbe9cc, 0x86e178b1, 0x2f304163, 0x543b0818, 0xb2205663,

直接上脚本?

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
30
31
32
33
34
35
36
37
38
39
40
41
42
import struct


def shift(z, y, x, k, p, e):
return ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((x ^ y) + (k[(p & 3) ^ e] ^ z)))


def decrypt(v, k):
delta = 0x9E3779B9
n = len(v)
rounds = int(6 + 52 / n)
x = (rounds * delta) & 0xFFFFFFFF
y = v[0]
for i in range(rounds):
e = (x >> 2) & 3
for p in range(n - 1, 0, -1):
z = v[p - 1]
v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[p]
p -= 1
z = v[n - 1]
v[0] = (v[0] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[0]
x = (x - delta) & 0xFFFFFFFF
return v


if __name__ == '__main__':
k = [0x44, 0x41, 0x53, 0x21]
enctxt = [0x9432244e, 0x5f60b399, 0xee847593, 0xdccbe9cc, 0x86e178b1, 0x2f304163, 0x543b0818, 0xb2205663,]
print("===========================================================================")
# 解密
decrypted = decrypt(enctxt, k)
print(decrypted)
for i in range(len(decrypted)):
print("{:08X}".format(decrypted[i]))
tmp = b''
for i in range(len(decrypted)):
tmp += struct.pack('<L', decrypted[i])
print("解密内容:")
print(tmp)
# b'DASCTF{NO!!Th15_15_F@k3F1@G_qwq}'

临近比赛结束出了个fakeflag,至此错过提交时间(

之后想了想应该没这么简单的,直接上动调,从比较的地方入手

结果连断点都没到就给我截下来了

还是降低难度了,这个地方不放个int3完全可以

看来在比较之前被劫持了,执行了其他东西

一个个看

这个byte_17B024里面也是32字节的数据,可能这个才是真的flag

不过用XXTEA直接解是没有什么结果的

而之后的这个函数sub_171348跟下去会发现是比较

试了试向上跟也没发现什么很有意思的东西,只是发现劫持用的函数

不过在比较的函数里发现加密结果不同了

我输入的是全1,在XXTEA的加密结果应该是这样的

1
2
3
4
5
6
7
8
9
10
"""
57505803
608BF893
3E4021AD
BAD19A87
1A37D5C3
14B0A95B
6081C020
DB4BE498
"""

可以发现应该后面又加了一次什么东西

在main函数中的比较下断点,然后再下内存断点,看看什么时候这个结果被更改了

断下来之后就能发现这个

XTEA算法

看来XXTEA之后又进行了XTEA加密

不过继续运行起来会发现不止使用了一次XTEA加密,而是两次(一共断下来四次,加密一次会断两次)

之后再进行跟踪会发现两次XTEA之后就比较了,看来加密方式就是一次XXTEA加上两次XTEA

需要注意的是XTEA一次只对数组中的8字节进行操作,所以要将输入两两一组分为4组进去进行操作,轮数是0x24H = 36D

上脚本!

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import struct


def XTEAdecrypt(rounds, v, k):
v0 = v[0]
v1 = v[1]
delta = 0x9E3779B9
x = delta * rounds
for i in range(rounds):
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (x + k[(x >> 11) & 3])
v1 = v1 & 0xFFFFFFFF
x -= delta
x = x & 0xFFFFFFFF
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (x + k[x & 3])
v0 = v0 & 0xFFFFFFFF
v[0] = v0
v[1] = v1
return v


def shift(z, y, x, k, p, e):
return ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((x ^ y) + (k[(p & 3) ^ e] ^ z)))


def XXTEAdecrypt(v, k):
delta = 0x9E3779B9
n = len(v)
rounds = int(6 + 52 / n)
x = (rounds * delta) & 0xFFFFFFFF
y = v[0]
for i in range(rounds):
e = (x >> 2) & 3
for p in range(n - 1, 0, -1):
z = v[p - 1]
v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[p]
p -= 1
z = v[n - 1]
v[0] = (v[0] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[0]
x = (x - delta) & 0xFFFFFFFF
return v


encrypted = [0x87aaa7c1, 0x857321b6, 0xe71d28c, 0xcadf39f2, 0x58efca14, 0xd7e7d9d8, 0xf29f5c5d, 0x5f5ed45e]
k = [0x44, 0x41, 0x53, 0x21]
rounds = 36
i = 0

for j in range(int(len(encrypted)/2)):
tmp = [0]*2
tmp[0] = encrypted[i]
tmp[1] = encrypted[i+1]
tmp = XTEAdecrypt(rounds, tmp, k)
encrypted[i] = tmp[0]
encrypted[i+1] = tmp[1]
i += 2

i = 0
for j in range(int(len(encrypted)/2)):
tmp = [0]*2
tmp[0] = encrypted[i]
tmp[1] = encrypted[i+1]
tmp = XTEAdecrypt(rounds, tmp, k)
encrypted[i] = tmp[0]
encrypted[i+1] = tmp[1]
i += 2

decrypted = XXTEAdecrypt(encrypted, k)
tmp = b''
for i in range(len(decrypted)):
tmp += struct.pack('<L', decrypted[i])
print(tmp)
# b'DASCTF{Gr3@t!Y0u_have_50lv3d_1T}'

真是给摆了一道呢(