🕹️ 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?