$ ghidrarun
Ghidra를 이용하여 바이너리를 디컴파일한다.
undefined8 main(void)
{
int iVar1;
char *pcVar2;
long in_FS_OFFSET;
uint i;
char local_b8 [32];
char local_98 [136];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
local_b8[0] = '\0';
local_b8[1] = '\0';
local_b8[2] = '\0';
local_b8[3] = '\0';
local_b8[4] = '\0';
local_b8[5] = '\0';
local_b8[6] = '\0';
local_b8[7] = '\0';
local_b8[8] = '\0';
local_b8[9] = '\0';
local_b8[10] = '\0';
local_b8[0xb] = '\0';
local_b8[0xc] = '\0';
local_b8[0xd] = '\0';
local_b8[0xe] = '\0';
local_b8[0xf] = '\0';
local_b8[0x10] = '\0';
local_b8[0x11] = '\0';
local_b8[0x12] = '\0';
local_b8[0x13] = '\0';
local_b8[0x14] = '\0';
local_b8[0x15] = '\0';
local_b8[0x16] = '\0';
local_b8[0x17] = '\0';
local_b8[0x18] = '\0';
local_b8[0x19] = '\0';
puts("Welcome to the \x1b[1;3mSPOOKIEST\x1b[0m party of the year.");
printf("Before we let you in, you\'ll need to give us the password: ");
fgets(local_98,0x80,stdin);
pcVar2 = strchr(local_98,10);
if (pcVar2 != (char *)0x0) {
*pcVar2 = '\0';
}
iVar1 = strcmp(local_98,"s3cr3t_p455_f0r_gh05t5_4nd_gh0ul5");
if (iVar1 == 0) {
puts("Welcome inside!");
for (i = 0; i < 26; i = i + 1) {
local_b8[(int)i] = (char)*(undefined4 *)(parts + (long)(int)i * 4);
}
puts(local_b8);
}
else {
puts("You\'re not a real ghost; clear off!");
}
if (local_10 != *(long *)(in_FS_OFFSET + 40)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
일단 fgets로 받는 입력 변수 local_98이 "s3cr3t_p455_f0r_gh05t5_4nd_gh0ul5" 문자열과 동일해야 함. 아니면 종료된다.
그럼 문자 연산을 통해 26 길이의 어떤 문자열을 출력해준다.
ghidra의 디컴파일 성능이 좋지 않아서 다시 ida를 이용하여 확인하였다.
int __fastcall main(int argc, const char **argv, const char **envp)
{
unsigned int i; // [rsp+4h] [rbp-BCh]
char *v5; // [rsp+8h] [rbp-B8h]
char v6[8]; // [rsp+10h] [rbp-B0h] BYREF
char v7[10]; // [rsp+18h] [rbp-A8h] BYREF
__int64 v8; // [rsp+22h] [rbp-9Eh]
char s[136]; // [rsp+30h] [rbp-90h] BYREF
unsigned __int64 v10; // [rsp+B8h] [rbp-8h]
v10 = __readfsqword(0x28u);
*(_QWORD *)v6 = 0LL;
memset(v7, 0, sizeof(v7));
v8 = 0LL;
puts("Welcome to the \x1B[1;3mSPOOKIEST\x1B[0m party of the year.");
printf("Before we let you in, you'll need to give us the password: ");
fgets(s, 128, _bss_start);
v5 = strchr(s, 10);
if ( v5 )
*v5 = 0;
if ( !strcmp(s, "s3cr3t_p455_f0r_gh05t5_4nd_gh0ul5") )
{
puts("Welcome inside!");
for ( i = 0; i <= 25; ++i )
v6[i] = parts[i];
puts(v6);
}
else
{
puts("You're not a real ghost; clear off!");
}
return 0;
}
ida의 경우 기존 C 문법과 상당히 유사하게 복원해준다.

parts가 뭔가 했는데 전역변수였다.
정확하게 26개로 확인된다.
그럼 이 0x48, 0x54 ...를 이어붙여서 chr로 출력해보면 플래그이지 않을까?
#!/usr/bin/pyton3
hint=[0x48, 0x54, 0x42, 0x7B, 0x75, 0x6E, 0x30, 0x62, 0x66, 0x75, 0x35, 0x63, 0x34, 0x74, 0x33, 0x64, 0x5F, 0x35, 0x74, 0x72, 0x31, 0x6E, 0x67, 0x35, 0x7D]
for h in hint:
print(chr(h),end='')
위와 같이 익스플로잇 코드를 작성하였다.

예상대로 플래그가 출력된 것을 확인할 수 있다.

| [Hack The Box] Pwnable - You know 0xDiablos (0) | 2022.01.03 |
|---|---|
| [Hack The Box] Machine - Cap (0) | 2021.10.02 |
| [Hack The Box] Web - Templated (0) | 2021.09.11 |
| [Hack The Box] Mobile - Cat (0) | 2021.09.11 |