Reverse Engineering
The Windows 32bit binary takes two user inputs. The first input is a number which has between 1 to 5 digits. The second is a key which will give the flag.
Reverse engineering the binary to determine the flag value is very difficult. The quickest way is to examine the binary during execution and patch it so that the flag can be discovered.
Executable code – using Ghidra to decompile the binary.
void FUN_00408040(void)
{
int iVar1;
FILE *_File;
uint uVar2;
undefined extraout_DL;
undefined extraout_DL_00;
undefined extraout_DL_01;
undefined uVar3;
undefined uVar4;
void *in_stack_ffffff88;
int local_74;
char local_6c [100];
uint local_8;
local_8 = DAT_0047b174 ^ (uint)&stack0xfffffffc;
thunk_FUN_004083e0((wchar_t *)s_Input_a_number_between_1_and_5_d_0047b06c);
thunk_FUN_00408430((wchar_t *)&DAT_0047b094);
local_74 = 1;
while (9 < (int)in_stack_ffffff88) {
local_74 = local_74 + 1;
in_stack_ffffff88 = (void *)((int)in_stack_ffffff88 / 10);
}
if (local_74 < 6) {
thunk_FUN_004083e0((wchar_t *)s_Initializing…_0047b0b4);
thunk_FUN_00407ff0(in_stack_ffffff88,local_74);
do {
iVar1 = __fgetchar();
uVar4 = SUB41(in_stack_ffffff88,0);
} while (iVar1 != 10);
thunk_FUN_004083e0((wchar_t *)s_Enter_the_correct_key_to_get_the_0047b0c8);
_File = (FILE *)___acrt_iob_func(0);
_fgets(local_6c,100,_File);
uVar2 = thunk_FUN_00407f60(local_6c); <- user entered key verified
if ((char)uVar2 == ‘\0’) {
thunk_FUN_004083e0((wchar_t *)s_Incorrect_key._Try_again._0047b0f8);
uVar3 = extraout_DL_00;
}
else {
thunk_FUN_004083e0((wchar_t *)s_Correct_input._Printing_flag:_0047b114);
thunk_FUN_00408010();
uVar3 = extraout_DL_01;
}
}
else {
thunk_FUN_004083e0((wchar_t *)s_Number_too_big._Try_again._0047b098);
uVar4 = SUB41(in_stack_ffffff88,0);
uVar3 = extraout_DL;
}
thunk_FUN_004084bf(local_8 ^ (uint)&stack0xfffffffc,uVar3,uVar4);
return;
}
*————————————————————————-
uint __cdecl FUN_00407f60(char *param_1)
{
char *_Str;
size_t sVar1;
size_t sVar2;
uint local_8;
_Str = (char *)thunk_FUN_00407f40();
local_8 = 0;
while( true ) {
sVar1 = _strlen(param_1);
if (sVar1 – 1 <= local_8) {
return CONCAT31((int3)(sVar1 – 1 >> 8),1);
}
sVar1 = _strlen(param_1);
sVar2 = _strlen(_Str);
if (sVar1 – 1 != sVar2) break;
if (param_1[local_8] != _Str[local_8]) {
return (uint)(_Str + local_8) & 0xffffff00;
}
local_8 = local_8 + 1;
}
return sVar2 & 0xffffff00;
}
Binary Debugging – using OllyDbg to analyse the execution of the program and solve the challenge.
Method 1.
Open executable in OllyDbg and run the binary until the first input.
In the main windows, go to Search for -> All referenced text strings.
Find the line and “Enter the correct key..” double click to go to the code.
Double click line 75 0F JNZ SHORT to change the command.
Change command from JNZ to JMP.
Click Assemble to update main program code.
Continue program with dummy values. The flag will be printed.
Method 2.
Set breakpoint and observe program execution to find the key required. This can be used in the program to get the flag.
Search for Text Key is and click on code.
Set breakpoint in main program.
Continue program until the breakpoint is reached and find the key in the OllyDbg window.
Run the binary and enter the key.