Dùng DIE, ta biết được đây là một file PE32. Decompile bằng IDA32, ta có được hàm main()
như sau
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int i; // esi
int j; // edi
char *v5; // esi
int v6; // ecx
__int128 v8; // [esp+0h] [ebp-28h] BYREF
int v9; // [esp+10h] [ebp-18h]
int v10; // [esp+14h] [ebp-14h]
__int16 v11; // [esp+18h] [ebp-10h]
char input[8]; // [esp+1Ch] [ebp-Ch] BYREF
v8 = *(_OWORD *)&byte_83B6E0;
v9 = 0x467B6E60;
v10 = 0x72686661;
v11 = 0x457;
sub_821020((int)"Guest your flag. The flag will be of the form flag{[a-zA-Z0-9]+}\\n");
sub_821020((int)"Enter your key:");
for ( i = 0; i < 5; ++i )
sub_821050("%hhd", &input[i]);
for ( j = 0; j < 26; j += 2 )
{
v5 = (char *)&v8 + j;
*v5 ^= input[j % 5u];
v6 = j;
v5[1] ^= input[v6 - 5 * ((unsigned int)&v5[1 - (_DWORD)&v8] / 5) + 1];
}
sub_821020((int)"flag is : %s\\n", (const char *)&v8);
return 0;
}
Chương trình yêu cầu chúng ta nhập key 5 lần. Với format string %hhd
, chúng ta sẽ nhập giá trị ASCII của kí tự. Với input là abcde
, nó sẽ tương ứng với lần lượt các giá trị 97, 98, 99, 100, 101.
Sau khi debug đoạn code dưới và liên tục check giá trị của v5
và v5[1]
, mình nhận ra nó sẽ lấy lần lượt các byte từ v8
→ v11
(tổng 26 byte) rồi đem xor với input nhập vào.
for ( j = 0; j < 26; j += 2 )
{
v5 = (char *)&v8 + j;
*v5 ^= input[j % 5u];
v6 = j;
v5[1] ^= input[v6 - 5 * ((unsigned int)&v5[1 - (_DWORD)&v8] / 5) + 1];
}
Với flag format là flag{
, ta dễ dàng tìm được key bằng cách xor ngược lại với 5 giá trị đầu tiên của mảng v8
.
Mình đã bỏ hết tất cả các byte của
v8
→v11
vào trong mảngencryptedFlag
.
encryptedFlag = [0x62, 0x64, 0x6E, 0x70, 0x51, 0x61, 0x69, 0x7C, 0x6E, 0x75, 0x66, 0x69, 0x6D, 0x6E, 0x75, 0x67, 0x60, 0x6E, 0x7B, 0x46, 0x61, 0x66, 0x68, 0x72, 0x57, 0x04]
key = []
leak = "flag{"
for i in range(len(leak)):
tmp = ord(leak[i]) ^ encryptedFlag[i]
key.append(tmp)
print(f"key = {key}")
# key = [4, 8, 15, 23, 42]
Sau khi thu được key, ta xor lại với toàn bộ 26 byte encryptedFlag
để lấy flag.
flag = ""
for i in range(len(encryptedFlag)):
flag += chr(encryptedFlag[i] ^ key[i % len(key)])
print(flag)
# flag{easy_baby_challenge}
Decompile bằng IDA32, ta thu được pseudo-code của hàm main()
như sau
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4; // [esp+0h] [ebp-2CCh]
char v5; // [esp+0h] [ebp-2CCh]
char v6; // [esp+0h] [ebp-2CCh]
char Format[160]; // [esp+8h] [ebp-2C4h] BYREF
char input; // [esp+A8h] [ebp-224h] BYREF
char v9[299]; // [esp+A9h] [ebp-223h] BYREF
char v10[200]; // [esp+1D4h] [ebp-F8h] BYREF
void *v11; // [esp+29Ch] [ebp-30h]
int v12; // [esp+2A0h] [ebp-2Ch]
int v13; // [esp+2A4h] [ebp-28h]
char *v14; // [esp+2A8h] [ebp-24h]
int v15; // [esp+2ACh] [ebp-20h]
char *v16; // [esp+2B0h] [ebp-1Ch]
int v17; // [esp+2B4h] [ebp-18h]
int v18; // [esp+2B8h] [ebp-14h]
char *p_input; // [esp+2BCh] [ebp-10h]
char *addrInput; // [esp+2C0h] [ebp-Ch]
int i; // [esp+2C8h] [ebp-4h]
input = 0;
memset(v9, 0, sizeof(v9));
v12 = 335;
memset(v10, 0, sizeof(v10));
strcpy(
Format,
"Do you remember the good old days?! I don't know how about you,but I don't. Please help me to recover my memory, it'"
"s password protected, and that's sad :(\\n");
v11 = &byte_864BE8;
printf(Format, v4);
printf("Enter password: ", v5);
scanf("%300[^\\n]s", (char)&input);
addrInput = &input;
v16 = v9;
addrInput += strlen(addrInput);
v15 = ++addrInput - v9;
v17 = addrInput - v9;
p_input = &input;
v14 = v9;
p_input += strlen(p_input);
v13 = ++p_input - v9;
if ( (unsigned int)(p_input - v9) >= 294 )
{
if ( checkInput(&input) )
{
v18 = v17 / 3;
for ( i = 0; i < v17; ++i )
v10[i % v18] ^= v9[i - 1];
for ( i = 0; i < v12; ++i )
byte_864020[i] ^= v10[i % v18];
printf("\\n\\nCongratulation! Here is your memo :> \\n\\n", v6);
printf("%s", (char)byte_864020);
}
else
{
printf("\\nInvalid password\\n", v6);
}
getchar();
getchar();
return 0;
}
else
{
printf("oh, no!", v6);
return 0;
}
}