fbpx

Buffer Overflow – BOF

il Buffer Overflow (BOF) è una delle problematiche di sicurezza informatica più famose e note da sempre!

Un Buffer Overflow (BOF) si verifica quando il Buffer non è in grado di contenere la stringa di input per cui la memoria viene sovrascritta.

Tale evenienza comporterebbe un grave rischio per la sicurezza, in quanto un attaccante potrebbe eseguire del codice arbitrario.

In questo articolo tratteremo la memoria dei processori x86.

Le cose fondamentali da conoscere per eseguire un BOF :

  • ASSEMBLY= Linguaggio Assemblativo, spesso confuso con il termine “Assembler” e/o “Linguaggio Macchina”. Il suo scopo è semplificare il Linguaggio Macchina
  • ASSEMBLER= è un software che trasforma le istruzioni mnemoniche dell’assembly in linguaggio macchina. Si tratta dunque di un compilatore per un particolare linguaggio assembly. Vedi Wikipedia
  • CODICE BINARIO= è il inguaggio Macchina… vedi Wikipedia

Info indispensabili da conoscere:

    • STACK è una zona di memoria preposta al contenimento di dati.
    • EBP (Base Pointer) la parte iniziale dello STACK
    • ESP (Stack Pointer) un registro che contiene un indirizzo dello STACK
    • EIP (Instruction Pointer) Un puntatore all’istruzione successiva
    • PUSH Aggiunge info dallo STACK
    • POP Rimuove info dallo STACK
    • RET è un’istruzione che riassegna EBP ed EIP
    • CALL è un’istruzione che salva EIP e passa lla funzione che si intende eseguire.

Il Buffer Overflow

Letteralmente Straripamento della Memoria (più o meno). In sostanza consiste nel riempire la memoria di un’applicazione, fino a raggiungere il punto critico di contenimento dei dati, per poi sovrascriverli con del codice maligno.

Esempio:

Zona di memoria adibita al contenimento dei dati dei programmi.
Esso viene spesso paragonato ad una pila, invece a me sembra di più un semplice contenitore che raccoglie dei dati che noi possiamo depositare o prelevare al suo interno soltanto uno per volta.
Per aiutarci nell’operazione di prelevamento ed inserimento esiste un puntatore allo stack il cui compito è quello di tenere traccia della posizione corrente e permettere così di eseguire operazioni ad un “livello” specifico.

Lo stack può essere rappresentato in questo modo (secondo lo schema di Luigi Auriemma di siforge.org):

Stack

+———–+
| oggetto 0 |
| … |
| oggetto 7 |
| oggetto 8 |
| oggetto 9 |
| … |
+———–+

EBP
EBP è un registro x86, rappresenta il puntatore alla base dello stack. Serve per sapere da dove inizia la porzione di stack che stiamo utilizzando (ad esempio da dove iniziano i dati locali ad una funzione in esecuzione):

Stack

+———–+ <– EBP
| oggetto 0 |
| … |
| oggetto 7 |
| oggetto 8 |
| oggetto 9 |
| … |
+———–+

ESP
Anche ESP è un registro che contiene un indirizzo dello stack.
Mentre EBP ci ricorda da dove inizia lo stack, ESP invece ci permette di scorrerlo a nostro piacimento per prelevare od inserire dati in un punto preciso della memoria:

Stack

+———–+ <– EBP
| oggetto 0 |
| … |
| oggetto 7 |
| oggetto 8 | <– ESP
| oggetto 9 |
| … |
+———–+

EIP
Forse il registro più famoso nella sicurezza informatica. Esso è semplicemente un puntatore all’istruzione successiva, ossia ciò che la CPU dovrà eseguire subito dopo l’istruzione corrente.
EIP viene sfruttato per l’esecuzione di codice “maligno” inserito sfruttando errori di programmazione.
CALL
CALL non è un registro ma è un’istruzione che svolge sostanzialmente queste operazioni:

Salvare EIP in memoria
Saltare alla funzione che vogliamo eseguire (modificando EIP)

 
RET è un’istruzione che si preoccupa di riassegnare ad EBP ed EIP i valori precedentemente immagazzinati nello stack in occasione di una CALL.
È proprio quando viene chiamato RET che EIP può essere alterato a piacimento manipolando i dati contenuti nello stack.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *