29 marzo 2012

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

Introducción

EMET es una herramienta que mejora la protección de aplicaciones de terceros y binarios propios de Windows mediante siete técnicas de mitigación. Funciona inyectando una DLL (de 32 o 64 bits) en cada proceso de la aplicación protegida.

En este texto se habla varias veces de compilar con un cierto flag los fuentes de una aplicación. Aunque se utiliza ese término, la fase exacta sería la de enlazado y no de compilación.

Mitigaciones de seguridad


- DEP

Solución hardware y software para prevenir la ejecución de código en páginas de memoria que que no han sido marcadas explícitamente como ejecutables, ya que típicamente se usan para datos (stack, heap). Para esto marca como no ejecutables la pila y el heap, de forma que cualquier intento de ejecución de código en estas zonas será denegado a nivel de procesador. Para utilizar DEP la CPU debe soportar la desactivación de ejecución (XD en Intel y NX en AMD).

En principio sólo se podía hacer uso de DEP si una aplicación había sido compilada con el flag correspondiente /NXCOMPAT. EMET posibilita su uso sin necesidad de recompilar la aplicación; para esto llama a SetProcessDEPPolicy desde el proceso en cual se inyectó la DLL de EMET. En CPUs de 64 bits sobre Windows de 64 bits siempre está activo y no se puede desactivar. Por lo tanto si se invoca a SetProcessDEPPolicy en estas CPUs se produce un fallo.

Se puede evadir mediante una técnica llamada return-to-libc, en la cual se sobreescribe la pila para apuntar a código de librerías (por ejemplo, system en glibc). En este caso no se ejecuta código en la propia pila, y por eso se puede bypassear. Sucede algo parecido con la técnica ROP, donde tampoco se busca ejecutar código en la pila.

Para realizar la técnica ROP es necesario tener el control de la pila. La idea es aprovechar pequeños trozos de código (instrucciones) que ya están en memoria para construir el payload deseado. Para ello se escriben en la pila las direcciones de las instrucciones que interesan. A esto se le llama ROP-gadgets. Éstas instrucciones se ejecutan sin problemas, ya que están ubicadas en páginas de memoria marcadas con permisos de ejecución (NX=0). Finalmente se escribe la shellcode en una zona ejecutable, que previamente estaba en la pila, y se salta a ella. Se puede escribir sobre la sección de código en JIT, ya que requiere que los permisos que se utilicen sean rwx. Sino, se puede hacer uso de VirtualAlloc para establecer todos los permisos o dar permisos de ejecución con VirtualProtect.

Se podría hacer que todo el exploit funcionara a base de ROP puramente, pero típicamente se hace uso de él solo durante la primera fase. Es decir, se persigue como objetivo ejecutar el código que hemos copiado en la pila y no construirlo mediante ROP-gadgets.

Visto que existen técnicas para evitar DEP, es conveniente además hacer uso de otras técnicas de mitigación (ASLR, SHEOP, MIC) para convertirlo en realmente efectivo. Por ejemplo, mediante ASLR el atacante no podrá encontrar las posiciones de memoria donde están situados los ROP-gadgets.

DEP se puede configurar de cuatro maneras diferentes:

  • optIn: sólo afecta a binarios de Windows y a aplicaciones que explícitamente lo indiquen. Los binarios de 64 bits son la excepción, ya que siempre serán protegidos a menos que se indique lo contrario mediante optOut.

  • optOut: afecta a todos los binarios, tanto de Windows como de terceros. Se puede indicar explícitamente que algunos binarios no se vean afectados.

  • AlwaysOn: se aplica a todo el sistema haciendo caso omiso de las excepciones optOut.

  • Disabled: se desactiva totalmente haciendo caso omiso de las excepciones optIn.


- ASLR

En Windows los ejecutables (EXE y DLL) en principio se cargan en memoria en la dirección base establecida en tiempo de compilación que consta en el propio fichero. Para prevenir la explotación de vulnerabilidades mediante ASLR se aleatoriza esta dirección, de forma que no se utiliza la indicada en el ejecutable.

Es necesario distinguir dos implementaciones de ASLR. La que realiza el propio Windows trabaja con módulos que han sido compilados con un flag específico (IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE), y aleatoriza la dirección base con hasta 256 posibilidades. La segunda implementación es la ofrecida por EMET donde no se necesario indicar nada en tiempo de compilación, y por lo tanto no hace falta recompilar la aplicación. Esto es, si un ejecutable no soporta ASLR de forma nativa, mediante EMET se asigna la dirección de memoria base donde se carga el ejecutable de forma que el cargador de imágenes tenga que buscar una nueva dirección. A esto se le llama Mandatory ASLR (pseudo-ASLR), y tiene una menor entropía que ASLR real: 4 bits frente a 8 en ASLR nativo.

Mandatory ASLR usado conjuntamente con la técnica de mitigación Bottom Up Randomization, implementado en la versión 2.1 de EMET, ofrece una gran protección. La entropía obtenida es la misma que con ASLR real, y además la dirección base cambia cada vez que se inicia la aplicación. Con ASLR nativo esto no ocurre, y además es necesario un reinicio.

En EMET la mitigación Mandatory ASLR fuerza la relocalización de DLLs que han sido cargadas posteriormente a EMET.DLL. Por lo tanto no se aleatoriza con EMET ni la propia imagen core ni las librerías estáticas empotradas en él. Cuando EMET se carga hace un hook a LdrLoadDll y comprueba por cada módulo que se vaya a cargar el bit IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE. Si no está presente implica que la DLL no ha sido enlazada con el flag ASLR, por lo tanto se fuerza pseudo-ASLR preasignando una página de la dirección base para que el operativo la cargue en otra dirección.

Para comprobar si EMET está funcionando correctamente con ASLR podemos usar Process Explorer de la suite Sysinternals. Primero hay que tener en cuenta que los módulos que marca como ASLR son los que han sido compilados específicamente para ello; es decir, aquellos con los que trabaja Windows y no EMET. Para poder ver los que EMET ha forzado la relocalización hay que ir a Options-Configure Colors y activar Relocated DLLs. Después indicaremos que queremos que se muestren las DLLs mediante View-Show Lower Pane y finalmente View-Lower Pane View-DLLs. Entonces al pinchar sobre un proceso protegido con ASLR en EMET, si no utiliza DLLs compiladas con dynamic base, veremos que han sido relocalizadas mediante EMET (las mostrará de amarillo si se utiliza el color por defecto).

Artículo cortesía de David Montero  

2 comments :

Moxilo dijo...

Felicidades por la entrada, esta muy trabajada. Ahora a leer la segunda parte que ya esta disponible.

damontero dijo...

Me alegro que te haya gustado esta parte y también la segunda. Quedan dos por publicar así que disfrútalas :)





Un saludo