BUUCTF xor 解题思路

1、先用die查看是多少位的文件

根据模式那里显示是64位文件

2、用x64位IDE打开文件进入汇编界面找到主函数

选中后,按F5反汇编为c语言代码

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);
  if ( strlen(__b) != 33 )
    goto LABEL_7;
  for ( i = 1; i < 33; ++i )
    __b[i] ^= __b[i - 1];
  if ( !strncmp(__b, global, 0x21uLL) )
    printf("Success");
  else
LABEL_7:
    printf("Failed");
  return 0;
}

这个是使用了异或的运算,将数据就是所谓的flag进行了加密

什么是异或? 

a⊕b = (¬a ∧ b) ∨ (a ∧¬b)  (可以不用看这个,数学表示式)

如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。(important)

3、前面的不影响做题,重要的是for循环这边,是在这个地方对数据进行了异或加密

for ( i = 1; i < 33; ++i )
    __b[i] ^= __b[i - 1];

那要得到原来的数据就要将他异或回去,看大多数人用python写脚本确实简单,在这提供一下与众不同的代码,用c写。

4、

接下来将这些数据提取出来,转为16进制。在IDE内选中这两行然后shift+E提取数据

转化为16进制之后结果如下

 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

有了这些,让我们进行脚本的编写,来让原来的数据恢复

#include<stdio.h>
//如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

/*	
  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
 */
int main()
{
	int arr[33] = { 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 };//定义数组存储数据
	char flag[33] = { 0 };//定义存储flag数组存储结果
	for (int i = 1; i < 33; ++i)//进行二次异或运算,将一次异或运算结果转回未异或时的数据
		flag[i] = arr[i] ^ arr[i - 1];//将异或数据存储至flag数组中
	for (int i = 0; i < 33; i++)
	{
		printf("%c", flag[i]);//打印结果
	}
}

自此运行程序可以得到flag:flag{QianQiuWanDai_YiTongJiangHu} 提交即可

在此程序运行出结果后是这样的:不用担心是不是程序写错了,是在原来的汇编代码里已经给出了f,所以在提取的时候无法将f提取出来,结果是没错的,提交时加上f即可。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值