jueves, 18 de enero de 2018

DLL Hijacking: Aprendiendo los conceptos básicos

Compartir este artículo:
Hace un tiempo estuve leyendo el libro Gray Hat Python de Justin Seitz, recomendable, así que dejo el enlace al libro en Amazon. En él se explican cosas bastante interesantes, entre otras se puede ver cómo crear un debugger básico para Windows o cómo hacer una inyección de shellcode o DLL en un proceso.

Esta última tarea, la inyección de DLL en un proceso es de la que voy a hablar en este post. Os dejo una definición de la Wikipedia:

DLL injection es una técnica utilizada para ejecutar lenguaje de máquina dentro del espacio de direcciones de otro proceso forzándolo a cargar una biblioteca de enlace dinámico.”
Antes de empezar hay que tener en cuenta lo siguiente:

·       Se hace uso de Python 3 (usar versión de 32 bits para inyecciones de 32 y la de 64 para la correspondiente)
·       DLL de 32 bits para aplicaciones de 32 bits
·       DLL de 64 bits para aplicaciones de 64 bits
·       Uso de Process Hacker para ver información del proceso objetivo
·       Yo uso Windows 10

Se muestra a continuación el código por partes. Empecemos:


La primera parte no tiene mucho que explicar. Vemos que se comprueba la versión de Python que está corriendo (para saber si es de 32 bits o 64 bits), se hace uso de argparse par los 2 argumentos que necesitamos, PID del proceso y ruta de la DLL. Al final se ve la definición de 3 constantes:
·       PAGE_READWRITE: sirve para establecer un acceso de lectura y escritura.
·       PROCESS_ALL_ACCESS: todos los accesos posibles al proceso.
·       COMMIT_RESERVE: para reservar espacio en las direcciones virtuales, asegurándonos de que al acceder el contenido esté en 0.

Continuamos con más código:



Vemos como cargamos un “envoltorio” a través del objeto windll, que nos permitirá acceder a las funciones de la librería kernel32, acto seguido manejamos los parámetros recibidos al llamar al script y comprobamos si la dll existe con la función isfile. Vemos que se obtiene la longitud de la ruta de la dll, es necesario para reservar la memoria en los siguientes pasos.
Se llama a la función OpenProcess, que si va bien, nos devolverá un manejador al proceso, si no tendremos un NULL y salimos. El prototipo de la función es el siguiente:


Se procede a llamar a VirtualAllocEx, si se procesa con éxito, se devolverá la región de memoria asignada, si no NULL y salimos. El prototipo a continuación:


Ya estamos llegando al final, penúltima parte del código:


Se hace la llamada a WriteProcessMemory, si falla devolverá 0, y si no un valor distinto a 0. Y su prototipo es:


Se obtiene la dirección de memoria de la función “LoadLibraryA”, si todo va bien seguimos, si no salimos, no tiene sentido seguir. Y pasamos a la última parte del código:


Aquí lo primero que hacemos es crear un tipo de datos que se va a necesitar para definir los tipos de argumentos de la función, LPSECURITY_ATTRIBUTES, se trata de una estructura de C, y que tiene 3 campos. Acto seguido, se definen los tipos que se le van a pasar a la función CreateRemoteThread (podemos ver la estructura, aunque la dejaremos como None), si no hacemos esto, en la versión de 64 bits fracasaremos , y finalmente se llama a la función, y si va como esperamos, devolverá un manejador al nuevo hilo, si no devolverá NULL. El prototipo de la función es como sigue:


Para hacer la primera prueba, yo tengo un XAMPP de 32 bits corriendo, voy a utilizar la herramienta Process Hacker para obtener el PID, aquí también se podría hacer uso del administrador de tareas:


Ahora ejecutamos el script, en mi PC tengo instalada tanto la versión de 32 bits, como la de 64 bits (en la PATH).


Vemos que se ha podido inyectar la DLL en el proceso con PID 5128, si ahora hacemos uso de Process Hacker, click derecho del ratón en nuestro proceso objetivo, y damos en Properties, ahí vamos a la pestaña Modules, y buscamos la DLL inyectada. (Nota: en esta prueba se utilizo una versión antigua del script, que solo corría en 32 bits).
La segunda prueba es para 64 bits, y hago uso de Android Studio:


Si se mira en Process Hacker, se ve la DLL de Python inyectada, se deja a continuación una captura, ya que en la otra prueba no se mostró:



Para jugar puedes crear tu propia DLL, consulta la siguiente página de Microsoft, por ejemplo, en el caso de DLL_PROCESS_ATTACH, puedes escribir:
            MessageBox(0, "Flu-project!", "DLL Injected…", 0);
            break;

Es posible que en algunos procesos no se tengan los permisos suficientes y falle la inyección, además, si intentas inyectar una DLL de 64 bits en algún proceso de 32 bits no habrá errores, pero la inyección no se realizará (y viceversa).
El código se puede consultar en mi GitHub en este link: DLL injection. Hasta la próxima.

