Buffer Overflows y protección del kernel: práctica (II)

Para acabar con esta serie de entradas sobre los ataques de buffer overflow, y una vez explicadas las bases, vamos a ejecutar el programa que vimos en la entrada anterior varias veces, para ver cual es la posición del EPI (dirección de la siguiente línea a ejecutar):

user1@base:~/Desktop> for i in `seq 1 5`; do ./prueba | grep Premio; done
Premio: Valor: 0x29 PosMem: 0xBFFFF04C
Premio: Valor: 0x29 PosMem: 0xBFFFF04C
Premio: Valor: 0x29 PosMem: 0xBFFFF04C
Premio: Valor: 0x29 PosMem: 0xBFFFF04C
Premio: Valor: 0x29 PosMem: 0xBFFFF04C

¡Madre mía! ¡Es la misma dirección todas las veces que se ejecuta! Seguramente muchos estarán viendo la peligrosidad de esto, y por ello en el kernel 2.6 se creó una protección llamada “Virtual Address Space Randomization” que se encarga de asignar distintas posiciones de memoria a los procesos cada vez que se ejecuten. Para habilitarlo (por defecto esta habilitado) hay que asignar el valor 1 al fichero “randomize_va_space“:

base:~ # echo 1 > /proc/sys/kernel/randomize_va_space

Ahora ejecutaremos el programa a ver que ocurre:

user1@base:~/Desktop> for i in `seq 1 5`; do ./prueba | grep Premio; done
Premio: Valor: 0x29 PosMem: 0xBFF71FBC
Premio: Valor: 0x29 PosMem: 0xBF8A20EC
Premio: Valor: 0x29 PosMem: 0xBFD50D9C
Premio: Valor: 0x29 PosMem: 0xBF9D721C
Premio: Valor: 0x29 PosMem: 0xBFBDE42C

Como vemos, ahora se emplean distintas direcciones de memoria cada vez que se ejecuta el mismo proceso, lo que dificulta enormemente la ejecución de ataques de buffer overflow en entornos con sistemas operativos Linux 2.6.

Esto se realiza mediante una función de generación de posiciones aleatorias prf(s, j + p), a la cual se le pasan 3 valores: el IP de la pila (secure_ip_id) que cambia cada segundo (parámetro s), el jiffies del reloj que normalmente es 4ms (parámetro j), y el pid del proceso actual (parámetro p). Como vemos esta es una medida realmente efectiva contra los desbordamientos de buffer, que junto con otras protecciones como las que incluye el GCC está dificultando cada vez más la aparición de estos ataques.

Por desgracia, a principio de año Hagen Fritsch presentó en la Blackhat europea 2009 un algoritmo que permitía predecir de forma local el salto, y de esta forma romper el “ Virtual Address Space Randomization” [véase la entrada en su blog]. La probabilidad teórica de acertar es de 1/2.5, y se puede predecir hasta pasados dos minutos la ejecución del programa.

Aunque no se sabe muy bien todavía cómo puede llegar a afectar esto a la seguridad del kernel, puesto que es explotable de forma local, sí es cierto que están apareciendo ya las primeras herramientas que permiten predecir el salto. Estaremos atentos a la evolución de esta protección.

Comments

  1. Me ha gustado mucho esta versión más técnica de este blog. Felicidades Ximo, impresionante.