Format Strings
Información Básica
En C printf
es una función que se puede utilizar para imprimir una cadena. El primer parámetro que esta función espera es el texto sin formato con los formateadores. Los parámetros siguientes esperados son los valores para sustituir los formateadores del texto sin formato.
Otras funciones vulnerables son sprintf()
y fprintf()
.
La vulnerabilidad aparece cuando un texto del atacante se utiliza como el primer argumento de esta función. El atacante podrá crear una entrada especial abusando de las capacidades de las cadenas de formato printf para leer y escribir cualquier dato en cualquier dirección (legible/inscriptible). De esta manera, puede ejecutar código arbitrario.
Formateadores:
Ejemplos:
Ejemplo vulnerable:
Uso Normal:
Con Argumentos Faltantes:
Vulnerabilidad de fprintf:
Accediendo a Punteros
El formato %<n>$x
, donde n
es un número, permite indicar a printf que seleccione el parámetro n (de la pila). Por lo tanto, si deseas leer el cuarto parámetro de la pila usando printf, podrías hacer lo siguiente:
y leerías desde el primer hasta el cuarto parámetro.
O podrías hacer:
y lee directamente el cuarto.
Ten en cuenta 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 utilizar este comportamiento.
Lectura Arbitraria
Es posible utilizar el formateador %n$s
para hacer que printf
obtenga la dirección situada en la posición n, siguiéndola e imprimiéndola como si fuera una cadena (imprimir hasta encontrar un 0x00). Entonces, si la dirección base del binario es 0x8048000
, y sabemos que la entrada del usuario comienza en la cuarta posición en la pila, es posible imprimir el inicio del binario con:
Ten en cuenta que no puedes poner la dirección 0x8048000 al principio de la entrada porque la cadena se concatenará con 0x00 al final de esa dirección.
Encontrar el desplazamiento
Para encontrar el desplazamiento de tu entrada, podrías enviar 4 u 8 bytes (0x41414141
) seguidos de %1$x
y aumentar el valor hasta recuperar las A's
.
Última actualización