题解BUUCTF xxor

分析

首先用exe查壳,发现它是64位,于是用IDA打开看看,按F5去看反汇编代码

image-20220406164420387

发现它要输入6次,然后看到下面的for循环,这个上面是把v6的东西都放在dword_601078里头,然后进行sub_400686,于是我们点进去,看看这个函数要干嘛。

image-20220406164610798

然后可以发现这是个魔改的tea加密,然后返回,看最外面怎样得到flag

image-20220406164704117

说明要得到flag一定要使这个函数正确,才可以得到flag,那么我们点进去看这个函数在干嘛

image-20220406164743451

发现他这里刚好给出了我们6个a数组的值,与上面的tea加密的函数里头的v3和v4需要的值相对应,于是就能够知道这个会是一个明文

那么现在就需要找到密匙就能解出来了

image-20220406164826272

在前面可以看到这个a2于是我们点进去,看看它是个什么东西

image-20220406164919949

于是我们很容易得到密匙是2 2 3 4

那么就可以写脚本了

#include <iostream>
#pragma warning(disable:4996)
using namespace std;
int main()
{
long long a[6] = { 3746099070, 550153460, 3774025685, 1548802262, 2652626477, 2230518816 };
unsigned int a2[4] = { 2,2,3,4 };
unsigned int v3, v4;
int v5;
for (int j = 0; j <= 4; j += 2) {
v3 = a[j];
v4 = a[j + 1];
v5 = 1166789954*0x40;
for (int i = 0; i <= 63; ++i) {
v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
v5 -= 1166789954;
}
a[j] = v3;
a[j + 1] = v4;
}
for (int i = 0; i < 6; ++i)
{
cout << *((char*)&a[i]+2) << *((char*)&a[i] +1) << * ((char*)&a[i]);
}
system("PAUSE");
return 0;
}

一开始我是用C去输出的,发现会出现乱码,于是去看看别人写的脚本,发现这里涉及到了大小端的输出,这里使用的小端序输出,因为之前的是方便于人去看的大端序输出,所以输出的时候需要反过来,因为这里是64位所以需要输出三次,如果这里是32位就是+1 和a[i]本身。

最后得到flag

flag{re_is_great!}