DLL Injection
DLL injection
es un método que implica insertar un fragmento de código, estructurado como una biblioteca de vínculos dinámicos (DLL), en un proceso en ejecución. Esta técnica permite que el código insertado se ejecute dentro del contexto del proceso, influyendo así en su comportamiento o accediendo a sus recursos.
DLL injection
se puede encontrar en aplicaciones legítimas en varias áreas. Por ejemplo, los desarrolladores de software aprovechan esta tecnología para hot patching
, un método que permite la modificación o actualización de código sin problemas, sin la necesidad de reiniciar el proceso en curso de inmediato. Un excelente ejemplo de esto es el uso de hot patching de Azure para actualizar servidores operativos , lo que facilita los beneficios de la actualización sin necesidad de tiempo de inactividad del servidor.
Sin embargo, no es completamente inocuo. Los cibercriminales suelen manipular DLL injection
para insertar código malicioso en procesos de confianza. Esta técnica es especialmente eficaz para evadir la detección del software de seguridad.
Existen varios métodos diferentes para ejecutar una inyección de DLL.
LoadLibrary
LoadLibrary
es un método ampliamente utilizado para la inyección de DLL, que emplea la API LoadLibrary
para cargar la DLL en el espacio de direcciones del proceso de destino.
La LoadLibrary
API es una función proporcionada por el sistema operativo Windows que carga una biblioteca de vínculos dinámicos (DLL) en la memoria del proceso actual y devuelve un identificador que puede usarse para obtener las direcciones de las funciones dentro de la DLL.
El primer ejemplo muestra cómo se puede utilizar LoadLibrary
para cargar una DLL en el proceso actual de forma legítima:
Código: c
El segundo ejemplo ilustra el uso de LoadLibrary
para la inyección de DLL. Este proceso implica asignar memoria dentro del proceso de destino para la ruta de la DLL y luego iniciar un subproceso remoto que comienza en la ruta de la DLL LoadLibrary
y se dirige hacia ella:
Mapeo manual
Manual Mapping
es un método increíblemente complejo y avanzado de inyección de DLL. Implica la carga manual de una DLL en la memoria de un proceso y resuelve sus importaciones y reubicaciones. Sin embargo, evita la detección fácil al no utilizar la función LoadLibrary
, cuyo uso es monitoreado por sistemas de seguridad y antivirus.
Un esquema simplificado del proceso puede representarse de la siguiente manera:
Cargue la DLL como datos sin procesar en el proceso de inyección.
Asigne las secciones de DLL al proceso de destino.
Inyectar el shellcode en el proceso de destino y ejecutarlo. Este shellcode reubica la DLL, rectifica las importaciones, ejecuta las devoluciones de llamadas de Thread Local Storage (TLS) y, por último, llama a la DLL principal.
Inyección de DLL reflexiva
Reflective DLL injection
es una técnica que utiliza programación reflexiva para cargar una biblioteca desde la memoria a un proceso host. La biblioteca en sí es responsable de su proceso de carga implementando un cargador de archivos ejecutable portátil (PE) mínimo. Esto le permite decidir cómo se cargará e interactuará con el host, minimizando la interacción con el sistema y el proceso host.
Stephen Fewer tiene un excelente GitHub que demuestra la técnica. A continuación, se reproduce su explicación:
"El procedimiento para inyectar de forma remota una biblioteca en un proceso es doble. En primer lugar, la biblioteca que se pretende inyectar debe estar escrita en el espacio de direcciones del proceso de destino (en adelante denominado "proceso host"). En segundo lugar, la biblioteca debe cargarse en el proceso host para cumplir con las expectativas de tiempo de ejecución de la biblioteca, como resolver sus importaciones o reubicarla en una ubicación adecuada en la memoria.
Suponiendo que tenemos ejecución de código en el proceso host y la biblioteca que pretendemos inyectar se ha escrito en una ubicación de memoria arbitraria en el proceso host, la inyección de DLL reflectante funciona de la siguiente manera.
El control de ejecución se transfiere a la función reflectante de la biblioteca, una función exportada que se encuentra en la tabla de exportación de la biblioteca. Esto puede suceder a través de
El control de ejecución se transfiere a la función
ReflectiveLoader
de la biblioteca, una función exportada que se encuentra en la tabla de exportación de la biblioteca. Esto puede suceder medianteCreateRemoteThread()
un shellcode de arranque mínimo.Como la imagen de la biblioteca reside actualmente en una ubicación de memoria arbitraria,
ReflectiveLoader
inicialmente calcula la ubicación de memoria actual de su propia imagen para analizar sus propios encabezados para su uso posterior.Luego
ReflectiveLoader
, analiza la tabla de exportación del proceso hostkernel32.dll
para calcular las direcciones de tres funciones que necesita el cargador, a saberLoadLibraryA
,GetProcAddress
, yVirtualAlloc
.Ahora
ReflectiveLoader
asigna una región de memoria continua donde se cargará su propia imagen. La ubicación no es crucial; el cargador reubicará correctamente la imagen más adelante.Los encabezados y secciones de la biblioteca se cargan en sus nuevas ubicaciones de memoria.
Luego,
ReflectiveLoader
procesa la copia recién cargada de la tabla de importación de su imagen, carga cualquier biblioteca adicional y resuelve sus respectivas direcciones de función importadas.Luego
ReflectiveLoader
procesa la copia recién cargada de la tabla de reubicación de su imagen.Luego
ReflectiveLoader
llama a la función de punto de entrada de la imagen recién cargada,DllMain,
conDLL_PROCESS_ATTACH
. La biblioteca se ha cargado correctamente en la memoria.Finalmente, la ejecución de
ReflectiveLoader
retorna al shellcode de arranque inicial que lo llamó, o si se llamó a través deCreateRemoteThread
, el hilo finalizaría.
DLL Hijacking
DLL Hijacking
es una técnica de explotación en la que un atacante aprovecha el proceso de carga de DLL de Windows. Estas DLL se pueden cargar durante el tiempo de ejecución, lo que crea una oportunidad de secuestro si una aplicación no especifica la ruta completa a una DLL requerida, lo que la hace susceptible a este tipo de ataques.
El orden de búsqueda de DLL predeterminado que utiliza el sistema depende de si Safe DLL Search Mode
está activado o no. Cuando está activado (que es la configuración predeterminada), el modo de búsqueda segura de DLL reubica el directorio actual del usuario más abajo en el orden de búsqueda. Es fácil habilitar o deshabilitar la configuración editando el registro.
Presione
Windows + R
para abrir el cuadro de diálogo Ejecutar.Escriba
Regedit
y presioneEnter
. Esto abrirá el Editor del Registro.Navegar a
HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager
.En el panel derecho, busque el valor
SafeDllSearchMode
. Si no existe, haga clic derecho en el espacio en blanco de la carpeta o haga clic derecho en la carpetaSession Manager
, seleccioneNew
y luegoDWORD (32-bit) Value
. Nombre este nuevo valor comoSafeDllSearchMode
.Haga doble clic en
SafeDllSearchMode
. En el campo Datos del valor, introduzca1
para habilitar o0
para deshabilitar el modo de búsqueda segura de DLL.Haga clic en
OK
, cierre el Editor del Registro y reinicie el sistema para que los cambios surtan efecto.
Con este modo habilitado, las aplicaciones buscan los archivos DLL necesarios en la siguiente secuencia:
El directorio desde el que se carga la aplicación.
El directorio del sistema.
El directorio del sistema de 16 bits.
El directorio de Windows.
El directorio actual.
Los directorios que aparecen enumerados en la variable de entorno PATH.
Sin embargo, si el 'Modo de búsqueda segura de DLL' está desactivado, el orden de búsqueda cambia a:
El directorio desde el que se carga la aplicación.
El directorio actual.
El directorio del sistema.
El directorio del sistema de 16 bits.
El directorio de Windows
Los directorios que se enumeran en la variable de entorno PATH
El secuestro de DLL implica unos cuantos pasos más. En primer lugar, debe identificar la DLL que el objetivo está intentando localizar. Hay herramientas específicas que pueden simplificar esta tarea:
Process Explorer
: Esta herramienta, que forma parte de la suite Sysinternals de Microsoft, ofrece información detallada sobre los procesos en ejecución, incluidas las DLL cargadas. Si selecciona un proceso e inspecciona sus propiedades, podrá ver sus DLL.PE Explorer
: Este explorador de archivos ejecutables portátiles (PE) puede abrir y examinar un archivo PE (como un .exe o .dll). Entre otras funciones, revela las DLL desde las que el archivo importa funcionalidad.
Después de identificar una DLL, el siguiente paso es determinar qué funciones desea modificar, lo que requiere herramientas de ingeniería inversa, como desensambladores y depuradores. Una vez que se han identificado las funciones y sus firmas, es momento de construir la DLL.
Tomemos un ejemplo práctico. Considere el programa en C que se muestra a continuación:
Código: c
Carga una función add
del library.dll
y utiliza esta función para sumar dos números. Posteriormente, imprime el resultado de la suma. Examinando el programa en Process Monitor (procmon), podemos observar el proceso de carga del library.dll
ubicado en el mismo directorio.
Primero, configuremos un filtro en procmon para incluir únicamente main.exe
, que es el nombre del proceso del programa. Este filtro nos ayudará a centrarnos específicamente en las actividades relacionadas con la ejecución de main.exe
. Es importante tener en cuenta que procmon solo captura información mientras se está ejecutando activamente. Por lo tanto, si su registro aparece vacío, debe cerrar main.exe
y volver a abrirlo mientras procmon se está ejecutando. Esto garantizará que se capture la información necesaria y esté disponible para su análisis.
Luego, si te desplazas hasta la parte inferior, podrás ver la llamada a load library.dll
.
Podemos filtrar aún más por una operación de carga de imagen para obtener solo las bibliotecas que la aplicación está cargando.
Proxy
Podemos utilizar un método conocido como DLL Proxying para ejecutar un secuestro. Crearemos una nueva biblioteca que cargará la función Add
desde library.dll
, la manipulará y luego la devolverá a main.exe
.
Crear una nueva biblioteca: crearemos una nueva biblioteca que sirva como proxy para
library.dll
. Esta biblioteca contendrá el código necesario para cargar la funciónAdd
enlibrary.dll
y realizar la manipulación necesaria.Cargar la función
Add
: Dentro de la nueva librería cargaremos la funciónAdd
de la originallibrary.dll
. Esto nos permitirá acceder a la función original.Modificar la función: Una vez cargada la función
Add
, podemos aplicar las modificaciones o manipulaciones que queramos a su resultado. En este caso, simplemente vamos a modificar el resultado de la suma, para añadir+ 1
al resultado.Devolver la función modificada: después de completar el proceso de manipulación, devolveremos la función
Add
modificada desde la nueva biblioteca amain.exe
. Esto garantizará que, cuandomain.exe
invoque la funciónAdd
, se ejecutará la versión modificada con los cambios previstos.
El código es el siguiente:
Código: c
Compílelo o utilice la versión precompilada proporcionada. Cambie el nombre de library.dll
a library.o.dll
y cambie el nombre de tamper.dll
a library.dll
.
Al ejecutar main.exe
se muestra el hackeo exitoso.
Bibliotecas no válidas
Otra opción para ejecutar un ataque de secuestro de DLL es reemplazar una biblioteca válida que el programa intenta cargar pero no puede encontrar con una biblioteca creada. Si cambiamos el filtro de procmon para enfocarnos en las entradas cuya ruta termina en .dll
y tiene un estado de NAME NOT FOUND
podemos encontrar dichas bibliotecas en main.exe
.
Como sabemos, main.exe
busca en muchas ubicaciones buscando x.dll
, pero no se encuentra en ninguna parte. La entrada que nos interesa especialmente es:
Buscamos cargar x.dll
desde el directorio de la aplicación. Podemos aprovechar esto y cargar nuestro propio código, con muy poco contexto de lo que busca en x.dll
.
Código: c
Este código define una función de punto de entrada de DLL DllMain
que Windows llama automáticamente cuando se carga la DLL en un proceso. Cuando se carga la biblioteca, simplemente se imprime Hijacked... Oops...
en la terminal, pero en teoría podría hacer cualquier cosa aquí.
Compílelo o utilice la versión precompilada proporcionada. Cambie el nombre hijack.dll
a x.dll
y ejecute main.exe
.
Última actualización
¿Te fue útil?