# 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`: ![](https://hackmd.io/_uploads/HyVqQCG2h.png) hàm `flag_check`: ![](https://hackmd.io/_uploads/rkUnXAf3n.png) ![](https://hackmd.io/_uploads/S13n7Rz32.png) Tiến hành phân tích ![](https://hackmd.io/_uploads/BkE3dRf3h.png) 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}