# Crackme # Check file bằng DIE ![](https://i.imgur.com/gD4dygb.png) Bài này được viết bằng Elf 64bit Chạy thử chương trình ![](https://i.imgur.com/oG5f2aZ.png) Mở IDA và load vào main ![](https://i.imgur.com/CURavHL.png) Giải thích sơ qua về code thì, Chương trình chứa 2 vòng lặp lồng nhau lặp qua bộ đệm nằm ở địa chỉ **0x4006E5** và gọi một hàm có tên **sub_400526** trên mỗi byte. Sau khi vòng lặp kết thúc, chương trình gọi một hàm nằm ở địa chỉ bộ nhớ **0x4006E5** và kiểm tra giá trị trả về của nó. Nếu giá trị trả về là true, chương trình in ra chuỗi "Correct!" Nếu không, nó sẽ in chuỗi "Wrong!". Do vậy chúng ta chỉ quan tâm đến hàm **0x4006E5** vì đây sẽ là hàm checkflag sau khi input bị mã hóa bởi hàm **sub_400526** **0x4006E5**:![](https://i.imgur.com/873ATlp.png) **Sub_400526**: ![](https://i.imgur.com/B4qnDq0.png) Vì thế nên ta đặt breakpoint tại: ![](https://i.imgur.com/eqLEdsl.png) Sau khi debug thì IDA sẽ bị lẻ byte nên ta sẽ dùng GDB xem có bị trường hợp này không Đặt breakpoint tại 0x004006db để lấy shellcode ![](https://i.imgur.com/vG8JDNi.png) gef➤ x/300i $rip để vào **sub_4006E5** do hàm main chỉ sửa được 552 byte nên ta chỉ xét từ 0x4006e5 => 0x40090b ``` => 0x4006db: call 0x4006e5 0x4006e0: jmp 0x40090d 0x4006e5: push rbp 0x4006e6: mov rbp,rsp 0x4006e9: call 0x400702 0x4006ee: mov cl,al 0x4006f0: mov eax,0xae5fe432 0x4006f5: add eax,0x51a01bce 0x4006fa: inc eax 0x4006fc: jae 0x400706 0x4006fe: mov al,cl 0x400700: leave 0x400701: ret 0x400702: push rbx 0x400703: push rdi 0x400704: push rbp 0x400705: mov rbp,rsp 0x400708: mov rdx,rax 0x40070b: dec eax 0x40070d: jmp 0x40070e 0x40070f: ror BYTE PTR [rax-0x75],0xfa 0x400713: xor al,al 0x400715: xor ecx,ecx 0x400717: dec rcx 0x40071a: repnz scas al,BYTE PTR es:[rdi] 0x40071c: not ecx 0x40071e: dec ecx 0x400720: mov eax,0x92185987 0x400725: xor eax,0x32963a85 0x40072a: jns 0x4006b7 0x40072c: mov eax,0xc3bc42d9 0x400731: xor eax,0x1ed2c907 0x400736: jns 0x400742 0x400738: push 0x50 0x40073a: pop r9 0x40073c: xor r8d,r8d 0x40073f: cmp r8d,0x539 0x400746: jl 0x400763 0x400748: jmp 0x400774 0x40074a: dec eax 0x40074c: jmp 0x40074d 0x40074e: rol BYTE PTR [rcx-0x7d],0xc0 0x400752: add DWORD PTR [rax+0x669ec28e],edi 0x400758: add eax,0x99613d72 0x40075d: inc eax 0x40075f: jae 0x400724 0x400761: jmp 0x40073f 0x400763: mov eax,0xe72b5c52 0x400768: add eax,0x18d4a3ae 0x40076d: jne 0x400747 0x40076f: xor r11d,r11d 0x400772: jmp 0x4007ac 0x400774: mov eax,0xea3e6566 0x400779: xor eax,0x5f69faeb 0x40077e: jns 0x4007b6 0x400780: lea rax,[rip+0x164] # 0x4008eb 0x400787: lea r8,[rax] 0x40078a: mov eax,0xb5de3358 0x40078f: xor eax,0x459f236e 0x400794: jns 0x400797 0x400796: dec eax 0x400798: jmp 0x400799 0x40079a: shr BYTE PTR [rdx+0x1],0x41 0x40079e: pop rdx 0x40079f: dec eax 0x4007a1: jmp 0x4007a2 0x4007a3: rol BYTE PTR [rbp+0x33],0xc9 0x4007a7: jmp 0x400834 0x4007ac: dec eax 0x4007ae: jmp 0x4007af 0x4007b0: rol BYTE PTR [rbx+rdi*1-0x27],0x7c 0x4007b5: add ch,bl 0x4007b7: xchg edx,eax 0x4007b8: mov eax,0x2b71234a 0x4007bd: add eax,0xd48edcb6 0x4007c2: inc eax 0x4007c4: jae 0x400774 0x4007c6: movsxd r10,r11d 0x4007c9: mov eax,0xef8ac85b 0x4007ce: xor eax,0xe71ae312 0x4007d3: js 0x4007ff 0x4007d5: mov rbx,rdx 0x4007d8: add rbx,r10 0x4007db: mov eax,0x46d3a79d 0x4007e0: add eax,0xb92c5863 0x4007e5: jne 0x4007ee 0x4007e7: movsxd r10,r11d 0x4007ea: mov eax,0xf45102a7 0x4007ef: xor eax,0xae9accbc 0x4007f4: js 0x40085f 0x4007f6: mov rax,rdx 0x4007f9: add rax,r10 0x4007fc: mov al,BYTE PTR [rax] 0x4007fe: xor al,r9b 0x400801: mov BYTE PTR [rbx],al 0x400803: movsxd r10,r11d 0x400806: mov rax,rdx 0x400809: add rax,r10 0x40080c: mov al,BYTE PTR [rax] 0x40080e: xor r9b,al 0x400811: mov eax,0x91ecf78 0x400816: add eax,0xf6e13088 0x40081b: inc eax 0x40081d: jae 0x4007be 0x40081f: add r11d,0x1 0x400823: mov eax,0x15690edd 0x400828: xor eax,0xd68c1903 0x40082d: jns 0x400888 0x40082f: jmp 0x4007ac 0x400834: mov eax,0x4759bfd0 0x400839: add eax,0xb8a64030 0x40083e: inc eax 0x400840: jae 0x400847 0x400842: cmp r9d,ecx 0x400845: jl 0x400849 0x400847: jmp 0x400850 0x400849: test r10b,r10b 0x40084c: jne 0x400857 0x40084e: jmp 0x40089f 0x400850: mov al,r10b 0x400853: leave 0x400854: pop rdi 0x400855: pop rbx 0x400856: ret 0x400857: movsxd r11,r9d 0x40085a: mov eax,0x5f9c75ce 0x40085f: xor eax,0x5d98bd96 0x400864: js 0x4008a0 0x400866: mov r10,rdx 0x400869: add r10,r11 0x40086c: dec eax 0x40086e: jmp 0x40086f 0x400870: rol BYTE PTR [rbp-0x76],0x1a 0x400874: mov eax,0xf8eca7d8 0x400879: add eax,0x7135828 0x40087e: jne 0x40081c 0x400880: movsxd rax,r9d 0x400883: mov r10,r8 0x400886: add r10,rax 0x400889: mov eax,0x3b4ad836 0x40088e: xor eax,0xf1d7dbea 0x400893: jns 0x400818 0x400895: mov al,BYTE PTR [r10] 0x400898: cmp r11b,al 0x40089b: je 0x4008c3 0x40089d: jmp 0x4008da 0x40089f: xor r10b,r10b 0x4008a2: mov eax,0x2e4ef210 0x4008a7: add eax,0xd1b10df0 0x4008ac: jne 0x40087e 0x4008ae: mov eax,0x1bff10d0 0x4008b3: xor eax,0x9dd00315 0x4008b8: jns 0x40091d 0x4008ba: add r9d,0x1 0x4008be: jmp 0x400834 0x4008c3: mov eax,0x451c2342 0x4008c8: add eax,0xbae3dcbe 0x4008cd: jne 0x400901 0x4008cf: push 0x1 0x4008d1: pop r10 0x4008d3: dec eax 0x4008d5: jmp 0x4008d6 0x4008d7: shr bl,0x3 0x4008da: xor r10b,r10b 0x4008dd: mov eax,0x5e82d693 0x4008e2: add eax,0xa17d296d 0x4008e7: jne 0x40090a 0x4008e9: jmp 0x4008a2 0x4008eb: rex.W pop rdi 0x4008ed: ss xor eax,0x2c142535 0x4008f3: sbb eax,0xc2d0301 0x4008f8: outs dx,DWORD PTR ds:[rsi] 0x4008f9: xor eax,0xa347e61 0x4008fe: rex.R and al,0x2c 0x400901: rex.WX 0x400902: rex.RX sbb DWORD PTR [rcx+0x5b],r11d 0x400906: (bad) 0x400907: js 0x40097d 0x400909: sub DWORD PTR [rbx],edx 0x40090b: sub al,0x0 ``` Ta có thể hiểu đoạn code này như sau, byte đầu tiên của flag sẽ được XOR với 0x50, byte thứ hai được XOR với byte đầu tiên của cờ và lặp 1337 lần. Kết quả được so sánh với dữ liệu được lưu trữ ở 0x4008eb. Nếu chúng khớp với nhau, nó sẽ in"Correct ”. Do byte thứ 34 là 0 nên => độ dài của flag 33 đoạn code được viết lại: ``` for k in range(0,256): key = 0x50 mask = k flag = bytearray(data) for i in range(0,1337): for j in range(length,-1,-1): mask = flag[j] ^ mask flag[j] = flag[j] ^ mask ``` Do byte thứ 34 là 0 nên => độ dài của flag 33, tiến hành dump từ 0x4008eb ![](https://i.imgur.com/r8TU29r.png) **Script** ``` data = [72,95,54,53,53,37,20,44,29,1,3,45,12,111,53,97,126,52,10,68,36,44,74,70,25,89,91,14,120,116,41,19,44] length = len(data)-1 for k in range(0,256): key = 0x50 mask = k flag = bytearray(data) for i in range(0,1337): for j in range(length,-1,-1): mask = flag[j] ^ mask flag[j] = flag[j] ^ mask if mask == key: print(flag[:length+1]) ``` ![](https://i.imgur.com/rulWhz4.png) flag = pctf{ok_nothing_too_fancy_there!}