Quantcast
Channel: Un informático en el lado del mal
Viewing all articles
Browse latest Browse all 4204

API Hooking para inyectar DLLs .NET con NetInternals

$
0
0
Probablemente todos conocéis o habéis escuchado en qué consisten las técnicas de API hooking que pueden ser usadas por rootkits o que puedes usar para analizar el comportamiento de binarios. Para quien a ni siquiera le suene, ésta técnica consiste en la modificación del flujo de ejecución de un programa para interceptar y/o modificar su comportamiento mediante la alteración de los parámetros de entrada/salida de la API que se esté hookeando– ¡Bueno, realmente no tiene por qué consistir exclusivamente en una API, pudiendo ser cualquier función existente en la aplicación! -.

Figura 1: API Hooking para inyectar DLLs .NET con NetInternals

Personalmente, esto es algo que siempre me ha llamado la atención debido a la gran cantidad de ‘hacks’ (¿Alguien ha dicho latchear API’s?) que se pueden realizar sobre un software, por lo que llevaba bastante tiempo pensando en hacer un sistema que permitiera interactuar a bajo nivel con procesos de Windows. Por lo tanto, en mi idea inicial se encontraba que permitiera, entre otras cosas, realizar hookeos a las API’s que utilizan los procesos remotos, y así hace unos meses me animé a iniciar NetInternalsDisponible en un repositorio GitHub - , una librería en .Net. ¡Aviso! El proyecto se encuentra aún en una fase muy inicial de desarrollo.

A continuación paso a explicar un poco más a bajo nivel pero muy brevemente como actúa la librería para realizar el proceso de hooking. El primer paso consiste en la ejecución de código en el proceso remoto. Para conseguir este propósito se realiza la inyección de una librería. El procedimiento es muy sencillo, con la ayuda de la API VirtualAlloc se reserva espacio en el proceso remoto para cargar la ruta en la que se encuentra la DLL que se va a inyectar. Posteriormente con WriteProcessMemory se escribe la ruta física de la DLL en la dirección de memoria que se ha reservado, y para finalizar se lanza un hilo remoto haciendo uso de CreateRemoteThread sobre LoadLibrary, pasándole como argumento la dirección de memoria que se había reservado.

Figura 2: Inyección de una DLL no manejada

¡Hey! ¡Un momento! ¿Y cómo dices que ejecutas código .Net (código manejado a partir de ahora) en un proceso no manejado? Sí, esto es posible mediante la inyección de código no manejado que cargue el framework .Net y posteriormente cargue la librería manejada (.Net). Ésta técnica está muy bien documentada en el artículo ‘Injecting .Net Assemblies Into Unmanaged Processes’ de Pero Matíc, el cual recomiendo. En la siguiente imagen se muestra cuáles serían los pasos para la carga de la misma.

Figura 3: Carga de código manejado desde código no manejado

A partir de este momento, el código manejado se encuentra cargado y en ejecución en el proceso remoto. ¡Es hora de realizar el hook! NetInternals realiza la técnica de ‘InLine hooking’ la cual consiste básicamente en la sobrescritura de las primeras instrucciones de la API para lograr un salto a otra zona de memoria.


Figura 4: Primeras instrucciones de la API "send" (WS2_32.dll)

A la hora de realizar el hook,NetInternals realiza distintas acciones. Una de ellas es la sobrescritura de los primeros 14 bytes (MOV EAX, [dir] y JMP EAX) de la API original. Con esto se consigue llevar el flujo de ejecución al código no manejado desde el cual NetInternals hace la modificación de los valores de entrada/salida de la API.

La segunda tarea a realizar es devolver el flujo de ejecución, pero tenemos un problema y es que al hacer el JMP a nuestro código, hemos sobrescrito código de la API que no se ejecutará nunca, por lo que será necesario antes de haber realizado dicha sobrescritura realizar una copia de la API original en otra zona de memoria. Esa copia de la API ejecutará las primeras instrucciones (contenidas en los primeros 14 bytes) y luego se le establecerá un JMP a la dirección de la API original más 14 bytes, que son los que se han sobrescrito. De este modo, cuando nuestro código manejado finalice la ejecución, hará otro salto a la dirección en donde hemos realizado la copia de la API, completando así el círculo y consiguiendo un correcto flujo de ejecución, como se muestra a en el siguiente gráfico.

Figura 5: Flujo de ejecución

Pero aquí no termina todo, ¿Qué facilidad aportaría NetInternals si hubiera que implementar la funcionalidad del tratado de las entradas/salidas de la llamada a la API en la propia librería? Exacto, ninguna. Por ello, y complicando un poco más el flujo, NetInternals es capaz de ‘migrar’ el flujo de ejecución a un proceso remoto mediante el uso de Pipes para la intercomunicación de procesos mediante WCF (Windows Communication Foundation).

Figura 6: Migración del flujo de funcionamiento

De este modo, desde una aplicación externa que haga uso de NetInternals es posible realizar todo este proceso con apenas un par de líneas de código, y obtener en el propio proceso las llamadas a la API que está ejecutando un proceso remoto.


Figura 7: Modificando las entradas/salidas de la API

Para terminar me gustaría mostrar un par de capturas de pantalla de una pequeña aplicación que hace uso de ‘NetInternals’ (Aplicación incluida en el proyecto de GitHub) para la interceptación y modificación de llamas a la APIBurpSuite Style’.

Figura 8: Editando memoria del proceso remoto

Espero que os haya resultado de interés o que el proyecto os sirva para alguna idea que tengáis en mente. ¡Un saludo!

Autor: Manu "The Sur"
Eleven Paths

Viewing all articles
Browse latest Browse all 4204

Trending Articles