[2019红帽杯]easyRE
新手一枚,如有错误(不足)请指正,谢谢!!
题目链接:BUUCTF-re-[2019红帽杯]childRE
题目下载:点击下载

IDA64位载入,shift+F12查看字符串,然后双击过去

"x"键交叉引用,切换到关键代码

F5反汇编显示
截取的部分代码

  int i; // [rsp+Ch] [rbp-114h]
  char str0[36]; // [rsp+60h] [rbp-C0h]
  char input1[32]; // [rsp+90h] [rbp-90h]
  int v16; // [rsp+B0h] [rbp-70h]
  char v17; // [rsp+B4h] [rbp-6Ch]
  char input2; // [rsp+C0h] [rbp-60h]
  char v19; // [rsp+E7h] [rbp-39h]
  char v20; // [rsp+100h] [rbp-20h]
  unsigned __int64 v21; // [rsp+108h] [rbp-18h]

  v21 = __readfsqword(0x28u);
  str0[0] = 73;
  str0[1] = 111;
  str0[2] = 100;
  str0[3] = 108;
  str0[4] = 62;
  str0[5] = 81;
  str0[6] = 110;
  str0[7] = 98;
  str0[8] = 40;
  str0[9] = 111;
  str0[10] = 99;
  str0[11] = 121;
  str0[12] = 127;
  str0[13] = 121;
  str0[14] = 46;
  str0[15] = 105;
  str0[16] = 127;
  str0[17] = 100;
  str0[18] = 96;
  str0[19] = 51;
  str0[20] = 119;
  str0[21] = 125;
  str0[22] = 119;
  str0[23] = 101;
  str0[24] = 107;
  str0[25] = 57;
  str0[26] = 123;
  str0[27] = 105;
  str0[28] = 121;
  str0[29] = 61;
  str0[30] = 126;
  str0[31] = 121;
  str0[32] = 76;
  str0[33] = 64;
  str0[34] = 69;
  str0[35] = 67;
  memset(input1, 0, sizeof(input1));
  v16 = 0;
  v17 = 0;
  v0 = input1;
  sub_4406E0(0LL, input1, 37LL);
  v17 = 0;
  v1 = input1;
  if ( sub_424BA0(input1) == 36 )
  {
    for ( i = 0; ; ++i )
    {
      v1 = input1;
      if ( i >= (unsigned __int64)sub_424BA0(input1) )
        break;
      if ( (unsigned __int8)(input1[i] ^ i) != str0[i] )
      {
        result = 4294967294LL;
        goto LABEL_13;
      }
    }
    sub_410CC0("continue!");
    memset(&input2, 0, 0x40uLL);
    v20 = 0;
    v0 = &input2;
    sub_4406E0(0LL, &input2, 64LL);
    v19 = 0;
    v1 = &input2;
    if ( sub_424BA0(&input2) == 39 )
    {
      v3 = sub_400E44(&input2);
      v4 = sub_400E44(v3);
      v5 = sub_400E44(v4);
      v6 = sub_400E44(v5);
      v7 = sub_400E44(v6);
      v8 = sub_400E44(v7);
      v9 = sub_400E44(v8);
      v10 = sub_400E44(v9);
      v11 = sub_400E44(v10);
      v12 = sub_400E44(v11);
      v0 = off_6CC090;
      v1 = (char *)v12;
      if ( !(unsigned int)sub_400360(v12, off_6CC090) )
      {
        sub_410CC0("You found me!!!");
        v1 = "bye bye~";
        sub_410CC0("bye bye~");
      }

先分析input1有关的代码,将用户输入与i异或后与在栈上存的数据进行比对
写脚本
然后知道flag前四位是flag
再分析与input2有关的代码

反复调用了sub_400E44()函数,查看后发现是base64加密,也就是进行了十次base64加密
可参考Base16,Base32,Base64编码详细学习

然后将编码后的字符串与off_6CC090处存放的字符串进行比对

编写脚本

查看网址……

参考wp

找到这段不随机的数据

发现其来自于sub_400D35函数
对sub_400D35函数进行交叉引用

发现来自.fini段的调用

而.fini段的解释是

此节区包含了可执行的指令,是进程终止代码的一部分。程序正常退出时,系统将安排执行这里的代码。

找到正确的关键代码

关键代码
v4^byte_6CC0A0[0] == ‘f’
v7 = v4
HIBYTE(v7)=HIBYTE(v4)=(*((_BYTE*)&(V4)+1))
也就是v4的下一位
byte_6CC0A3 也就是byte_6CC0A0[3]
因为第一次开始解出来flag开头是flag
可以推测就是判断v4的四位是不是与byte_6CC0A0前四位异或后等于’flag’
然后下面的异或应该是出flag的
写脚本

得出flag为flag{Act1ve_Defen5e_Test}