¡Tu mensaje de bienvenida, twitter o publicidad aquí!

| Suscríbete vía RSS

19 abr. 2010

Adress space layout randomization

| |

Introducción


Más conocida como ASLR, es una técnica de seguridad que se viene encargando de la aleatorización de direcciones de memoria. De forma que no podamos predecir cuál será la dirección de retorno de un determinado buffer o de cualquier otra dirección que se encuentre en la pila.

Esto complica la tarea de cualquier atacante que intente ejecutar un ataque de return-to-libc que tendrá que buscar el código a ejecutar, o aquellos que traten de ejecutar una shellcode, deberán primero averiguar dónde se encuentra la pila.

¿Cómo funciona?


Para demostrar el funcionamiento vamos a utilizar el siguiente código.Que compilaremos utilizando la opción -ggdb:

$ gcc -ggdb -o Prueba Prueba.c

/tmp/ccCPLK8V.o: In function `main':
/home/sebas/Lab/Ensamblador/Prueba.c:19: warning: the `gets' function is dangerous and should not be used.


El mensaje de aviso, es para indicarnos que la función gets es peligrosa y no debería ser utilizada, esto es debido a que no estamos controlando en ningún momento la longitud que vamos a introducirle y podríamos provocar un buffer overflow.

Si ejecutamos la aplicación y hacemos un grep por el nombre de esta para que nos muestre información del proceso, obtenemos la siguiente información:

$ ps -aux | grep Prueba
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
sebas 11777 0.0 0.0 1656 328 pts/0 S+ 00:32 0:00 ./Prueba 10 40
sebas 11783 0.0 0.0 3352 812 pts/1 S+ 00:32 0:00 grep Prueba


El PID es el 11777, ahora podemos buscarlo en la carpeta /proc y mostrar por pantalla cómo está organizada la memoria para permitir la ejecución de la aplicación:

$ cat /proc/11777/maps
08048000-08049000 r-xp 00000000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
08049000-0804a000 r-xp 00000000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
0804a000-0804b000 rwxp 00001000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
b75ac000-b75ad000 rwxp b75ac000 00:00 0
b75ad000-b7709000 r-xp 00000000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b7709000-b770a000 ---p 0015c000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b770a000-b770c000 r-xp 0015c000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b770c000-b770d000 rwxp 0015e000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b770d000-b7710000 rwxp b770d000 00:00 0
b7722000-b7725000 rwxp b7722000 00:00 0
b7725000-b7726000 r-xp b7725000 00:00 0 [vdso]
b7726000-b7742000 r-xp 00000000 08:09 65422 /lib/ld-2.9.so
b7742000-b7743000 r-xp 0001b000 08:09 65422 /lib/ld-2.9.so
b7743000-b7744000 rwxp 0001c000 08:09 65422 /lib/ld-2.9.so
bfaad000-bfac2000 rw-p bffeb000 00:00 0 [stack]


El segmento de direcciones donde se encuentra nuestra pila es bfaad000-bfac2000 y el offset es bffeb000. Si probamos ahora a repetir el mismo proceso (ejecutando la aplicación y averiguando su respectivo PID) obtenemos el siguiente resultado.

$ cat /proc/13372/maps
08048000-08049000 r-xp 00000000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
08049000-0804a000 r--p 00000000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
0804a000-0804b000 rw-p 00001000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
b7668000-b7669000 rw-p b7668000 00:00 0
b7669000-b77c5000 r-xp 00000000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b77c5000-b77c6000 ---p 0015c000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b77c6000-b77c8000 r--p 0015c000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b77c8000-b77c9000 rw-p 0015e000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b77c9000-b77cc000 rw-p b77c9000 00:00 0
b77de000-b77e1000 rw-p b77de000 00:00 0
b77e1000-b77e2000 r-xp b77e1000 00:00 0 [vdso]
b77e2000-b77fe000 r-xp 00000000 08:09 65422 /lib/ld-2.9.so
b77fe000-b77ff000 r--p 0001b000 08:09 65422 /lib/ld-2.9.so
b77ff000-b7800000 rw-p 0001c000 08:09 65422 /lib/ld-2.9.so
bfeed000-bff02000 rw-p bffeb000 00:00 0 [stack]


El segmento donde se encuentra nuestra pila ha cambiado, teniendo ahora el valor de bfeed000-bff02000, lo que se mantiene igual es el valor del offset a bffeb000.

Este hecho viene provocado por la variable del sistema randomize-va-space, que nos permite especificar al sistema el tipo de aleatorización a utilizar, donde:

  • value 0 - Desactiva la aleatorización del espacio de direcciones ocupado por el proceso. Se establece por defecto en aquellos sistemas que no soportan esta característica o son iniciados con el parámetro norandmaps

  • value 1 - Asigna direcciones de memorias aleatorias a mmap base, stack y VDSO page. Entre otras cosas las librerías compartidas son cargadas en direcciones al azar, incluyendo también los binarios de PIE-enlazados y el inicio de ejecución de la aplicación. Se establece por defecto si la opción CONFIG_COMPAT_BRK está activada.

  • value 2 - Adicionalmente habilita la aleatorización del montículo (heap). Se establece por defecto si la opción CONFIG_COMPAT_BRK está desactivada.



Para ver el valor que tenemos asignado basta con: cat /proc/sys/kernel/randomize_va_space y si quieres cambiarla: echo valor_numerico > /proc/sys/kernel/randomize_va_space

Quizás sea oportuno comentar que existen varias formas de saltarse este tipo de protección a día de hoy, y que confiar plenamente en ello puede generarnos una falsa sensación de seguridad que podría ocasionarnos algún que otro disgusto. También se pondrá en duda esa aleatoriedad a la hora de generar los segmentos de memoria, donde comprobaremos que realmente sólo 3 bytes de los 4 que componen nuestra dirección sufrirán variación alguna, provocando que de los 32 bits que esta ocupa, tan sólo sean 24 los que sufren el cambio. Pero de eso hablaremos en otra entrada, hoy sólo vamos a mostrar en qué consiste.

0 comentarios: