#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
volatile int (*fp)();
char buffer[64];
fp = 0;
gets(buffer);
if(fp) {
printf("calling function pointer, jumping to 0x%08x\n", fp);
fp();
}
}
C
win
, tuttavia notiamo che non è raggiungibile da nessuna parte del codice, non vi è nessuna chiamata alla funzione win
fp
, che viene inizializzato a 0 e su cui viene fatto un controllo. Per entrare nell'if
il valore di fp
deve essere diverso da 0. All'interno vi è una stampa che ci comunica l'indirizzo corrente di fp
. Quello che dobbiamo fare è sovrascrivere tale puntatore a funzione, facendolo puntare a win
.Proviamo una esecuzione riempiendo il buffer con un valore qualsiasi, per esempio delle 'A', per fare ciò usiamo python:
come potevamo prevedere, riempiendo il buffer si riesce ad accedere al puntatore a funzione, il cui valore viene sovrascritto con il valore esadecimale (in ASCII) della 'A', ovvero 0x61.
A questo punto sappiamo che dobbiamo replicare tale stampa aggiungendo al posto della 'A' un indirizzo, quello della funzione win
win
?Usiamo gdb
per stampare l'indirizzo della funzione win
:
Tale indirizzo dobbiamo passare in formato little endian al programma.
Creiamo l'exploit:
i dati da passare al programma verranno scritti in un file.
Il programma non prende in input dei file, per cui, effettuiamo una lettura del file con cat
e passiamo il suo output al programma target:
Ovviamente prima di effettuare la lettura del file exploit
abbiamo eseguito l'exploit python per generare il file.