Format Strings
Informazioni di Base
In C printf
è una funzione che può essere utilizzata per stampare una stringa. Il primo parametro che questa funzione si aspetta è il testo grezzo con i formattatori. I parametri successivi previsti sono i valori da sostituire ai formattatori nel testo grezzo.
Altre funzioni vulnerabili sono sprintf()
e fprintf()
.
La vulnerabilità si manifesta quando un testo dell'attaccante viene utilizzato come primo argomento per questa funzione. L'attaccante sarà in grado di creare un input speciale sfruttando le capacità della stringa di formato printf per leggere e scrivere qualsiasi dato in qualsiasi indirizzo (leggibile/scrivibile). Essendo in grado in questo modo di eseguire codice arbitrario.
Formattatori:
Esempi:
Esempio vulnerabile:
Uso Normale:
Con argomenti mancanti:
fprintf vulnerabile:
Accesso ai Puntatori
Il formato %<n>$x
, dove n
è un numero, consente di indicare a printf di selezionare il parametro n (dallo stack). Quindi, se si desidera leggere il 4° parametro dallo stack utilizzando printf, si potrebbe fare:
e dovresti leggere dal primo al quarto parametro.
Oppure potresti fare:
e leggere direttamente il quarto.
Si noti che l'attaccante controlla il parametro pr
intf
, il che significa fondamentalmente che il suo input sarà nello stack quando viene chiamato printf
, il che significa che potrebbe scrivere specifici indirizzi di memoria nello stack.
Un attaccante che controlla questo input sarà in grado di aggiungere un indirizzo arbitrario nello stack e far sì che printf
vi acceda. Nella sezione successiva verrà spiegato come sfruttare questo comportamento.
Lettura Arbitraria
È possibile utilizzare il formato %n$s
per fare in modo che printf
ottenga l'indirizzo situato nella posizione n, seguendolo e stampandolo come se fosse una stringa (stampando fino a trovare un 0x00). Quindi se l'indirizzo base del binario è 0x8048000
, e sappiamo che l'input dell'utente inizia nella quarta posizione nello stack, è possibile stampare l'inizio del binario con:
Nota che non puoi inserire l'indirizzo 0x8048000 all'inizio dell'input perché la stringa verrà concatenata con 0x00 alla fine di quell'indirizzo.
Trova l'offset
Per trovare l'offset del tuo input, potresti inviare 4 o 8 byte (0x41414141
) seguiti da %1$x
e aumentare il valore fino a recuperare gli A's
.
Last updated