Sto cercando di saperne di più sulla vulnerabilità di printf. Capisco la teoria ma non riesco a metterla in pratica.
TL; DR
Tutti i miei tentativi di scrivere un singolo byte in memoria provocano un errore di segmentazione.
Qual è la ragione più probabile per l'errore? La mia ipotesi è che potrebbe essere una sorta di protezione nei moderni compilatori / OS (sto lavorando su Ubuntu Xenial a 64 bit), ma non ne so molto.
Dettagli
Sono in grado di leggere lo stack. Ho scoperto che la chiamata che sto cercando di sfruttare mette 6 * 4 byte davanti al mio input:
Your choice: AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x
You entered: AAAA.00000001.00000005.f76c7d60.0000000a.09787008.ff9c9e48.41414141
Ho disassemblato il file binario e ho trovato la posizione (i) di memoria che voglio cambiare. Ho provato vari indirizzi, sia codice che dati con lo stesso risultato. Ad esempio, l'indirizzo della stringa La tua scelta: è 0x0804b795
.
$ gdb -batch -ex "x/s 0x0804b795" ./a.out
0x804b795: "Your choice: "
Sono in grado di scrivere quell'indirizzo nel payload:
$ echo "the binary ignores the 1st line" > ./payload
$ echo $(printf "\x95\xb7\x04\x08").%08x.%08x.%08x.%08x.%08x.%08x.%08x >> ./payload
$ cat payload - | ./a.out
Your choice: You entered: ?.00000001.00000005.f76f5d60.0000000a.09844008.ff8ff1d8.0804b795
Quindi sostituisco l'ultima %08x
con %n
per scrivere in quell'indirizzo. Il numero di caratteri stampati sarà 4 (per l'indirizzo) + 6 * 8 (imbottito% x) + 7 (punti) = 59 che inserisce il valore da scrivere nell'intervallo ASCII; 59 rappresenta il punto e virgola - un carattere adatto per scrivere in una stringa.
$ echo "the binary ignores the 1st line" > ./payload
$ echo $(printf "\x95\xb7\x04\x08").%08x.%08x.%08x.%08x.%08x.%08x.%n >> ./payload
$ cat payload | ./a.out
Per quanto ne so, dovrebbe funzionare e speravo di vedere ; la nostra scelta sulla prossima iterazione, ma sto ottenendo
Your choice: You entered:
Segmentation fault
Per confermare:
$ gdb a.out
(gdb) run < payload
Your choice: You entered:
Program received signal SIGSEGV, Segmentation fault.
0xf7e58dff in vfprintf () from /lib32/libc.so.6
(gdb) bt
#0 0xf7e58dff in vfprintf () from /lib32/libc.so.6
#1 0xf7e5df66 in printf () from /lib32/libc.so.6
#2 0x080487b4 in getInput ()
#3 0x0804b206 in programMain ()
#4 0x0804b3b0 in main ()
Cosa mi manca? Cos'altro posso controllare?