2018/12/07-SCUCTF-re5

链接:https://pan.baidu.com/s/14evvLd4jTLHp2Zg7_ugr0g
提取码:auki

根据题目意思,程序是一个加密器,文件中的txt中是截获的密文,txt中的内容是“T2aNoifxUjIgKYMxKCsHKxAUZsDDGStqwV8Gh3W=”,可以猜到和base64加密有关。

可以发现每运行一次程序就会生成一个txt,可以猜到输入和生成的txt有关。

程序使用C++写的,静态分析起来很头痛,大部分信息都是用OD调试获得和确定的。

首先是有两个输入,一个是输入name,name的长度不小于8,一个是information,长度不小于0。

sub_401640函数来处理两个输入,但是函数里面反编译地很乱不知道在干什么。

但经过调试我们发现函数的作用将输入的input复制到内存的另一个地方,然后函数的第一个参数应该是一个结构体,然后函数处理完成后,查看第一个参数的地址+4的word值,就是字符串复制到内存另一个地方的起始地址,+8的word值是结束地址。

以v26(对应input2,即information)为例,v26在内存中的地址是0x19FEEC,然后地址+4的word值就是0x02B00E30,+8的word值是0x02B00E36,然后我们查看0x2B00E30可以发现就是输入的input2。

 继续往下看。

sub_401242函数是一个被改的rc4加密,根据里面中的函数多次出现256可以猜到。

关于rc4加密可以看一下这篇文章https://www.52pojie.cn/thread-800115-1-1.html。

并且动态调试时候发现,只加密了input2即information,进去分析一下。

主要是这三个函数,其中函数sub_401432是将字符串“'rm36ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678'”中的前四位即“rm36”与0xce进行异或运算,然后异或后的四个值作为fake_rc4的密钥。

fake_rc4分为sub_401314和sub_13A0,一个是根据密钥进行初始化,一个是对data进行加密。

fake_rc4的初始化函数和加密函数都和rc4不一样。

fake_rc4初始化函数中,这三处异或明显和rc4不同,从而导致生成的生成的SBox不一样了。

fake_rc4加密函数中,同样也是三处异或明显不同。

那么我们如何写脚本时如何处理这个fake_rc4加密呢,我们发现密钥是固定的,也就是说fake_rc4初始化函数得到的SBox是固定的,而加密的数据只有在最后一处异或时参与运算,并且因为SBox是固定的,所以加密数据异或的值和顺序也都是固定。

也就是说我们完全可以动态调试,把异或的值都记录下来。

在此处设断点,然后根据后面base64解密得到的值的长度可知记录需要29个,我们输入的information的长度大于29然后调试即可记录异或的值,可以得到异或的29个值为[0xc8,0x23,0x0f,0x36,0x46,0xa9,0xda,0x76,0x4d,0x20,0x35,0x61,0x0f,0x20,0x3d,0x0d,0xb9,0x46,0xbe,0x62,0xf4,0x57,0x3a,0x95,0xdf,0xc1,0x6b,0x60,0x06]。

继续向下分析。

sub_4017CE作用即是对fake_rc4加密输入information得到的数据进行base64加密,但是需要主要的base64的编码表是经过变化的。

进去分析一下。

函数sub_4018D1的功能即是变化编码表,用OD动态调试可以得到变化后的编码表为”AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789/+“,下面的就是base64加密的部分了。

再回到main函数里继续往下分析。

函数sub_40147C的作用是生成txt文件名,和flag没有什么关系,就不仔细分析了。

然后下面的操作就是生成txt文件了,内容就是密文即是先fake_rc4再base64得到的,文件名即base32得到的。

现在程序逻辑已经清楚了,flag经过这个加密器程序得到txt文件即是题目给的,其中的密文就是flag加密的密文。

然后我们写出脚本即可得到flag,脚本思路就是首先对题目txt文件中的密文进行base64解密,注意编码表是变化了的,然后在异或我们动态调试得到的值即可。

from string import maketrans

base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
diy_base = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789/+'
t = maketrans(base, diy_base)
t2 = maketrans(diy_base, base)

def cus_base64_enc(x):
    return x.encode('base64').translate(t)
def cus_base64_dec(x):
    return x.translate(t2).decode('base64')

str = "T2aNoifxUjIgKYMxKCsHKxAUZsDDGStqwV8Gh3W="
str1 = cus_base64_dec(str)

flag = []
xor_data = [0xc8,0x23,0x0f,0x36,0x46,0xa9,0xda,0x76,0x4d,0x20,0x35,0x61,0x0f,0x20,0x3d,0x0d,0xb9,0x46,0xbe,0x62,0xf4,0x57,0x3a,0x95,0xdf,0xc1,0x6b,0x60,0x06]
for i in range(len(str1)):
    a = ord(str1[i]) ^ xor_data[i]
    flag.append(a)
print ''.join(map(chr,flag))

运行即可得到flag。

猜你喜欢

转载自www.cnblogs.com/Fingerprint/p/10086372.html