Format Strings
Información Básica
En C printf
es una función que se puede usar para imprimir alguna cadena. El primer parámetro que esta función espera es el texto en bruto con los formateadores. Los siguientes parámetros esperados son los valores para sustituir los formateadores del texto en bruto.
Otras funciones vulnerables son sprintf()
y fprintf()
.
La vulnerabilidad aparece cuando un texto del atacante se usa como el primer argumento para esta función. El atacante podrá crear una entrada especial abusando de las capacidades de la cadena de formato printf para leer y escribir cualquier dato en cualquier dirección (legible/escribible). De esta manera, podrá ejecutar código arbitrario.
Formateadores:
Ejemplos:
Ejemplo vulnerable:
Uso Normal:
Con argumentos faltantes:
fprintf vulnerable:
Accediendo a Punteros
El formato %<n>$x
, donde n
es un número, permite indicar a printf que seleccione el n-ésimo parámetro (de la pila). Así que si quieres leer el 4º parámetro de la pila usando printf, podrías hacer:
y leerías del primer al cuarto parámetro.
O podrías hacer:
y leer directamente el cuarto.
Nota que el atacante controla el parámetro pr
intf
, lo que básicamente significa que** su entrada estará en la pila cuando se llame a printf
, lo que significa que podría escribir direcciones de memoria específicas en la pila.
Un atacante que controle esta entrada, podrá agregar direcciones arbitrarias en la pila y hacer que printf
las acceda. En la siguiente sección se explicará cómo usar este comportamiento.
Lectura Arbitraria
Es posible usar el formateador %n$s
para hacer que printf
obtenga la dirección situada en la n posición, siguiéndola y imprimirla como si fuera una cadena (imprimir hasta que se encuentre un 0x00). Así que si la dirección base del binario es 0x8048000
, y sabemos que la entrada del usuario comienza en la 4ª posición en la pila, es posible imprimir el inicio del binario con:
Tenga en cuenta que no puede poner la dirección 0x8048000 al principio de la entrada porque la cadena se cortará en 0x00 al final de esa dirección.
Encontrar el desplazamiento
Para encontrar el desplazamiento a su entrada, podría enviar 4 u 8 bytes (0x41414141
) seguidos de %1$x
y aumentar el valor hasta recuperar los A's
.
Last updated