Format Strings
Basic Information
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 seguenti attesi sono i valori da sostituire ai formattatori nel testo grezzo.
Altre funzioni vulnerabili sono sprintf()
e fprintf()
.
La vulnerabilità appare quando un testo dell'attaccante viene utilizzato come primo argomento per questa funzione. L'attaccante sarà in grado di creare un input speciale abusando delle capacità della stringa di formato printf per leggere e scrivere qualsiasi dato in qualsiasi indirizzo (leggibile/scrivibile). Essere in grado in questo modo di eseguire codice arbitrario.
Formatters:
Esempi:
Esempio vulnerabile:
Uso Normale:
Con argomenti mancanti:
fprintf vulnerabile:
Accessing Pointers
Il formato %<n>$x
, dove n
è un numero, consente di indicare a printf di selezionare il n-esimo parametro (dallo stack). Quindi, se vuoi leggere il 4° parametro dallo stack usando printf, potresti fare:
e potresti leggere dal primo al quarto parametro.
Oppure potresti fare:
e leggere direttamente il quarto.
Nota 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 indirizzi di memoria specifici nello stack.
Un attaccante che controlla questo input sarà in grado di aggiungere indirizzi arbitrari nello stack e far accedere printf
a essi. Nella sezione successiva verrà spiegato come utilizzare questo comportamento.
Lettura Arbitraria
È possibile utilizzare il formattatore %n$s
per far sì che printf
ottenga l'indirizzo situato nella n posizione, seguendolo e stamparlo come se fosse una stringa (stampa fino a quando non viene trovato 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 mettere l'indirizzo 0x8048000 all'inizio dell'input perché la stringa sarà tagliata a 0x00 alla fine di quell'indirizzo.
Trova l'offset
Per trovare l'offset per il tuo input puoi inviare 4 o 8 byte (0x41414141
) seguiti da %1$x
e aumentare il valore fino a recuperare le A's
.
Last updated