19 abril 2012

Mitigaciones de seguridad en EMETv2.1 (III de III)

Mitigaciones de seguridad en EMETv2.1 (I de III)
Mitigaciones de seguridad en EMETv2.1 (II de III)

Heap Spray

Es una técnica que consiste en copiar una shellcode muchas veces en memoria. Persigue como objetivo aumentar la probabilidad de éxito en la ejecución de la shellcode, debido a la dificultad que existe en conocer de antemano la posición exacta de la misma. Normalmente se hace uso de JavaScript o Flash para este fin.

EMET mitiga esta técnica preasignando las páginas de memoria virtual más utilizadas, lo cual evita que se pueda escribir la shellcode.



NULL page allocation

Mitigación que persigue como objetivo evitar problemas de seguridad con las referencias a NULL. Para conseguir este fin EMET preasigna la dirección 0x00000000.


EAF

Para comprender esta mitigación es necesario saber que Export Address Table (EAT) es un vector de punteros que contiene las direcciones de las funciones exportadas.

Existen shellcodes estáticas y dinámicas. Las primeras utilizan direcciones de memoria hardcodeadas, pero el problema es que éstas suelen cambiar con diferentes versiones de núcleos, idiomas, etc; amen de la dificultad de explotación si se usa ASLR. El hardcoding disminuye el nivel de éxito de ejecución de una shellcode. En cambio las shellcode dinámicas llaman a APIs de Windows, pero previamente deben obtener su dirección y para esto recorren la EAT de los módulos cargados. El comportamiento por defecto de la mayoría de las shellcodes es obtener la dirección base de kernel32.dll y después la del API GetProcAddress (y también LoadLibrary). Mediante ésta se obtiene la dirección de otras funciones.

Mediante EAF se filtra el acceso a la EAT de los módulos ntdll.dll y kernel32.dll permitiéndolo o denegándolo basándose en el código que intenta acceder. Para esto se usan puntos de ruptura hardware para interceptar operaciones de lectura, y Vectored Exception Handler para comprobar si la dirección origen del código que intenta acceder pertenece a un módulo. Cuando el punto de ruptura salta debido al acceso a EAT, EAF determina si el código que está accediendo es legítimo del proceso o malicioso que ha sido inyectado en el proceso mediante un exploit. Si detecta que es malicioso, entonces termina el proceso.

Para que la mitigación EAF funcione, EMET crea un nuevo hilo en el proceso. Por lo tanto no se aplica inmediatamenteal iniciarse, tarda unos milisegundos. Es importante recalcar que es una mitigación útil para prevenir la ejecución de la mayoría de las shellcodes, pero es relativamente fácil de evitar.

Existen varias formas de bypassear EAF:

  • EAF comprueba la localización de la instrucción que accede a EAT permitiendo su acceso si está dentro del segmento de código; sino termina el proceso. Por lo tanto se podría hacer que la shellcode usara instrucciones del segmento de código de un módulo cargado para leer memoria, de forma que se invoque desde la shellcode para leer EAT. En este caso el acceso pasaría como legítimo, aún habiendo sido invocado por la shellcode. Esto está explicado con mayor detalle en este enlace.

  • Como aquí se comenta, una forma de desactivar la protección EAF es poner a cero los registros debug del procesador mediante SEH, inhibiendo así los puntos de ruptura hardware. Esto sólo funciona si no tenemos activo /SAFESEH. Un ejemplo de código para inhibir EAF borrando el contenido de los registros debug sería éste. En vez de utilizar SEH para esto, hace uso de llamadas al sistema. Al utilizar syscalls no hace falta averiguar la dirección de memoria de una función accediendo a EAT, lo cual denegaría EAF. Tiene como inconveniente que no es portable, ya que el número de llamada al sistema puede cambiar con el Service Pack, etc. De hecho se advierte en el texto.


BottomUpRand

Utiliza 8 bits de entropía para aleatorizar la dirección base de diferentes secciones como stack, heap y otros. Esto permite incrementar la entropía de la dirección base de las DLLs, pasando de 15 a más de 200.

Mandatory ASLR preasigna la dirección base preferida de una DLL para forzar que se cargue en otra dirección. Si la dirección base está asignada, a esto se le llama DLL collided, y ahí es donde entra en juego Bottom Up Randomization.

Esta mitigación funciona reservando un número entre 0 y 256 de bloques de 64K mediante VirtualAlloc. Esto consume una porción de la parte más baja del espacio de direcciones. Windows asigna la dirección base de DLLs que colisionan buscando una región libre en en la parte más baja del espacio de direcciones, por lo tanto Bottom Up asegura que la dirección asignada sea aleatoria. Si no se hace uso de esta técnica de mitigación la parte más baja permanece prácticamente estática.


Artículo cortesía de David Montero