# Arab CTF
Challenge này đưa ta 1 file source asm. Challenge yêu cầu ta nhập rồi check flag ta nhập vào. Vì source code khá xáu để ta có thể đọc, ta sẽ phải tìm cách để chuyển nó thành code C.
```asm=
.LC0:
.string "Enter The Flag:"
.LC1:
.string "%s"
.LC2:
.string "Wrong Flag"
.LC3:
.string "Correct Flag"
flag_check():
push rbp
mov rbp, rsp
sub rsp, 464
mov QWORD PTR [rbp-112], 0
mov QWORD PTR [rbp-104], 0
mov QWORD PTR [rbp-96], 0
mov QWORD PTR [rbp-88], 0
mov QWORD PTR [rbp-80], 0
mov QWORD PTR [rbp-72], 0
mov QWORD PTR [rbp-64], 0
mov QWORD PTR [rbp-56], 0
mov QWORD PTR [rbp-48], 0
mov QWORD PTR [rbp-40], 0
mov QWORD PTR [rbp-32], 0
mov QWORD PTR [rbp-24], 0
mov DWORD PTR [rbp-16], 0
mov edi, OFFSET FLAT:.LC0
call puts
lea rax, [rbp-112]
mov rsi, rax
mov edi, OFFSET FLAT:.LC1
mov eax, 0
call __isoc99_scanf
movabs rax, -871222578553387942
movabs rdx, -3456440840989770153
mov QWORD PTR [rbp-368], rax
mov QWORD PTR [rbp-360], rdx
movabs rax, -6917285895965957581
movabs rdx, 2096695603964784419
mov QWORD PTR [rbp-352], rax
mov QWORD PTR [rbp-344], rdx
movabs rax, 4501421280245125089
movabs rdx, -5989732096912246845
mov QWORD PTR [rbp-336], rax
mov QWORD PTR [rbp-328], rdx
movabs rax, -7641474145812966946
movabs rdx, 5943263215614115999
mov QWORD PTR [rbp-320], rax
mov QWORD PTR [rbp-312], rdx
movabs rax, 3346881274156629838
movabs rdx, -4046563652848771978
mov QWORD PTR [rbp-304], rax
mov QWORD PTR [rbp-296], rdx
movabs rax, 1600213061547397258
movabs rdx, -7907006450299616387
mov QWORD PTR [rbp-288], rax
mov QWORD PTR [rbp-280], rdx
movabs rax, 2641250925692849876
movabs rdx, 5764027888120773659
mov QWORD PTR [rbp-272], rax
mov QWORD PTR [rbp-264], rdx
movabs rax, -2708211178971868809
movabs rdx, -1437889653997315907
mov QWORD PTR [rbp-256], rax
mov QWORD PTR [rbp-248], rdx
movabs rax, -1790267167538066993
movabs rdx, 6751799815650390725
mov QWORD PTR [rbp-240], rax
mov QWORD PTR [rbp-232], rdx
movabs rax, -7155949167227380485
movabs rdx, -240513889820188763
mov QWORD PTR [rbp-224], rax
mov QWORD PTR [rbp-216], rdx
movabs rax, 8430573516374475283
movabs rdx, 7014569824855873983
mov QWORD PTR [rbp-208], rax
mov QWORD PTR [rbp-200], rdx
movabs rax, -1194317526320485479
movabs rdx, -2635243135622213470
mov QWORD PTR [rbp-192], rax
mov QWORD PTR [rbp-184], rdx
movabs rax, 3816607778456458796
movabs rdx, 7739645478794557909
mov QWORD PTR [rbp-176], rax
mov QWORD PTR [rbp-168], rdx
movabs rax, 2239858223738625365
movabs rdx, 6262919446888351940
mov QWORD PTR [rbp-160], rax
mov QWORD PTR [rbp-152], rdx
movabs rax, 5359968574739497219
movabs rdx, -5945185636638990574
mov QWORD PTR [rbp-144], rax
mov QWORD PTR [rbp-136], rdx
movabs rax, 4289602485438450409
movabs rdx, -4136753309120802266
mov QWORD PTR [rbp-128], rax
mov QWORD PTR [rbp-120], rdx
movabs rax, 3689636007142570038
movabs rdx, 7149575679097845041
mov QWORD PTR [rbp-400], rax
mov QWORD PTR [rbp-392], rdx
movabs rax, 3544442000607754086
movabs rdx, 58494055442021
mov QWORD PTR [rbp-390], rax
mov QWORD PTR [rbp-382], rdx
movabs rax, -6712584965997026559
movabs rdx, 5818345077617353901
mov QWORD PTR [rbp-464], rax
mov QWORD PTR [rbp-456], rdx
movabs rax, -1172694937141806812
movabs rdx, -4970398359911696349
mov QWORD PTR [rbp-448], rax
mov QWORD PTR [rbp-440], rdx
movabs rax, -7528756344694355204
movabs rdx, -880185776627970324
mov QWORD PTR [rbp-432], rax
mov QWORD PTR [rbp-424], rdx
mov WORD PTR [rbp-416], -4294
mov BYTE PTR [rbp-1], 0
mov BYTE PTR [rbp-2], 0
mov BYTE PTR [rbp-9], 0
mov DWORD PTR [rbp-8], 0
jmp .L2
.L7:
mov eax, DWORD PTR [rbp-8]
cdqe
movzx eax, BYTE PTR [rbp-112+rax]
mov BYTE PTR [rbp-9], al
movzx eax, BYTE PTR [rbp-9]
cdqe
movzx eax, BYTE PTR [rbp-368+rax]
mov BYTE PTR [rbp-1], al
mov ecx, DWORD PTR [rbp-8]
movsx rax, ecx
imul rax, rax, 715827883
shr rax, 32
mov edx, eax
sar edx, 2
mov eax, ecx
sar eax, 31
sub edx, eax
mov eax, edx
add eax, eax
add eax, edx
sal eax, 3
sub ecx, eax
mov edx, ecx
movsx rax, edx
movzx eax, BYTE PTR [rbp-400+rax]
mov BYTE PTR [rbp-2], al
mov ecx, DWORD PTR [rbp-8]
movsx rax, ecx
imul rax, rax, 715827883
shr rax, 32
mov edx, eax
sar edx, 2
mov eax, ecx
sar eax, 31
sub edx, eax
mov eax, edx
add eax, eax
add eax, edx
sal eax, 3
sub ecx, eax
mov edx, ecx
mov eax, edx
and eax, 1
test eax, eax
je .L3
not BYTE PTR [rbp-2]
.L3:
movzx eax, BYTE PTR [rbp-2]
xor BYTE PTR [rbp-1], al
movzx eax, BYTE PTR [rbp-1]
cdqe
movzx eax, BYTE PTR [rbp-368+rax]
mov BYTE PTR [rbp-1], al
movzx eax, BYTE PTR [rbp-1]
and eax, 1
test eax, eax
je .L4
xor BYTE PTR [rbp-1], 66
.L4:
not BYTE PTR [rbp-1]
mov eax, DWORD PTR [rbp-8]
cdqe
movzx eax, BYTE PTR [rbp-464+rax]
cmp BYTE PTR [rbp-1], al
je .L5
mov edi, OFFSET FLAT:.LC2
mov eax, 0
call printf
mov eax, 1
jmp .L8
.L5:
add DWORD PTR [rbp-8], 1
.L2:
cmp DWORD PTR [rbp-8], 49
jle .L7
mov edi, OFFSET FLAT:.LC3
mov eax, 0
call printf
mov eax, 0
.L8:
leave
ret
```
Trước tiên ta cần phải modify lại code thành code nasm thì ta mới có thể chuyển compile được từ file này sang 1 file mà ta có thể phân tích trong iDa. Sau 1 hồi sửa thì code sẽ trở thành như sau
```nasm=
section .data
.LC0:
db "Enter The Flag:", 0
.LC1:
db "%s", 0
.LC2:
db "Wrong Flag", 0
.LC3:
db "Correct Flag", 0
section .bss
flag_input resb 50
section .text
global flag_check
extern printf, puts, __isoc99_scanf
flag_check:
push rbp
mov rbp, rsp
sub rsp, 464
mov QWORD [rbp-112], 0
mov QWORD [rbp-104], 0
mov QWORD [rbp-96], 0
mov QWORD [rbp-88], 0
mov QWORD [rbp-80], 0
mov QWORD [rbp-72], 0
mov QWORD [rbp-64], 0
mov QWORD [rbp-56], 0
mov QWORD [rbp-48], 0
mov QWORD [rbp-40], 0
mov QWORD [rbp-32], 0
mov QWORD [rbp-24], 0
mov DWORD [rbp-16], 0
mov edi, .LC0
call puts
lea rax, [rbp-112]
mov rsi, rax
mov edi, .LC1
mov eax, 0
call __isoc99_scanf
mov rax, -871222578553387942
mov rdx, -3456440840989770153
mov QWORD [rbp-368], rax
mov QWORD [rbp-360], rdx
mov rax, -6917285895965957581
mov rdx, 2096695603964784419
mov QWORD [rbp-352], rax
mov QWORD [rbp-344], rdx
mov rax, 4501421280245125089
mov rdx, -5989732096912246845
mov QWORD [rbp-336], rax
mov QWORD [rbp-328], rdx
mov rax, -7641474145812966946
mov rdx, 5943263215614115999
mov QWORD [rbp-320], rax
mov QWORD [rbp-312], rdx
mov rax, 3346881274156629838
mov rdx, -4046563652848771978
mov QWORD [rbp-304], rax
mov QWORD [rbp-296], rdx
mov rax, 1600213061547397258
mov rdx, -7907006450299616387
mov QWORD [rbp-288], rax
mov QWORD [rbp-280], rdx
mov rax, 2641250925692849876
mov rdx, 5764027888120773659
mov QWORD [rbp-272], rax
mov QWORD [rbp-264], rdx
mov rax, -2708211178971868809
mov rdx, -1437889653997315907
mov QWORD [rbp-256], rax
mov QWORD [rbp-248], rdx
mov rax, -1790267167538066993
mov rdx, 6751799815650390725
mov QWORD [rbp-240], rax
mov QWORD [rbp-232], rdx
mov rax, -7155949167227380485
mov rdx, -240513889820188763
mov QWORD [rbp-224], rax
mov QWORD [rbp-216], rdx
mov rax, 8430573516374475283
mov rdx, 7014569824855873983
mov QWORD [rbp-208], rax
mov QWORD [rbp-200], rdx
mov rax, -1194317526320485479
mov rdx, -2635243135622213470
mov QWORD [rbp-192], rax
mov QWORD [rbp-184], rdx
mov rax, 3816607778456458796
mov rdx, 7739645478794557909
mov QWORD [rbp-176], rax
mov QWORD [rbp-168], rdx
mov rax, 2239858223738625365
mov rdx, 6262919446888351940
mov QWORD [rbp-160], rax
mov QWORD [rbp-152], rdx
mov rax, 5359968574739497219
mov rdx, -5945185636638990574
mov QWORD [rbp-144], rax
mov QWORD [rbp-136], rdx
mov rax, 4289602485438450409
mov rdx, -4136753309120802266
mov QWORD [rbp-128], rax
mov QWORD [rbp-120], rdx
mov rax, 3689636007142570038
mov rdx, 7149575679097845041
mov QWORD [rbp-400], rax
mov QWORD [rbp-392], rdx
mov rax, 3544442000607754086
mov rdx, 58494055442021
mov QWORD [rbp-390], rax
mov QWORD [rbp-382], rdx
mov rax, -6712584965997026559
mov rdx, 5818345077617353901
mov QWORD [rbp-464], rax
mov QWORD [rbp-456], rdx
mov rax, -1172694937141806812
mov rdx, -4970398359911696349
mov QWORD [rbp-448], rax
mov QWORD [rbp-440], rdx
mov rax, -7528756344694355204
mov rdx, -880185776627970324
mov QWORD [rbp-432], rax
mov QWORD [rbp-424], rdx
mov WORD [rbp-416], -4294
mov BYTE [rbp-1], 0
mov BYTE [rbp-2], 0
mov BYTE [rbp-9], 0
mov DWORD [rbp-8], 0
jmp .L2
.L7:
mov eax, DWORD [rbp-8]
cdqe
movzx eax, BYTE [rbp-112+rax]
mov BYTE [rbp-9], al
movzx eax, BYTE [rbp-9]
cdqe
movzx eax, BYTE [rbp-368+rax]
mov BYTE [rbp-1], al
mov ecx, DWORD [rbp-8]
movsx rax, ecx
imul rax, rax, 715827883
shr rax, 32
mov edx, eax
sar edx, 2
mov eax, ecx
sar eax, 31
sub edx, eax
mov eax, edx
add eax, eax
add eax, edx
sal eax, 3
sub ecx, eax
mov edx, ecx
movsx rax, edx
movzx eax, BYTE [rbp-400+rax]
mov BYTE [rbp-2], al
mov ecx, DWORD [rbp-8]
movsx rax, ecx
imul rax, rax, 715827883
shr rax, 32
mov edx, eax
sar edx, 2
mov eax, ecx
sar eax, 31
sub edx, eax
mov eax, edx
add eax, eax
add eax, edx
sal eax, 3
sub ecx, eax
mov edx, ecx
mov eax, edx
and eax, 1
test eax, eax
je .L3
not BYTE [rbp-2]
.L3:
movzx eax, BYTE [rbp-2]
xor BYTE [rbp-1], al
movzx eax, BYTE [rbp-1]
cdqe
movzx eax, BYTE [rbp-368+rax]
mov BYTE [rbp-1], al
movzx eax, BYTE [rbp-1]
and eax, 1
test eax, eax
je .L4
xor BYTE [rbp-1], 66
.L4:
not BYTE [rbp-1]
mov eax, DWORD [rbp-8]
cdqe
movzx eax, BYTE [rbp-464+rax]
cmp BYTE [rbp-1], al
je .L5
mov edi, .LC2
mov eax, 0
call printf
mov eax, 1
jmp .L8
.L5:
add DWORD [rbp-8], 1
.L2:
cmp DWORD [rbp-8], 49
jle .L7
mov edi, .LC3
mov eax, 0
call printf
mov eax, 0
.L8:
leave
ret
```
Ta sẽ tạo 1 file tên là `awaken.c` có nội dung như sau
```c=
#include <stdio.h>
int flag_check(void);
int main()
{
flag_check();
}
```
tiếp sau đó, ta sử dụng 3 câu lệnh sau để compile
```
nasm -f elf64 awaken.asm -o your_filename.o
gcc -c awaken.c
gcc awaken.o your_filename.o -no-pie -o code
```
sau khi chạy 3 câu lệnh này trên linux, ta sẽ ra được 1 file elf có tên là `code`. Sau đó mình đưa vào iDa để phân tích
hàm `main`:

