BUUCTF-RE-[2019红帽杯]easyRE

这道题很难,但是并不难在他的解题要用到的方法和技巧上,而是难在它的题目设计。做的过程中真的有一种闯关的感觉,非常有趣
首先我们通过对字符的定位我们可以来到sub_4009C6函数

__int64 sub_4009C6()
{
  __int64 result; // rax
  int i; // [rsp+Ch] [rbp-114h]
  __int64 v2; // [rsp+10h] [rbp-110h]
  __int64 v3; // [rsp+18h] [rbp-108h]
  __int64 v4; // [rsp+20h] [rbp-100h]
  __int64 v5; // [rsp+28h] [rbp-F8h]
  __int64 v6; // [rsp+30h] [rbp-F0h]
  __int64 v7; // [rsp+38h] [rbp-E8h]
  __int64 v8; // [rsp+40h] [rbp-E0h]
  __int64 v9; // [rsp+48h] [rbp-D8h]
  __int64 v10; // [rsp+50h] [rbp-D0h]
  __int64 v11; // [rsp+58h] [rbp-C8h]
  char v12[32]; // [rsp+60h] [rbp-C0h] BYREF
  char v13[32]; // [rsp+90h] [rbp-90h] BYREF
  int v14; // [rsp+B0h] [rbp-70h]
  char v15; // [rsp+B4h] [rbp-6Ch]
  char v16[72]; // [rsp+C0h] [rbp-60h] BYREF
  unsigned __int64 v17; // [rsp+108h] [rbp-18h]

  v17 = __readfsqword(0x28u);
  qmemcpy(v12, "Iodl>Qnb(ocy", 12);
  v12[12] = 127;
  qmemcpy(&v12[13], "y.i", 3);
  v12[16] = 127;
  qmemcpy(&v12[17], "d`3w}wek9{iy=~yL@EC", 19);
  memset(v13, 0, sizeof(v13));
  v14 = 0;
  v15 = 0;
  sub_4406E0(0LL, v13, 37LL);
  v15 = 0;
  if ( len_0(v13) == 36 )
  {
    for ( i = 0; i < (unsigned __int64)len_0(v13); ++i )
    {
      if ( (unsigned __int8)(v13[i] ^ i) != v12[i] )
      {
        result = 4294967294LL;
        goto LABEL_13;
      }
    }
    printf("continue!");
    memset(v16, 0, 65);
    sub_4406E0(0LL, v16, 64LL);
    v16[39] = 0;
    if ( len_0(v16) == 39 )
    {
      v2 = sub_400E44((__int64)v16);
      v3 = sub_400E44(v2);
      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);
      if ( !(unsigned int)sub_400360(v11, (__int64)off_6CC090) )
      {
        printf("You found me!!!");
        printf("bye bye~");
      }
      result = 0LL;
    }
    else
    {
      result = 4294967293LL;
    }
  }
  else
  {
    result = 0xFFFFFFFFLL;
  }
LABEL_13:
  if ( __readfsqword(0x28u) != v17 )
    sub_444020();
  return result;
}

我们看到"you found me!!!!"下意识的以为我们的flag就在旁边我们往上看看到一个Base加密,下意识的去解开它,结果得到一个网站

打开一看,发现是一篇关于出题的帖子,仔细一看,废了,被骗了

也就是说这个思路有问题,我们继续观察程序,发现上面有一段异或加密,我们尝试解密一下

if ( (unsigned __int8)(v13[i] ^ i) != v12[i] )

我们已知v12可以尝试解密v13

cipher = "Iodl>Qnb(ocy\0y.i\0d`3w}wek9{iy=~yL@EC"
flag = ""
for i in range(len(cipher)):
    flag += chr(ord(cipher[i])^i)
print(flag)


感觉还是不行啊,但是好歹拿到了一个提示密文的前四位是flag,到这里我们就不知道怎么办了,看看别人的帖子,提示我们要看看其他的函数有没有什么线索
我们注意到一个函数里面的信息:

unsigned __int64 sub_400D35()
{
  unsigned __int64 result; // rax
  unsigned int v1; // [rsp+Ch] [rbp-24h]
  int i; // [rsp+10h] [rbp-20h]
  int j; // [rsp+14h] [rbp-1Ch]
  unsigned int v4; // [rsp+24h] [rbp-Ch]
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  v1 = sub_43FD20(0LL) - qword_6CEE38;
  for ( i = 0; i <= 1233; ++i )
  {
    sub_40F790(v1);
    sub_40FE60();
    sub_40FE60();
    v1 = sub_40FE60() ^ 0x98765432;
  }
  v4 = v1;
  if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 'f' && (HIBYTE(v4) ^ (unsigned __int8)byte_6CC0A3) == 'g' )
  {
    for ( j = 0; j <= 24; ++j )
      sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));
  }
  result = __readfsqword(0x28u) ^ v5;
  if ( result )
    sub_444020();
  return result;
}

前面的v1是生成的key,很明显加密是利用key的前四位进行加密。而密文就是byte_6CC0A0,其长度刚好是25位,由此我们可以写出我们的加密脚本:

cipher = [0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32, 0x45, 0x5B]
key = [0x40^ord('f'),0x35^ord('l'),0x20^ord('a'),0x56^ord('g')]
flag = ""
for i in range(len(cipher)):
    flag += chr(cipher[i]^(key[i%4]))
print(flag)

这里注意因为我们原来的前四位"flag"是key[4]和密文异或得到的,所以我们需要重新异或一遍得到key
综上解出本体

posted @ 2025-02-24 13:35  Ylin07  阅读(55)  评论(0)    收藏  举报