🕹️ Door Kicker

    귀여운 여우가 누군가의 작은 집문을 발로 차고 있네요!
    아무래도 집 주인이 화가나서 게임 파일을 마구 수정한것 같아요!
    여우가 편하게 문을 찰 수 있도록 도와주세요!
    그리고 여우가 말하길 특정 키를 가지고 문을 차면 신기한 일이 일어난다고 하네요!

    Files

    Unity로 제작된 윈도우 실행 파일인 Door-Kicker

    분석

    Assembly-CSharp.dll

    Door Kicker\Door-Kicker_Data\Managed\Assembly-CSharp.dll 파일을
    JetBrains dotPeek 프로그램으로 열어보면 확인할 수 있다.

    GameManager 클래스를 살펴보면 아래와 같이 작동한다.

    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Runtime.InteropServices;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    namespace TeamH4C.JaeyunJung
    {
      public class GameManager : MonoBehaviour
      {
        private const string FLAG_FILE_NAME = "flag";
    
        [DllImport("CheckFlag.dll")]
        private static extern bool CheckFlag(IntPtr flag);
    
        private void Start()
        {
          PlayerController.kickAction += new Action(this.OnKickTheDoor);
          if (!Debugger.IsAttached)
            return;
          Application.Quit();
        }
    
        private void OnKickTheDoor()
        {
          if (!File.Exists(Application.streamingAssetsPath + "/flag") || !GameManager.CheckFlag(Marshal.StringToHGlobalAnsi(File.ReadAllText(Application.streamingAssetsPath + "/flag"))))
            return;
          SceneManager.LoadScene("Success");
        }
      }
    }

    CheckFlag.dll 파일을 불러와서 CheckFlag 함수를 호출하는 코드를 볼 수 있다.

    따라서 우리는 Flag를 얻기 위해 CheckFlag.dll 파일을 분석해야 한다.

    CheckFlag.dll 파일은 Door Kicker\Door-Kicker_Data\Plugins\x86_64 위치에 있었다.

    CheckFlag.dll

    _BOOL8 __fastcall CheckFlag_0(const char *a1)
    {
      char *v1; // rdi
      __int64 i; // rcx
      char v4; // [rsp+20h] [rbp+0h] BYREF
      char Destination[276]; // [rsp+30h] [rbp+10h] BYREF
      int j; // [rsp+144h] [rbp+124h]
    
      v1 = &v4;
      for ( i = 82i64; i; --i )
      {
        *(_DWORD *)v1 = 0xCCCCCCCC;
        v1 += 4;
      }
      j___CheckForDebuggerJustMyCode((__int64)&unk_18003007A);
      j_strcpy(Destination, a1);
      for ( j = 0; (unsigned __int64)j < 26; ++j )
        Destination[j] ^= Destination[((_BYTE)j + 1) & 25];
      return strncmp(Destination, aDR, 26ui64) == 0;
    }

    위와 같이 간단히 XOR 연산을 해서 strncmp 함수로 문자열을 비교하고 있었다.

    풀이

    XOR 연산은 (A ^ B) ^ B = A이므로
    역순으로 문자를 하나씩 풀어서 FLAG를 얻을 수 있다.

    def decrypt_flag(data):
        result=""
    
        data = list(data)
        for i in range(len(data)-1, -1, -1):
            data[i] = data[i] ^ data[(i + 1) & 25]
    
        for i in range(len(data)):
            result = result + chr(data[i])
    
        return result
    
    enc_flag = b'\x2B\x44\x1B\x52\x2B\x5E\x1B\x05\x01\x6E\x19\x5E\x0F\x63\x01\x01\x2B\x74\x20\x4E\x15\x46\x3C\x77\x7C\x43'
    flag = decrypt_flag(enc_flag)
    print(flag)

    FLAG

    Do_you_know_about_TeamH4C?

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다