re学习笔记(30)HGAME2020-re-Level-Week1-bitwise_operation2

HGAME2020-re-Level-Week1-bitwise_operation2
新手一枚,如有错误(不足)请指正,谢谢!!

个人博客:点击进入
题目链接:HGAME2020-re-Level-Week1-bitwise_operation2
题目下载:点击下载

题目描述

还记得第三次C语言培训的作业“位运算”吗?这是2.0
学习资料:http://q42u2raim.bkt.clouddn.com/bitwise-hint1-xor.png
题目地址 http://q42u2raim.bkt.clouddn.com/bitwise_operation2_9d9dc26c1359ec66

题解

分析题目

void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
  signed int i; // [rsp+4h] [rbp-6Ch]
  signed int j; // [rsp+8h] [rbp-68h]
  signed int k; // [rsp+Ch] [rbp-64h]
  char v6[8]; // [rsp+10h] [rbp-60h]
  __int64 data_1; // [rsp+20h] [rbp-50h]
  char v8; // [rsp+28h] [rbp-48h]
  __int64 data_2; // [rsp+30h] [rbp-40h]
  char v10; // [rsp+38h] [rbp-38h]
  char user_input[40]; // [rsp+40h] [rbp-30h]
  unsigned __int64 v12; // [rsp+68h] [rbp-8h]

  v12 = __readfsqword(0x28u);
  sub_4007E6();
  v6[0] = 76;
  v6[1] = 60;
  v6[2] = -42;
  v6[3] = 54;
  v6[4] = 80;
  v6[5] = -120;
  v6[6] = 32;
  v6[7] = -52;
  __isoc99_scanf("%39s", user_input);
  if ( strlen(user_input) == 39
    && user_input[0] == 'h'
    && user_input[1] == 'g'
    && user_input[2] == 'a'
    && user_input[3] == 'm'
    && user_input[4] == 'e'
    && user_input[5] == '{'
    && user_input[38] == '}' )
  {
    data_1 = 0LL;
    v8 = 0;
    data_2 = 0LL;
    v10 = 0;
    sub_400616(&data_1, &user_input[6]);       // 加密下标6~21
    sub_400616(&data_2, &user_input[22]);      // 加密下标22~38
    for ( i = 0; i <= 7; ++i )                  // 进行运算
    {
      *(&data_1 + i) = ((*(&data_1 + i) & 224) >> 5) | 8 * *(&data_1 + i);
      *(&data_1 + i) = *(&data_1 + i) & 0x55 ^ ((*(&data_2 + 7 - i) & 0xAA) >> 1) | *(&data_1 + i) & 0xAA;
      *(&data_2 + 7 - i) = 2 * (*(&data_1 + i) & 0x55) ^ *(&data_2 + 7 - i) & 0xAA | *(&data_2 + 7 - i) & 0x55;
      *(&data_1 + i) = *(&data_1 + i) & 0x55 ^ ((*(&data_2 + 7 - i) & 0xAA) >> 1) | *(&data_1 + i) & 0xAA;
    }
    for ( j = 0; j <= 7; ++j )
    {
      *(&data_1 + j) ^= v6[j];                  // 异或运算
      if ( *(&data_1 + j) != byte_602050[j] )   // 进行比较
      {
        puts("sry, wrong flag");
        exit(0);
      }
    }
    for ( k = 0; k <= 7; ++k )
    {
      *(&data_2 + k) ^= *(&data_1 + k) ^ v6[k]; // 异或运算
      if ( *(&data_2 + k) != byte_602060[k] )   // 进行比较
      {
        puts("Just one last step");
        exit(0);
      }
    }
    puts("Congratulations! You are already familiar with bitwise operation.");
    puts("Flag is your input.");
    exit(0);
  }
  puts("Illegal input!");
  exit(0);
}

大体流程为,用户输入39个字符。
然后验证一下长度,前六个字符是否等于"hgame{",最后一个字符是否等于"}"
然后sub_400616每次将16个字符加密成8个字符。
然后进行了一堆位运算
之后进行了两个异或然后进行比较

exp

#include 
int main()
{
	int i;
	char flag[40] = { 'h','g','a','m','e','{' ,0,0 };
	flag[38] = '}';
	unsigned char data0[] = { 76,60,-42,54,80,-120,32,-52 };
	int  j, k;
	char data1[9] = "e4sy_Re_";
	char data2[9] = "Easylif3";
	unsigned char data_1[9] = { 0 }, data_2[9] = {0};
	unsigned char input1[9] = { 0 }, input2[9] = {0};
	for (i = 0; i < 8; i++)
		data_2[i] = data2[i] ^ data0[i] ^ data1[i];
	for (i = 0; i < 8; i++)
		data_1[i] = data1[i] ^ data0[i];
	for (i = 0; i < 8; i++)//正向爆破
	{
		for (j = 0; j < 256; j++)
		{
			for (k = 0; k < 256; k++)
			{
				int a1 = j, a2 = k;
				a1 = ((a1 & 0xE0) >> 5) | 8 * a1;
				a1 = a1 & 0x55 ^ ((a2 & 0xAA) >> 1) | a1 & 0xAA;
				a2 = 2 * (a1 & 0x55) ^ a2 & 0xAA | a2 & 0x55;
				a1 = a1 & 0x55 ^ ((a2 & 0xAA) >> 1) | a1 & 0xAA;
				if (a1 == data_1[i] && a2 == data_2[7 - i])
				{
					input1[i] = j;
					input2[7 - i] = k;
				}
			}
		}
	}
	for (i = 0; i < 8; i++)//正向爆破
	{
		for (j = 0; j < 16; j++)
		{
			for (k = 0; k < 16; k++)
			{
				if (input1[i] == 16 * j + k)
				{
					if (j > 9)
						flag[6 + 2 * i] = j + 87;
					else
						flag[6 + 2 * i] = j + 48;
					if (k > 9)
						flag[7 + 2 * i] = k + 87;
					else
						flag[7 + 2 * i] = k + 48;
				}
				if (input2[i] == 16 * j + k)
				{
					if (j > 9)
						flag[22 + 2 * i] = j + 87;
					else
						flag[22 + 2 * i] = j + 48;
					if (k > 9)
						flag[23 + 2 * i] = k + 87;
					else
						flag[23 + 2 * i] = k + 48;
				}
			}
		}
	}
	puts(flag);
	return 0;
}

运行得到flag

hgame{0f233e63637982d266cbf41ecb1b0102}

你可能感兴趣的:(ctf小白成长ing,#,reverse)