hàm `flag_check`:


Tiến hành phân tích

mình sẽ note từng dòng ở code sau đây cho dễ hình dung
```c=
for ( i = 0; i <= 49; ++i )
{
v7 = *((_BYTE *)input + i); // duyệt từng phần tử của chuỗi đầu vào
v10 = *((_BYTE *)v4 + v7); // duyệt phân tử ứng với vị trí mang giá trị của biến v7 ta vừa xét
v9 = v3[i % 24]; // lấy giá trị của v3 dựa trên i
if ( ((i % 24) & 1) != 0 )
v9 = ~v9; // kiểm tra xem i có chẵn hay không, nếu có thì đảo ngược bit của v9
v10 ^= v9; // tiến hành xor
v10 = *((_BYTE *)v4 + v10); // lại duyệt phần tử thứ v10 của chuỗi v4
if ( (v10 & 1) != 0 )
v10 ^= 0x42u; // nếu như v10 mang giá trị lẻ thì sẽ thực hiện xor v10 với 0x42
v10 = ~v10; // thực hiện đảo ngược bit của v10
if (v10 != *((_BYTE *)v1 + i))
{
printf("Wrong Flag"); // nếu như v10 mang giá trị không giống với các phần tử tương úng trong mảng v1 thì in ra chuỗi "Wrong Flag"
return 1LL;
}
}
```
Mình sẽ biết 1 script bruteforce ra flag với cách mã hõa này. Ở đây ta có thể dễ dàng nhận ra rằng `v3 --> key`, `v1 --> goal`, `v4 --> cipher`
`Script`:
```python=
# cipher = [0x5A, 0x84, 0x06, 0x45, 0xAE, 0xCB, 0xE8, 0xF3, 0x57, 0xFE,
# 0xA6, 0x3D, 0x5E, 0x41, 0x08, 0xD0, 0x33, 0x22, 0x21, 0x81,
# 0x20, 0xDD, 0x00, 0xA0, 0x23, 0xAF, 0x71, 0x04, 0x8B, 0xF5,
# 0x18, 0x1D, 0xE1, 0x0F, 0x65, 0x09, 0xCE, 0x42, 0x78, 0x3E,
# 0xC3, 0x37, 0xCA, 0x8F, 0x64, 0x32, 0xE0, 0xAC, 0xDE, 0x91,
# 0x7C, 0x2A, 0xC0, 0x07, 0xF4, 0x95, 0x9F, 0x40, 0x53, 0xE5,
# 0x67, 0xB6, 0x7A, 0x52, 0x4E, 0x3F, 0x83, 0x4B, 0xC9, 0x82,
# 0x72, 0x2E, 0x76, 0x1C, 0xF1, 0x1E, 0xCC, 0xB7, 0xD7, 0xC7,
# 0x8A, 0x10, 0x79, 0x1A, 0x4D, 0x19, 0x35, 0x16, 0x7D, 0x43,
# 0x2B, 0xCD, 0x86, 0xAB, 0x44, 0x92, 0xD4, 0x0E, 0x98, 0x14,
# 0xB9, 0x9B, 0xA7, 0x24, 0x1B, 0x3C, 0xE2, 0x3A, 0xD3, 0xF0,
# 0xFD, 0x4F, 0x77, 0xD1, 0xA3, 0x0C, 0x48, 0x80, 0x6A, 0xDA,
# 0xBD, 0xD8, 0x47, 0x5B, 0xFA, 0x96, 0x0B, 0xEC, 0xCF, 0x49,
# 0xD9, 0x11, 0x7F, 0xB1, 0x27, 0xE7, 0xC5, 0xB2, 0x63, 0xE6,
# 0x28, 0x36, 0xB3, 0x5D, 0xFB, 0xDC, 0xA8, 0x70, 0x25, 0xF6,
# 0xB0, 0x9C, 0xA5, 0x5F, 0xB8, 0x39, 0xE4, 0x85, 0xA9, 0xFC,
# 0x13, 0x02, 0x51, 0x30, 0xF2, 0x69, 0xFF, 0x74, 0xBF, 0x59,
# 0xB5, 0x46, 0x17, 0xC2, 0x58, 0x61, 0x99, 0xEB, 0xA4, 0x9E,
# 0x89, 0xEE, 0x6C, 0xEF, 0xA2, 0x90, 0x73, 0x8C, 0x54, 0xBC,
# 0x6D, 0xDB, 0x2C, 0xD6, 0xE3, 0xA1, 0x8D, 0x50, 0xF7, 0x34,
# 0xD5, 0xF9, 0x01, 0x7B, 0x8E, 0xBE, 0x68, 0x6B, 0x55, 0x9D,
# 0x2D, 0xED, 0x2F, 0x93, 0x15, 0x1F, 0xC4, 0x88, 0xAA, 0xF8,
# 0x0D, 0x5C, 0xEA, 0x56, 0x03, 0xC1, 0x9A, 0x38, 0x05, 0x6F,
# 0x62, 0x4A, 0x12, 0xDF, 0x60, 0x94, 0x29, 0x75, 0x7E, 0xAD,
# 0xE9, 0x0A, 0x31, 0xB4, 0xBB, 0xBA, 0x87, 0x3B, 0x26, 0xD2,
# 0x6E, 0x66, 0xC8, 0x4C, 0x97, 0xC6]
# key = [ 0x36, 0x38, 0x39, 0x64, 0x66, 0x38, 0x34, 0x33, 0x31, 0x35,
# 0x66, 0x37, 0x33, 0x65, 0x38, 0x63]
# goal = [0x01, 0xA3, 0x1E, 0xC9, 0x89, 0x1B, 0xD8, 0xA2, 0xAD, 0x64,
# 0x06, 0x6C, 0x05, 0xEA, 0xBE, 0x50, 0x24, 0x79, 0xC3, 0xF9,
# 0x2A, 0xC0, 0xB9, 0xEF, 0x23, 0x78, 0x47, 0xA5, 0x06, 0x99,
# 0x05, 0xBB, 0xFC, 0x4A, 0x06, 0x5A, 0xFE, 0x7B, 0x84, 0x97,
# 0xEC, 0x0E, 0xBD, 0x17, 0xB3, 0xF3, 0xC8, 0xF3, 0x3A, 0xEF]
cipher = b'Z\x84\x06E\xae\xcb\xe8\xf3W\xfe\xa6=^A\x08\xd03"!\x81 \xdd\x00\xa0#\xafq\x04\x8b\xf5\x18\x1d\xe1\x0fe\t\xceBx>\xc37\xca\x8fd2\xe0\xac\xde\x91|*\xc0\x07\xf4\x95\x9f@S\xe5g\xb6zRN?\x83K\xc9\x82r.v\x1c\xf1\x1e\xcc\xb7\xd7\xc7\x8a\x10y\x1aM\x195\x16}C+\xcd\x86\xabD\x92\xd4\x0e\x98\x14\xb9\x9b\xa7$\x1b<\xe2:\xd3\xf0\xfdOw\xd1\xa3\x0cH\x80j\xda\xbd\xd8G[\xfa\x96\x0b\xec\xcfI\xd9\x11\x7f\xb1\'\xe7\xc5\xb2c\xe6(6\xb3]\xfb\xdc\xa8p%\xf6\xb0\x9c\xa5_\xb89\xe4\x85\xa9\xfc\x13\x02Q0\xf2i\xfft\xbfY\xb5F\x17\xc2Xa\x99\xeb\xa4\x9e\x89\xeel\xef\xa2\x90s\x8cT\xbcm\xdb,\xd6\xe3\xa1\x8dP\xf74\xd5\xf9\x01{\x8e\xbehkU\x9d-\xed/\x93\x15\x1f\xc4\x88\xaa\xf8\r\\\xeaV\x03\xc1\x9a8\x05obJ\x12\xdf`\x94)u~\xad\xe9\n1\xb4\xbb\xba\x87;&\xd2nf\xc8L\x97\xc6'
key = b"689df84315f73e8c01efe535"
goal = b'\x01\xa3\x1e\xc9\x89\x1b\xd8\xa2\xadd\x06l\x05\xea\xbeP$y\xc3\xf9*\xc0\xb9\xef#xG\xa5\x06\x99\x05\xbb\xfcJ\x06Z\xfe{\x84\x97\xec\x0e\xbd\x17\xb3\xf3\xc8\xf3\x3a\xef'
def find(n):
for x in range(256):
v10 = cipher[x]
v9 = key[n % 24]
if (n % 24) & 1 != 0:
v9 ^= 0xff
v10 ^= v9
v10 = cipher[v10]
if v10 & 1 != 0:
v10 ^= 0x42
v10 ^= 0xff
if v10 == goal[n]:
return x
return -1
output = ""
for x in range(len(goal)):
output += chr(find(x))
print(output)
```
> Flag : ASCWG{What_do_you_see_before_it_is_over?_998bd0d4}