F81E37E841D0B2C1D5738A7D60FD98BE

Solution

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 v5v5[1], mình nhận ra nó sẽ lấy lần lượt các byte từ v8v11 (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 v8v11 vào trong mảng encryptedFlag.

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}

crackme_1

Solution

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;
  }
}