【TSCTF-J】新生赛debugMe WP

 

 下载附件,放到Exeinfo PE里面查一下

 

 发现是64位,无壳,用IDA64打开,F5读伪代码。

 

 发现buffer就是flag,于是要对上面的代码进行编译运行,输出buffer。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

typedef unsigned int    uint32;
typedef unsigned char   uint8;
typedef unsigned long long ull;
typedef ull             uint64;
#define __int64 long long
#define _BYTE  uint8
#define _QWORD uint64

int i; // [rsp+Ch] [rbp-584h]
int i_0; // [rsp+10h] [rbp-580h]
int *ptr; // [rsp+18h] [rbp-578h]
_BYTE key[72]; // [rsp+30h] [rbp-560h] OVERLAPPED BYREF
char input[256]; // [rsp+80h] [rbp-510h] BYREF
uint8 buffer[1024]; // [rsp+180h] [rbp-410h] BYREF
unsigned __int64 v10; // [rsp+588h] [rbp-8h]
unsigned char reverse_map[] =
{
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
  255, 255, 255,  36, 255, 255, 255,  37,  26,  27, 
   28,  29,  30,  31,  32,  33,  34,  35, 255, 255, 
  255, 255, 255, 255, 255,   0,   1,   2,   3,   4, 
    5,   6,   7,   8,   9,  10,  11,  12,  13,  14, 
   15,  16,  17,  18,  19,  20,  21,  22,  23,  24, 
   25, 255, 255, 255, 255, 255, 255,  38,  39,  40, 
   41,  42,  43,  44,  45,  46,  47,  48,  49,  50, 
   51,  52,  53,  54,  55,  56,  57,  58,  59,  60, 
   61,  62,  63, 255, 255, 255, 255, 255
};

void __cdecl decrypt(int *v, int *k)
{
    int v0; // [rsp+1Ch] [rbp-24h]
      int v1; // [rsp+20h] [rbp-20h]
      int sum; // [rsp+24h] [rbp-1Ch]
      int j; // [rsp+28h] [rbp-18h]

      v0 = *v;
      v1 = v[1];
      sum = -957401312;
      for ( j = 0; j <= 31; ++j )
      {
            v1 -= (v0 + sum) ^ ((v0 >> 5) + k[3]) ^ (16 * v0 + k[2]);
            v0 -= (v1 + sum) ^ ((v1 >> 5) + k[1]) ^ (16 * v1 + *k);
            sum += 1640531527;
      }
  *v = v0;
  v[1] = v1;
}
uint32 __cdecl base64_decode(const uint8 *code, uint32 code_len, uint8 *plain)
{
  uint32 v3; // rax
  uint32 v4; // rax
  uint32 v5; // rax
  uint32 i; // [rsp+28h] [rbp-28h]
  uint32 j; // [rsp+30h] [rbp-20h]
  uint32 k; // [rsp+38h] [rbp-18h]
  uint8 quad[4]; // [rsp+44h] [rbp-Ch]
  j = 0LL;
  for ( i = 0LL; i < code_len; i += 4LL )
  {
    for ( k = 0LL; k <= 3; ++k )
      quad[k] = reverse_map[code[k + i]];
    v3 = j++;
    plain[v3] = (quad[1] >> 4) | (4 * quad[0]);
    if ( quad[2] > 0x3Fu )
      break;
    if ( quad[3] > 0x3Fu )
    {
      v4 = j++;
      plain[v4] = (quad[2] >> 2) | (16 * quad[1]);
      return j;
    }
    plain[j] = (quad[2] >> 2) | (16 * quad[1]);
    v5 = j + 1;
    j += 2LL;
    plain[v5] = quad[3] | (quad[2] << 6);
  }
  return j;
}
int main()
{
    memset(buffer, 0, sizeof(buffer));
    memcpy(key, "flag{fake_flag!}\xB0\xCB\x3E\xC9\x24\x9F+i", 24);
    *(_QWORD *)&key[24] = 0x4C84B46449C15A4ELL;
    *(_QWORD *)&key[32] = 0x7BDFB74A90AED151LL;
    *(_QWORD *)&key[40] = 0x2954405AD89B1055LL;
    *(_QWORD *)&key[48] = 0xFA7ECCD6EBB7FD3ELL;
    *(_QWORD *)&key[56] = 0x84E7B0309D4C973FLL;
    *(_QWORD *)&key[64] = 0xBACEB9973E970C85LL;
    i = 7;
    ptr = (int *)&key[16];
    do
    {
      decrypt(ptr, (int *)key);
      ptr += 2;
      --i;
    }while ( i );
    buffer[(int)base64_decode(&key[16], 0x38uLL, buffer)] = 0;
    for(int i=0; i<40; i++) cout<<buffer[i];
    return 0;
}

需要注意的是很多没见过的数据类型都需要自己重定义,还有里面用到的函数也需要一起copy过来,最后在网上搜到qmemcpy与memcpy相同,进行替换后,就可以正常编译运行了。

 

 得到flag。

posted @ 2021-10-24 20:03  king_kb  阅读(90)  评论(0编辑  收藏  举报