해당 대회는 대회 당시 웹 문제들만 풀어봐서 대회 종료 후 리버싱 문제들을 다시 풀어봤다.


int sub_411860()

{

  int v0; // edx

  int v1; // ST08_4

  char v3; // [esp+0h] [ebp-698h]

  DWORD flag_pid; // [esp+250h] [ebp-448h]

  HWND hWnd; // [esp+25Ch] [ebp-43Ch]

  int j; // [esp+268h] [ebp-430h]

  CHAR *v7; // [esp+274h] [ebp-424h]

  unsigned int i; // [esp+280h] [ebp-418h]

  BOOL v9; // [esp+28Ch] [ebp-40Ch]

  PROCESSENTRY32 pe; // [esp+298h] [ebp-400h]

  char Dst[280]; // [esp+3C8h] [ebp-2D0h]

  size_t v12; // [esp+4E0h] [ebp-1B8h]

  int current_pid; // [esp+4ECh] [ebp-1ACh]

  int v14; // [esp+4F8h] [ebp-1A0h]

  int v15; // [esp+504h] [ebp-194h]

  DWORD dwProcessId; // [esp+510h] [ebp-188h]

  HANDLE hSnapshot; // [esp+528h] [ebp-170h]

  int v18; // [esp+640h] [ebp-58h]

  int v19; // [esp+644h] [ebp-54h]

  int v20; // [esp+648h] [ebp-50h]

  int v21; // [esp+64Ch] [ebp-4Ch]

  int v22; // [esp+650h] [ebp-48h]

  int v23; // [esp+654h] [ebp-44h]

  int v24; // [esp+658h] [ebp-40h]

  int v25; // [esp+65Ch] [ebp-3Ch]

  int v26; // [esp+660h] [ebp-38h]

  int v27; // [esp+664h] [ebp-34h]

  int v28; // [esp+668h] [ebp-30h]

  int v29; // [esp+66Ch] [ebp-2Ch]

  int v30; // [esp+670h] [ebp-28h]

  int v31; // [esp+674h] [ebp-24h]

  int v32; // [esp+678h] [ebp-20h]

  int v33; // [esp+67Ch] [ebp-1Ch]

  int v34; // [esp+680h] [ebp-18h]

  int v35; // [esp+684h] [ebp-14h]

  int v36; // [esp+688h] [ebp-10h]

  int v37; // [esp+68Ch] [ebp-Ch]

  int v38; // [esp+694h] [ebp-4h]

  int savedregs; // [esp+698h] [ebp+0h]


  sub_411235(&unk_41C017);

  system("title Very_easy_Reversing!");

  ((void (*)(void))sub_41123F)();

  v18 = 31;

  v19 = 41;

  v20 = 66;

  v21 = 15;

  v22 = 58;

  v23 = 50;

  v24 = 40;

  v25 = 29;

  v26 = 23;

  v27 = 49;

  v28 = 19;

  v29 = 21;

  v30 = 71;

  v31 = 87;

  v32 = 65;

  v33 = 69;

  v34 = 71;

  v35 = 11;

  v36 = 31;

  v37 = 68;

  hSnapshot = j_CreateToolhelp32Snapshot(2u, 0);

  GetCurrentProcessId();

  dwProcessId = ((int (*)(void))sub_41123F)();

  GetCurrentThread();

  v15 = ((int (*)(void))sub_41123F)();

  OpenProcess(0x2000000u, 1, dwProcessId);

  v14 = ((int (*)(void))sub_41123F)();

  GetCurrentProcessId();

  current_pid = ((int (*)(void))sub_41123F)();

  j_memset(Dst, 0, 0x104u);

  if ( hSnapshot )

  {

    pe.dwSize = 296;

    v9 = j_Process32First(hSnapshot, &pe);

    while ( v9 )

    {

      v9 = j_Process32Next(hSnapshot, &pe);

      v12 = j_strlen(pe.szExeFile);

      for ( i = 0; i < 0x14; ++i )

        pe.szExeFile[i] ^= *((_BYTE *)&v18 + 4 * i);

      j_memset(Dst, 0, 4u);

      v7 = pe.szExeFile;

      for ( j = 0; j < 20; ++j )

        Dst[j] = v7[j];

      FindWindowA(0, Dst);

      hWnd = (HWND)((int (*)(void))sub_41123F)();

      if ( hWnd )

      {

        GetWindowThreadProcessId(hWnd, &flag_pid);

        ((void (*)(void))sub_41123F)();

        if ( flag_pid == current_pid )

        {

          sub_41104B("Correct\n", v3);

          system("pause");

          ((void (*)(void))sub_41123F)();

          goto LABEL_15;

        }

      }

    }

  }

  system("pause");

  ((void (*)(void))sub_41123F)();

LABEL_15:

  sub_411262(&savedregs, &dword_411B9C, 0, v0);

  return sub_41123F((unsigned int)&savedregs ^ v38, v1);

}


코드를 보면 프로세스 리스트를 가져온 뒤 exe파일들에 대해 간단한 xor연산을 거친다. 이 때 구한 문자열을 통해 가져온 PID 값이 현재 파일의 PID와 같아야 한다. 즉 xor 연산을 통해 구해온 값이 현재 파일명인 Very_easy_Reversing!.exe이면 된다. 


 for ( i = 0; i < 0x14; ++i )

        pe.szExeFile[i] ^= *((_BYTE *)&v18 + 4 * i);


해당 코드에 맞게 복호화를 해보면 플래그가 나온다.


a = "Very_easy_Reversing!"
b = [31,41,66,15,58,50,40,29,23,49,19,21,71,87,65,69,71,11,31,68]
flag = ""
for i in range(0,len(a)):
flag += chr(ord(a[i])^b[i])
print "Flag = " + flag


Flag = IL0veWInnnAp1236.exe




'CTF > Writeup' 카테고리의 다른 글

ROOT CTF 2018 CrackMe  (0) 2019.01.01
ROOT CTF 2018 ROOT_Process_2  (0) 2018.12.30
35C3 CTF 2018 php  (0) 2018.12.30
Codegate 2014 clone technique  (1) 2018.12.29
X-MAS CTF 2018 Web Write up  (0) 2018.12.24
블로그 이미지

JeonYoungSin

메모 기록용 공간

,