Autor: Josué Encinar García (@JosueEncinar). Ingeniero de Software por la Universidad Rey Juan Carlos, estudiante del Máster Universitario en Seguridad de Tecnologías de la Información y de las Comunicaciones en la Universidad Europea de Madrid. Analista de Seguridad en Accenture. Co-Fundador de @_ciberbyte_.

martes, 16 de enero de 2018

OWASP ZSC: Ofuscando y personalizando shellcodes & scripts

Compartir este artículo:
A menudo podemos utilizar la herramienta msfvenom de Metasploit para poder llevar a cabo la generación de shellcodes o código ofuscado para que los exploits consigan ejecutarlos sobre los objetivos. La herramienta msfvenom es una de las fundamentales en el mundo de la seguridad, pero hoy queremos hablar de otras herramientas que pueden complementar a la gran msfvenom de Metasploit. Una shellcode es un pequeño código Assembly el cual puede ser utilizado como un payload o parte de él en una explotación de software.

Además, en otros ámbitos también son utilizados: el propio malware o la fase de bypass de antivirus, son claros ejemplos. La posibilidad de personalizar las shellcodes es algo interesante, desde el punto de vista ofensivo, ya que nos permite poder evadir y hacer más difícil la posible detección o contramedida en este caso. La herramienta OWASP ZSC utiliza nuevos encodes y métodos que, al principio, tendrán una menor detección por parte de los antivirus. OWASP ZSC permite generar miles de shellcodes de forma dinámica, a través del uso de encodes aleatorios. La herramienta puede ser descargada desde su Github.


Con esta herramienta, OWASP, ha trabajado en la creación de nuevos métodos de ofuscación. Esto lo llevaron a cabo durante el último Google Summer of Code. Además, se está buscando penetrar en el área de shellcodes para OS X, lo cual hace que esta herramienta gane en interés. Lógicamente, aún no está, desde mi punto de vista, a la altura de herramientas como msfvenom, pero si el proyecto sigue adelante, la cosa promete.

La instalación de la herramienta es sencilla: python installer.py, una vez descargado el código desde su Github. Accedemos a la herramienta ejecutando el comando zsc, previa instalación realizada. Como se puede ver en la imagen, las posibilidades que ofrece la herramienta van directamente relacionadas con la selección de las shellcodes, el listado de éstas y la ofuscación que se puede llevar a cabo.


Otra de las opciones que permite hacer las herramientas es listar las shellcodes disponibles. Para ello se puede hacer uso del comando shell_storm_list, una vez cargada la opción shellcode. El listado de shellcodes es el que se tiene disponible en el sitio web de Shell Storm, un sitio web que ofrece una gran cantidad de shellcodes para distintas plataformas y arquitecturas.


Para ejemplificar el uso de la herramienta, seleccionamos una de las shellcodes disponibles. Para este ejemplo, utilizamos la ruta shellcode/generate/windows_x86/[shellcode]. Si quisiéramos utilizar otra ruta para otra plataforma, sería del tipo: Windows_x86_x64, Linux, etcétera. Para mostrar en el ejemplo, seleccionamos la shellcode add_admin, cuyo código permitirá que cuando se ejecute aparezca un nuevo usuario en el sistema con privilegios de administrador.

Tras seleccionar la shellcode se puede introducir el nombre del usuario y la contraseña seleccionada. Tal y como se puede ver en la imagen, se preguntará por un encoder después de introducir los datos anteriores.


Se nos preguntará si queremos almacenar los resultados en un fichero assembly o de lenguaje C. Por otro lado, podremos mostrar la shellcode directamente en pantalla. En la imagen se puede ver un ejemplo de esto. Al final obtenemos una serie de opcodes, los cuales forman nuestra shellcode. Es el momento de introducirlos en el exploit con el objetivo de que el código que se ejecute, una vez comprometida la máquina en el pentest, sea el que hemos generado.


Para finalizar el ejemplo, configuramos la shellcode en un exploit contra la máquina remota. En exploit-db existen muchos exploits que podéis modificar y, además, tienen la versión del software vulnerable para que descarguéis y configuréis en vuestro laboratorio con el objetivo de poder probar y aprender.

En la imagen, se puede ver como se ha creado un usuario llamado “pepe” con privilegios de administrador y que tiene como contraseña “1234”. En este instante, el pentester puede lograr acceso a la máquina a través de este código ejecutado aprovechando la vulnerabilidad.


Sin duda, OWASP ZSC es una herramienta que debemos llevar en la mochila del pentesting, ya que es un gran complemento a msfvenom. Además, el listado de shellcodes proporcionado desde Shell Storm ayuda a enriquecer el proceso. Si no lo has probado, te recomendamos que la pruebas.