Sicurezza Informatica

Esercitazioni, Competizioni e Test:

LABORATORIO DI SICUREZZA INFORMATICA

a cura di: Francesco (Galt) Faloci

General Software Security

  • General Software Security
    • ​Buffer Overflow​
    • Format String

BUF-...WHU?

  • E’ il più comune tra tutti i tipi di insicurezza nel
    codice C
     
  • E’ quasi del tutto assente nei linguaggi ad alto
    livello che non permettono la gestione diretta
    della memoria
     
  • Consiste nel forzare la scrittura in memoria con una quantità di informazione superiore a quella accettabile
  • Se il software è privo di controlli è possibile
    inserire del codice eseguibile in queste stringhe di
    overflow
     
  • Può essere eseguito nello stack, nell’heap e nel
    BSS(block started by symbol, contiene variabili
    statiche)

BUF-...WHU?

Per poter svolgere l’esercitazione bisogna prima scaricare tre file che spiegheremo nel dettaglio successivamente:

  • call_shellcode.c
  • exploit.c
  • stack.c

BUF-...WHU?

Weird thing

Disattiviamo la prima protezione utilizzate dai
sistemi Linux per la memoria dinamica

 

  • - sudo sysctl -w kernel.randomize_va_space=0
     
  • - sudo sysctl kernel.randomize_va_space (verifica)

First Try

  • Prima di cominciare l’attacco abbiamo bisogno di uno shellcode, ovvero un codice per lanciare una shell
     

  • Esso deve essere caricato in memoria così da permetterci di forzare il programma vulnerabile a  "saltarci dentro"
     

  • Nel nostro caso è un codice assembler "shellcode.c" :

    • crea un array di caratteri che contiene lo shellcode

    • all'interno del main copia l’array in un buffer

First Try

Compiliamo e lanciamo il file:

  • gcc -z execstack -o call_shellcode call_shellcode.c
  • ./call_shellcode
  • > id (vedere che siamo ancora seed)

First Try

Il nostro scopo sarà usare questo shell code in  modo da poter aprire una bash con i permessi di root

  • sudo chown root call_shellcode (pass di seed)
  • sudo chmod u+s call_shellcode
  • ./call_shellcode
  • > id (vedere che NON siamo seed)

Second Try

Passiamo ora a vedere il programma vulnerabile stack.c
Contiene 2 funzioni:

  1. Main(): legge il contenuto di un file chiamato badfile da un buffer di lunghezza 517 byte
  2. Bof(): prende come parametro l’indirizzo del buffer precedente e ne copia il contenuto in un buffer locale

 

poiché la funzione strcpy() non controlla la lunghezza del buffer, continua a copiare il buffer di input all'interno del buffer locale andando a sovrascrivere il contenuto dello
stack sopra il buffer locale

Second Try

Il compilatore gcc implementa un meccanismo di sicurezza
chiamato Stack Guard per Prevenire buffer overflows.


In presenza di questa protezione il buffer overflow non lavora
perciò bisogna disabilitarlo compilando il programma con il
flag -fno-stack-protector

Second Try

Il nostro scopo è quello di creare il contenuto del file badfile in
modo da ottenere una shell con privilegi di root

Per ottenere ciò il nostro badfile dovrà contenere:

  1. Lo shellcode
  2. Indirizzo dello shell code


Lo shell code presente in badfile sarà copiato nello stack del
programma in modo da provocare un buffer overflow e sarà
eseguito solo se l’indirizzo di ritorno di bof contiene il suo
indirizzo. Dovrà quindi essere piazzato alla giusta distanza dall'inizio del badfile

Second Try

 

 

  1. Trovare l’indirizzo della variabile buffer[ ] nel metodo bof
     
  2. Trovare la distanza dell’indirizzo di ritorno dalla variabile buffer
     
  3. Trovare la distanza dello shell code dalla variabile buffer
     
  4. Dato 1) e 3), trovare l’indirizzo a nel quale posizionare lo shellcode
     
  5. Dato 2) e 4), inserire l’indirizzo citato sopra alla giusta distanza dall'inizio di badfile

Second Try

Per trovare l’indirizzo della variabile buffer in bof() bisogna
prima compilare una copia di stack.c usando i flag di debug

 

  • gcc -z execstack -fno-stack-protector -g -o stack_dbg stack.c
  • touch badfile
  • gdb stack_dbg
  • b bof
  • x &buffer (indirizzo di buffer)
  • x $ebp (indirizzo dell'ebp)

Second Try

Second Try

Dallo screen precedente si può vedere che l’indirizzo di buffer è
0xbffff118 mentre quello dell’ebp è 0xbffff138
Calcoliamo la distanza tra di essi...


L'indirizzo del buffer dista dall’ebp 0x20 bytes; nei sistemi a 32bit i puntatori sono lunghi 4 byte

 

Per questo motivo per arrivare all'indirizzo di ritorno bisogna sommare 4 bytes alla distanza = 0x20+4 = 0x24

Bisogna quindi aggiungere altri 4 bytes a causa dell’indirizzo di ritorno: per iniettare il nostro sarà "indirizzo" + 0x28 bytes

Second Try

Second Try

L’indirizzo di ritorno è almeno 0xbffff118 + 0x28 = 0xbffff140

Avendo runnato il programma precedente sotto gdb, ci sono
delle possibilità che lo stack frame sia alcuni bytes sfasato
rispetto alla normale esecuzione
Per incrementare le nostre chance di successo riempiamo il
nostro badfile con istruzioni NOP (una istruzione che fa
avanzare il contatore del programma all'istruzione successiva)

Inseriremo lo shellcode alla fine del file

Modifichiamo quindi il file exploit.cs

Second Try

Second Try

Aggiungeremo a exploit.cs:


*((long *) (buffer + 0x30)) = 0xbffff140;


memcpy(buffer + sizeof(buffer) - sizeof(shellcode), shellcode, sizeof(shellcode));

Second Try

Per verificare che tutto sia stato correttamente compilato:

 

  • gcc exploit.c -o exploit
  • hexdump -C badfile

Second Try

Eseguendo ora stack, precedentemente salvato coi privilegi di root, avremo:

 

Third Try

Riattiviamo la address randomization ed eseguiremo lo stesso attacco sviluppato nel primo task

Essendo dinamica l'allocazione della memoria però, il sistema non ci permette di scrivere in posizioni non idonee...

Third Try

Bisogna individuare una posizione adeguata quindi...

 

Per vedere come lavora la randomizzazione modifichiamo il
programma stack.c in modo da stampare l’indirizzo del buffer

 

Aggiungeremo: 

  • printf("%p/n", &buffer);

Third Try

... cambia in continuazione

Third Try

Per aggirare questa protezione creiamo uno script bash che
ripete all’infinito l’esecuzione dello script

Se siamo fortunati ad un certo punto avverrà una esecuzione
uguale a quella che abbiamo calcolato nello script precedente

/end

... grazie per l'attenzione.

CSLESS3

By frafolo

CSLESS3

  • 207