# KMACTF-1
## Callfustcate
`Challenge`

Khi chạy chương trình nó yêu cầu mình nhập flag, nếu nhập sai thì sẽ trả về `Wrong!`

Đọc file trong IDA, hàm `main chỉ đơn giản như sau`

Mình có đọc pseudocode thì mình đoán chức năng của từng hàm như sau:
`sub_7FF6443D2480` - `printf()`
`sub_7FF6443D2500` - `scanf()`
`sub_7FF6443D35B0` - `encode`
`sub_7FF6443D4680` - `check`
Mình xem 2 hàm `encode` và `check`
`encode`

`check`

Gosh, 2 hàm đều bị obfustcate @@ đọc mù hết cả mắt, mình thấy tất cả các câu lệnh bị obfustcate, ban đầu mình đoán rằng đây là `obfuscate MBA`rồi sau đó 2 tiếng mình ngồi loay hoay đề de-obfustcate đống code này, nhưng sau đó mình nghĩ nếu cứ như thế này thì sẽ rất mất thời gian, nên mình quyết định phân tích lại hàm 1 lần nữa, rồi mình phát hiện ra rằng đống obfustcate này nó không xử lý gì đến input mà mình truyền vào cả, thêm vào nữa cuối mỗi hàm nó sẽ return đến 1 địa chỉ khác. Mình có đặt break point ở đấy để xem đầy sẽ đi đến đâu
Trước tiên mình sẽ kiểm tra hàm `check`, hàm sẽ trả về hàm `memcmp()` và kiểm tra 48 kí tự sau khi ta encode có giống với data ở `unk_7FF6443F6000` không

Sau đó là hàm `encode` thì như sau

Mình đoán bên trong cái hàm `sub_7FF6443D1200` kia sẽ lại là 1 đống obfustcate khác và hàm `sub_7FF6443D1200` nó sẽ trả về hàm sau

Ở đây có 1 số biến mang giá trị cố định như sau
```py=
v18 = 0x63 c
v17 = 0x6f o
v15 = 0x6e n
v15 = 0x66 f
v14 = 0x75 u
v7 = 0x73 s
v9 = 0x65 e
v11 = 0x64 d
```
Các biến còn lại sẽ mang giá trị của input của mình truyền vào, sau đó chương trình sẽ thực hiện encode bằng thuật toán `__ROL1__` giá trị của mảng `byte_7FF6443EB000` 100 lần và kết thúc vòng lặp. Giá trị sau khi encode sẽ được lưu vào input vậy ta chỉ cần đảo ngược
Giờ ta chỉ cần dịch ngược hàm encode kia nữa là xong. Nếu như hôm đấy mình đủ tỉnh táo thì đã nghĩ ra được script giải. Đây là script giải ngược :<
```py=
cipher = [ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01,
0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D,
0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4,
0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7,
0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E,
0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB,
0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB,
0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C,
0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C,
0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D,
0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A,
0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3,
0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A,
0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E,
0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,
0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9,
0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99,
0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]
goal = [0xE5, 0xA8, 0x07, 0x2E, 0xE8, 0x67, 0xB5, 0x0C, 0xF9, 0x05,
0xA1, 0xA8, 0xFA, 0x05, 0x0A, 0x66, 0xA0, 0xC1, 0x20, 0x4E,
0xE3, 0x7D, 0xD0, 0x04, 0x21, 0x67, 0xEC, 0x9E, 0x7D, 0xBC,
0x2D, 0x8D, 0x9B, 0x65, 0xDC, 0x71, 0xE4, 0x57, 0x81, 0x11,
0x1A, 0x71, 0x7F, 0x84, 0x2C, 0x88, 0x25, 0x94]
ROL = lambda val, m, max: (val << m % max) & (2**max - 1) | ((val & (2**max - 1)) >> (max-(m % max)))
ROR = lambda val, m, max: ((val & (2**max - 1)) >> m % max) | (val << (max - (m % max)) & (2**max - 1))
for i in range(6):
for j in range(100):
goal[i*8+0] = 0xff & ((ror((goal[i*8+0]), 1, 8)) - cipher[(goal[i*8+7] & 0xff) + ord("d")&0xff])
goal[i*8+7] = 0xff & ((ror((goal[i*8+7]), 1, 8)) - cipher[(goal[i*8+6] & 0xff) + ord("e")&0xff])
goal[i*8+6] = 0xff & ((ror((goal[i*8+6]), 1, 8)) - cipher[(goal[i*8+5] & 0xff) + ord("s")&0xff])
goal[i*8+5] = 0xff & ((ror((goal[i*8+5]), 1, 8)) - cipher[(goal[i*8+4] & 0xff) + ord("u")&0xff])
goal[i*8+4] = 0xff & ((ror((goal[i*8+4]), 1, 8)) - cipher[(goal[i*8+3] & 0xff) + ord("f")&0xff])
goal[i*8+3] = 0xff & ((ror((goal[i*8+3]), 1, 8)) - cipher[(goal[i*8+2] & 0xff) + ord("n")&0xff])
goal[i*8+2] = 0xff & ((ror((goal[i*8+2]), 1, 8)) - cipher[(goal[i*8+1] & 0xff) + ord("o")&0xff])
goal[i*8+1] = 0xff & ((ror((goal[i*8+1]), 1, 8)) - cipher[(goal[i*8+0] & 0xff) + ord("c")&0xff])
for k in goal:
print(chr(k), end="")
```
>KMA{e81eabf0-db79-463d-b227-ea47dcf6cac6}
---
## Guess my flag
`Challenge`

