0%

decryptme

1. encryption代码逻辑

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
int __cdecl encrypt(unsigned __int8 *out, char *in)
{
char xor_ch; // ST09_1
char and_ch; // ST08_1
char tmp_ch; // ST08_1
int result; // eax
char index; // [esp+Ah] [ebp-6h]
unsigned __int8 src_ch; // [esp+Bh] [ebp-5h]
signed int i; // [esp+Ch] [ebp-4h]

for ( i = 0; i <= 31; ++i )
{
xor_ch = i ^ in[i];
and_ch = i & in[i];
src_ch = in[i];
index = i;
do
{
tmp_ch = 2 * (index & src_ch);
src_ch ^= index;
index = tmp_ch;
}
while ( tmp_ch );
result = src_ch;
out[i] = src_ch;
}
return result;
}

将输入的字符串中的每个字符根据其下标i做相应的加密操作,如上面的伪代码中的do-while循环所示,先是做了一个&操作,然后做了一个异或操作,每次循环判断&操作的结果是否为0,为0则完成加密。单独看这段代码不知道他到底做了什么,室友发现了一个奇妙的地方,其实这就是将字符的ASCII码值减去下标的值(从0开始),得到的新ASCII值为加密后的字符。具体的逻辑是为什么不太清楚现在,看来得弄清楚&和^到底具有什么实质性作用才会懂。

2. 解法

根据上面得分析可以写个脚本来将加密后字符串解密回去。

也可以写个爆破脚本来把(0,0xFF)内的值都试一遍:

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
#!/usr/bin/env python3
def encrypt(flag,i):
out = 0
and_ch = i & flag
#print("i:",hex(i),"ch:",hex(input[i]))
src_ch = flag
index = i
while (1):
tmp_ch = 2 * (index & src_ch)
src_ch = src_ch^index
#print("src_ch:",hex(src_ch))
index = tmp_ch
if tmp_ch == 0:
break
out = src_ch
#print (''.join(out))
return out

# def decrypt(ch,i):
# out = 0
# tmp_ch = 2 * (i & ch)
# src_ch = ch
# index = i
# while(1):
# pass



encrp = bytearray('34e8h9?<<mkCD>F@DEDCzHxxKRQRNSRS', 'utf-8')
#print(hex(encrp[5]))

flag = ''
index = 0
while(index < len(encrp)):
for i in range(0,0xFF):
encrypted = encrypt(i,index)
#print("ecrypt():",i,index)
if encrypted == encrp[index]:
flag += chr(i)
print(flag)
index += 1
if index == 32:
break

print("scuctf{"+flag+"}")

image-20201128022731544