---
# System prepended metadata

title: f@k3
tags: [KCSC_2024]

---

- Đây là lần đầu tiên mình tham gia giải offline nên khá nhiều bỡ ngỡ và lo lắng, hơn thế nữa mình còn là newbie :>
- Cảm ơn anh Sơn đã hỗ trợ e giải bài này ạ.
# Overview
![image](https://hackmd.io/_uploads/S1SNDLDmR.png)
# Solution
- Mình cho vào IDA để debug rồi F5 xem mã giả.
```
int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  unsigned int v4; // eax
  char v6[256]; // [rsp+30h] [rbp-D18h] BYREF
  char Str[1024]; // [rsp+130h] [rbp-C18h] BYREF
  CHAR fake[1024]; // [rsp+530h] [rbp-818h] BYREF
  CHAR input[1024]; // [rsp+930h] [rbp-418h] BYREF

  Str[0] = -33;
  Str[1] = 69;
  Str[2] = 67;
  Str[3] = 49;
  Str[4] = -122;
  Str[5] = 38;
  Str[6] = 116;
  Str[7] = -97;
  Str[8] = -87;
  Str[9] = 118;
  Str[10] = -115;
  Str[11] = -86;
  Str[12] = -108;
  Str[13] = 116;
  Str[14] = -73;
  Str[15] = 46;
  Str[16] = -98;
  Str[17] = -94;
  Str[18] = 20;
  Str[19] = 5;
  Str[20] = 109;
  Str[21] = -87;
  Str[22] = -34;
  Str[23] = -89;
  Str[24] = 80;
  Str[25] = 57;
  Str[26] = 17;
  memset(&Str[27], 0, 0x3E5ui64);
  printf("[+] Input flag: ");
  scanf("%s", input);
  v3 = strlen(Key);
  RC4_init(v6, Key, v3);
  v4 = strlen(Str);
  createFake(v6, Str, v4, fake);
  if ( lstrcmpA(input, fake) )
    printf("\nWrong!");
  else
    printf("Correct!");
  return 0;
}
```
- Mình đã thay đổi tên của vài hàm và biến cho dễ phân biệt bằng cách dùng `ctrl + N`.
- Chương trình chỉ đơn giản là nó bắt bạn nhập 1 string rồi so với 1  string khác.
- Bạn đặt bp rồi debug, sau khi chạy qua hàm creatFake, ta có thể thấy hàm createFake sẽ tạo 1 fake flag.
![image](https://hackmd.io/_uploads/H1Frw8D7A.png)
- Fake flag được lưu trong rcx, bạn trỏ đến thanh ghi này, sẽ thấy.
- Sau khi chạy qua mấy lệnh nữa, ta thấy hàm `lstrcmpA`.
=> Ban đầu mình tưởng đơn giản chỉ là hàm so sánh `strcmp` nhưng không, nó là 1 fake strcmp :>
- Ta có thể dễ dàng nhập ra khi debug tiếp, nó sẽ chạy xuống và in `Correct`, dù nó là false.
![image](https://hackmd.io/_uploads/rkt8vUP70.png)
- Mình bấm vào hàm ấy nó ra 1 cái địa chỉ.
- Đây mới chương trình thật của nó
```
__int64 __fastcall sub_7FF668F31230(__int64 input_string, __int64 fake_flag)
{
  int i; // [rsp+20h] [rbp-128h]
  char sus[128]; // [rsp+30h] [rbp-118h] BYREF
  char res[128]; // [rsp+B0h] [rbp-98h] BYREF

  qmemcpy(sus, "fM", 2);
  sus[2] = 12;
  sus[3] = -95;
  sus[4] = 86;
  sus[5] = 63;
  sus[6] = 43;
  sus[7] = -67;
  sus[8] = 78;
  sus[9] = 97;
  sus[10] = 106;
  sus[11] = -114;
  sus[12] = 73;
  sus[13] = 81;
  sus[14] = 61;
  sus[15] = -121;
  sus[16] = 114;
  sus[17] = 124;
  sus[18] = 54;
  sus[19] = -123;
  sus[20] = 69;
  sus[21] = 122;
  sus[22] = 104;
  sus[23] = -67;
  sus[24] = 75;
  sus[25] = 98;
  sus[26] = 62;
  sus[27] = -37;
  sus[28] = 114;
  sus[29] = 102;
  sus[30] = 58;
  sus[31] = -112;
  sus[32] = 72;
  sus[33] = 81;
  sus[34] = 1;
  sus[35] = -52;
  sus[36] = 115;
  sus[37] = 78;
  sus[38] = 31;
  sus[39] = -97;
  memset(&sus[40], 0, 0x58ui64);
  memset(res, 0, sizeof(res));
  for ( i = 0; i < strlen(sus); ++i )
    res[i] = *(_BYTE *)(fake_flag + i % 4) ^ sus[i];
  return 0i64;
}
```
- Mình đặt lại tên cho clean code cái.
- Đọc sơ qua, mình có thể đoán đc, flag mình đang tìm chính là chuỗi res.
- Nhưng khi mình chạy thử mấy vòng lặp XOR thì thấy nó không ra cái gì cả.
- Quay lại hàm main(), mình thấy 1 thứ, đã bỏ quên là cái key `f@**!`, là thứ mã hóa v6~map.
![image](https://hackmd.io/_uploads/ryIOv8wQ0.png)
- Dưới đây là hàm RC4_init() cùng với key đã bđ v6~map ntn:
![image](https://hackmd.io/_uploads/HJzXkwP7C.png)
- Đối với hàm createFake(), fake_flag sẽ được tạo ra từ map.
![image](https://hackmd.io/_uploads/BJ6a08P7R.png)
=> Từ đó, mình phát hiện ra rằng v6~map là thứ sẽ qđ flag ra chuẩn hay không.
- Bây giờ mình sẽ dùng xref, công dụng của nó là trỏ đến những hàm có sự xuất hiện của key.
- Mình xref key thì ra hàm này:
![image](https://hackmd.io/_uploads/HJlKwUvQC.png)
![image](https://hackmd.io/_uploads/SkYFvLvQA.png)
- Mình thử đặt bp tại đây và chạy thì nó luôn trỏ sang true => mình set ip hoặc đổi cờ ZF để nó sang false.
- Cuối cùng key nó bị biến từ `f@**!` -> `fA++!`.
![image](https://hackmd.io/_uploads/H1SswIPQR.png)
- Rồi ta chạy vào hàm fake strcmp rồi XOR lại với sus[], xem chuỗi res[] nó ra gì.
![image](https://hackmd.io/_uploads/SyCsPUP70.png)

=> flag: `KCSC{1t_co5ld_be_right7_fla9_here_^.^@@}`
- Tóm lại, cái key đã làm cái v6 bị biến đổi, do đó, ta cần sửa key rồi truyền nó vào hàm createFake(), bên cạnh đó, xuất hiện 1 hàm fake strcmp(), bản chất nó là tạo flag chứ kp là so sánh.