`Hint`

Khi chạy chương trình, chương trình sẽ yêu cầu ta nhập vào key, nếu như key đúng sẽ in ra flag, nếu như key sai thì sẽ trả về byte rác

Phân tích file trong IDA, trước tiên mình đọc Pseudocode

như vậy hàm sẽ yêu cầu mình nhập key vào, sau đó thực hiện 1 hàm encode và sau khi mình phân tích thì nhận ra đấy là `RC4_128bit`.


Sau đó từ `Hint`, mình tiến hành so sánh giữa code asm và Pseudocode xem điểm khác biệt nằm ở đâu thì mình có phát hiện ra rằng có 1 lượng lớn (56bytes) data có trong code asm mà lại ko có trong Pseudocode

Trông đống data này khá là nghi ngờ nên mình đã đặt 1 breakpoint tại hàm `scanf` nhập bừa input vào, sau đó patch lại input vào xem hàm sẽ trả ra cái gì =)))

mình nhập vào vài chữ a rồi tiến hành patch lại tại địa chỉ của input.


Ở đây mình sẽ patch tại địa chỉ `0xAE8048`, vì mỗi khi thực hiện debug, IDA sẽ map với 1 địa chỉ random nên đừng bối rối khi địa chỉ lưu input của bạn khác của mình.
Để viết script patch data ngay trong IDA, ta sẽ làm như sau: `File -> Script Command -> Python -> viết và run script (Hoặc ta có thể dùng Shift + F2 rồi viết và run script)`


`Script patch`
```py=
from os import *
sus_key = bytes.fromhex("45 32 55 35 14 0F 5D 63 26 76 74 06 02 31 05 34 51 77 5C 2C 3F 2B 3E 36 28 07 50 7D 40 58 24 15 65 79 6F 5A 3A 59 3B 04 5C 4C 2F 3D 26 11 38 2A 17 42 30 4E 1B 05 06 49")
for i in range(len(sus_key)):
idc.patch_byte(0xAE8048+i, sus_key[i])
```
Sau khi patch data sẽ như sau

Okay giờ ta sẽ đi thẳng tới hàm `print` cuối cùng để xem kết quả trả ra là gì, oh và ta có flag :3

> KMA{haycuvotuvalacquanlenemoichilakhongyeuthuongthoisaonuocmatphairoi}
---
## Time Chaos
`challenge`

Ném file vào Wireshark, sort theo time rồi mình bốc data tay, data mà mình cần lấy sẽ là byte hex cuối cùng là thứ mà ta cần lấy =))))))).



Đọc flag xong nhột ngang :<<<
> KMACTF{C0d3_cun9_du0c_t0Ol_Cun9_DuOc_nHun9_h1_v0n9_b4n_kh0n9_l@m_m0t_c4cH_tHu_C0nG}