Ci si riferisce all’esercizio precedente:
int main (void) {
char pw[8];
sprintf (pw, "root-pw");
if (authenticate(pw) > 0) {
printf ("[root]$ ...\\n);
}
else {
printf ("Root: incorrect password\\n");
}
return 0;
}
#include <stdio.h>
int authenticate (char* pw) {
int result = 0;
char buf[8];
printf ("Root Password: ");
if (gets(buf) != 0) {
if (strcmp (buf, pw) == 0) {
result = 1;
}
}
return result;
}
Non problemi:
- le variabili result e buf vengono inizializzate prima dell’uso
- logica di programmazione è ok → result ritorna 1 se e solo se l’input è uguale alla password fornita da pw
Problema:
- l’implementazione della funzione
gets non impedisce l’overflow del buffer (in questo caso buf)
Esempio: password lunga

- Dato un buffer overflow, i dati che dovrebbero stare in buf invadono lo spazio di result e possono cambiare il valore di result, sovrascrivendolo.
- Violazione dell’integrità dei dati!!!
- Variabili modificate senza un’assegnazione esplicita
⇒ in realtà i buffer overflow sono più complicati.
Ci potrebbe essere un spazio tra buf e result oppure se input è troppo lungo potrebbe addirittura intaccare ebp o return.
Difesa: ripristinare le variabili
- Aggiornare result dopo il gets (mettere un else nell’if dopo il gets e mettere result=0)
Ma non basta per scampare anche gli altri pericoli!
#include <stdio.h>
int authenticate (char* pw) {
int result = 0;
char buf[8];
printf ("Root Password: ");
if (gets(buf) != 0) {
if (strcmp (buf, pw) == 0) {
result = 1;
} else {
result=0;
}
}
return result;
}
Esempio: password molto lunga
- In questo caso va a sovrascrivere result, ebp e return (usato per tornare alla normale esecuzione del programma terminata l’esecuzione della funzione)
- La chiamata a return ritorna 47 11 47 11, facendo ripartire l’esecuzione in questa posizione della memoria
- L’overflow ha distrutto l’integrità del flusso del codice!

Codici di exploit - dove i malitenzionati fanno saltare il programma
I malintenzionati posizionano il loro codice exploit (dannoso) nella memoria durante attacchi di overflow di buffer. Alcuni punti chiave includono:
- Destinazione del salto: L'obiettivo principale di un attaccante potrebbe essere il codice che crea una shell, spesso privilegiata. Questo consente loro di ottenere un accesso più ampio al sistema.
- Posizionamento del codice di exploit: Un approccio comune è collocare il codice di exploit nello stack, spesso all'interno del buffer che è soggetto all'overflow. L'indirizzo di ritorno deve essere accuratamente selezionato per puntare al punto di ingresso del codice di exploit.