RE学习笔记1 [GWCTF 2019]xxor

每天一道CTF,可多不可少。
虽然还是处于看的懂却不会编写脚本阶段,但是要保持写题。

IDA加载,主函数

  __int64 v12; // [rsp+48h] [rbp-28h]
  __int64 v13; // [rsp+50h] [rbp-20h]
  __int64 v14; // [rsp+58h] [rbp-18h]
  __int64 v15; // [rsp+60h] [rbp-10h]
  unsigned __int64 v16; // [rsp+68h] [rbp-8h]

  v16 = __readfsqword(0x28u);
  puts("Let us play a game?");
  puts("you have six chances to input");
  puts("Come on!");
  v6 = 0LL;
  v7 = 0LL;
  v8 = 0LL;
  v9 = 0LL;
  v10 = 0LL;
  for ( i = 0; i <= 5; ++i )
  {
    printf("%s", "input: ", (unsigned int)i);
    __isoc99_scanf("%d", (char *)&v6 + 4 * i);
  }
  v11 = 0LL;
  v12 = 0LL;
  v13 = 0LL;
  v14 = 0LL;
  v15 = 0LL;
  for ( j = 0; j <= 4; j += 2 )
  {
    dword_601078 = *((_DWORD *)&v6 + j);
    dword_60107C = *((_DWORD *)&v6 + j + 1);
    sub_400686(&dword_601078, &unk_601060);
    *((_DWORD *)&v11 + j) = dword_601078;
    *((_DWORD *)&v11 + j + 1) = dword_60107C;
  }
  if ( (unsigned int)sub_400770(&v11) != 1 )
  {
    puts("NO NO NO~ ");
    exit(0);
  }
  puts("Congratulation!\n");
  puts("You seccess half\n");
  puts("Do not forget to change input to hex and combine~\n");
  puts("ByeBye");
  return 0LL;
}

先输入六个数,然后在 sub_400686里面进行两两比较。

__int64 __fastcall sub_400686(unsigned int *a1, _DWORD *a2)
{
  __int64 result; // rax
  unsigned int v3; // [rsp+1Ch] [rbp-24h]
  unsigned int v4; // [rsp+20h] [rbp-20h]
  int v5; // [rsp+24h] [rbp-1Ch]
  unsigned int i; // [rsp+28h] [rbp-18h]

  v3 = *a1;
  v4 = a1[1];
  v5 = 0;
  for ( i = 0; i <= 0x3F; ++i )
  {
    v5 += 1166789954;
    v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
    v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
  }
  *a1 = v3;
  result = v4;
  a1[1] = v4;
  return result;
}

两个数在里面抑或比较
然后跟着代码写脚本
由于自己的python学得不太好,就跟着网上大神的思路一起打。

在这里插入图片描述
取得六个输入值后,进入sub_400686函数查看。

__int64 __fastcall sub_400686(unsigned int *a1, _DWORD *a2)
{
  __int64 result; // rax
  unsigned int m; // [rsp+1Ch] [rbp-24h]
  unsigned int n; // [rsp+20h] [rbp-20h]
  int sum; // [rsp+24h] [rbp-1Ch]
  unsigned int i; // [rsp+28h] [rbp-18h]

  m = *a1;                                      // m=temp[0]
                                                // n=temp[1]
  n = a1[1];
  sum = 0;
  for ( i = 0; i <= 63; ++i )
  {
    sum += 0x458BCD42;
    m += (n + sum + 11) ^ ((n << 6) + *a2) ^ ((n >> 9) + a2[1]) ^ 0x20;
    n += (m + sum + 20) ^ ((m << 6) + a2[2]) ^ ((m >> 9) + a2[3]) ^ 0x10;
  }
  *a1 = m;
  result = n;
  a1[1] = n;
  return result;
}

然后开始写脚本

#include <stdio.h>
int main()
{
	unsigned int xorm[6];
	xorm[0] = 3746099070;
	xorm[1] = 550153460;
	xorm[2] = 3774025685;
	xorm[3] = 1548802262;
	xorm[4] = 2652626477;
	xorm[5] = 2230518816;
	int i = 0,j=0,sum;
	unsigned int temp[2] = {0};
	unsigned int data[4] = { 2,2,3,4 };
	for (i = 0; i < 5; i += 2)
	{
		temp[0] = xorm[i];
		temp[1] = xorm[i + 1];

		sum = 0x458BCD42 * 64;
		for (j = 0; j < 64; j++)
		{
			temp[1] -= (temp[0] + sum + 20) ^ ((temp[0] << 6) + 3) ^ ((temp[0] >> 9) + 4) ^ 0x10;
			temp[0] -= (temp[1] + sum + 11) ^ ((temp[1] << 6) + 2) ^ ((temp[1] >> 9) + 2) ^ 0x20;
			sum -= 0x458BCD42;
		}
		xorm[i] = temp[0];
		xorm[i + 1] = temp[1];
	}
	for (i = 0; i < 6; i++)
		printf("%c%c%c", *((char*)&xorm[i]+2), *((char*)&xorm[i] + 1), *(char*)&xorm[i]);
}

由于re新手,脚本还是转载于:

添加链接描述
最后取得flag为flag{re_is_great!}。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值