[BUUCTF]xor

下载下来发现文件不是exe, 先IDA看一下, 发现不是PE文件

image-20220121202632787

直接分析F5看伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [rsp+2Ch] [rbp-124h]
char __b[264]; // [rsp+40h] [rbp-110h] BYREF

memset(__b, 0, 0x100uLL);
printf("Input your flag:\n");
get_line(__b, 256LL); //将输入的字符串保存到__b数组中
if ( strlen(__b) != 33 ) //输入的字符串必须长33字节(不含尾部'\0')
goto LABEL_7;
for ( i = 1; i < 33; ++i )
__b[i] ^= __b[i - 1]; //输入字符串的每后一位与前一位的异或
if ( !strncmp(__b, global, 0x21uLL) ) //将异或后的结果与global这个字符串相比较
printf("Success");
else
LABEL_7:
printf("Failed");
return 0;
}

这这题需要用到一个知识点, 异或(XOR)两次会还原

1
2
101011 XOR 111111 = 010100  //101011111111异或
010100 XOR 111111 = 101011 //将异或所得结果再次与111111异或即可还原原文

所以只需要把global指向的字符串按照题目的方式再次进行一次异或即可得到原文, 原文应该就是flag

可以在IDA里使用shift+e提取字符数组

image-20220121205312277

解密代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <cstdio>

using namespace std;

int main()
{
unsigned char ciphertext[] =
{
0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11,
0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F,
0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F,
0x47, 0x32, 0x4F, 0x00
};
for (int i = 32; i >= 1; i--)
ciphertext[i] ^= ciphertext[i - 1];
printf("%s", ciphertext);
}
//flag{QianQiuWanDai_YiTongJiangHu}