Inyección de DLL
Inyección de DLL ( eng. Inyección de DLL ): en programación, un método utilizado para ejecutar código en el espacio de direcciones de otro proceso, obligándolo a cargar una biblioteca vinculada dinámicamente [1] . Las inyecciones de DLL a menudo son utilizadas por programas externos para afectar el comportamiento de otro programa de una manera que sus autores no pretendían o pretendían [1] [2] [3] . Por ejemplo, el código inyectado puede interceptar llamadas del sistema a funciones [4] [5] o leer el contenido de los campos de texto de la contraseña, lo que no se puede hacer de la forma habitual [6] . El programa utilizado para inyectar código arbitrario en procesos arbitrarios se denomina inyector de DLL .
Microsoft Windows
En Microsoft Windows, hay muchas formas de forzar a un proceso a cargar código en una DLL en contra de la voluntad del autor de la aplicación:
- Los archivos DLL enumerados en el registro del sistema por la clave HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLsse cargarán en cada proceso que cargue la biblioteca User32.dll en su llamada inicial. [7] [8] [9]
- Las DLL con clave HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDLLsse cargarán en cada proceso que llame a las funciones CreateProcess, CreateProcessAsUser, CreateProcessWithLogonW, CreateProcessWithTokenW y WinExec de la API de Windows . Este es uno de los métodos legítimos de inyección de DLL en Windows 10, siempre que el archivo DLL esté firmado con el certificado correcto.
- Funciones de manipulación de procesos, como CreateRemoteThread, o tecnologías de inyección de código, como AtomBombing [10] , que se pueden usar para inyectar una DLL en un programa después de que se haya ejecutado. [5] [6] [11] [12] [13] [14]
- Interceptar llamadas de Windows, como SetWindowsHookEx. [2] [5] [6] [15] [16] [17]
- Usar las funciones SuspendThread o NtSuspendThread para suspender todos los subprocesos y usar las funciones SetThreadContext o NtSetContextThread para modificar el contexto de los subprocesos existentes en la aplicación para ejecutar código inyectado que puede cargar la DLL. [4] [18] [19]
- Aproveche las limitaciones de Windows y las aplicaciones que llaman a LoadLibrary o LoadLibraryEx sin especificar la ruta a la DLL para cargar. [20] [21] [22]
- Operando con capas del nivel del sistema.
- Sustitución de una de las DLL dependientes de la aplicación por una falsa que contiene los mismos objetos exportados que la original. [23]
Sistemas operativos similares a Unix
En sistemas operativos similares a Unix , usando un enlazador dinámico basado en ld.so (en BSD ) y ld-linux.so (en Linux ), puede cargar bibliotecas arbitrarias en un nuevo proceso especificando la ruta a la biblioteca usando un entorno variable LD_PRELOAD.que se puede asignar globalmente o asignar a un proceso específico individualmente. [24]
Por ejemplo, en un sistema Linux, este comando inicia el proceso "prog" junto con la biblioteca compartida "test.so" asignada en el momento del inicio:
LD_PRELOAD = programa "./test.so "
Estas bibliotecas se crean de la misma manera que los objetos compartidos. La biblioteca tiene acceso a los símbolos externos especificados en el programa, como cualquier otra biblioteca.
En macOS , este comando inicia el proceso "prog" junto con la biblioteca compartida "test.dylib" asignada en el momento del inicio: [25]
DYLD_INSERT_LIBRARIES = "./test.dylib" DYLD_FORCE_FLAT_NAMESPACE
= 1 programaEn sistemas similares a Unix también es posible utilizar métodos basados en depuradores. [26]
Código de ejemplo
Uso de la API LoadLibrary
La siguiente función de muestra utiliza una técnica de inyección de DLL que aprovecha el hecho de que kernel32.dll está asignado a la misma dirección que casi todos los procesos. Por lo tanto, LoadLibrary (que es una función de kernel32.dll) también se asigna a la misma dirección. LoadLibrary también es adecuado para la rutina de inicio de subprocesos requerida por CreateRemoteThread.
#incluir <ventanas.h>
HANDLE inject_DLL ( const char * file_name , int PID )
{
HANDLE h_proceso , h_rThread ;
char fullDLLPath [ _MAX_PATH ];
LPVOID DLLPath_addr , LoadLib_addr ;
código_salida DWORD ;
/* Recuperar el identificador del proceso de destino */
h_process = OpenProcess ( PROCESS_ALL_ACCESS , FALSE , PID );
/* Obtener la ruta completa al archivo DLL */
GetFullPathName ( file_name , _MAX_PATH , fullDLLPath , NULL );
/* Asignar memoria en el proceso de destino */
DLLPath_addr = VirtualAllocEx ( h_process , NULL , _MAX_PATH ,
MEM_COMMIT | MEM_RESERVA , PÁGINA_LEER ESCRITURA );
/* Escribe la ruta del archivo DLL en el bloque de memoria recién creado */
WriteProcessMemory ( h_process , DLLPath_addr , fullDLLPath ,
strlen ( ruta DLL completa ), NULL );
/* Obtener la dirección de LoadLibraryA (igual para todos los procesos) para comenzar a ejecutarlo */
LoadLib_addr = GetProcAddress ( GetModuleHandle ( "Kernel32" ), "LoadLibraryA" );
/* Iniciar un subproceso remoto en LoadLibraryA y pasar la ruta a la DLL como argumento */
h_rThread = CreateRemoteThread ( h_process , NULL , 0 , ( LPTHREAD_START_ROUTINE ) LoadLib_addr , DLLPath_addr , 0 , NULL );
/* Esperar a que se complete */
WaitForSingleObject ( h_rThread , INFINITE );
/* Obtener el código de salida (es decir, el valor del identificador devuelto por la llamada a LoadLibraryA */
GetExitCodeThread ( h_rThread , & exit_code );
/* Liberar el host de la secuencia incrustada. */
CloseHandle ( h_rThread );
/* Así como la memoria asignada para la ruta a la DLL */
VirtualFreeEx ( h_process , DLLPath_addr , 0 , MEM_RELEASE );
/* Y también el handle-id del proceso de destino */
CloseHandle ( h_proceso );
return ( MANGO ) exit_code ;
}
Notas
- ↑ 1 2 James Shewmaker. Analizando la inyección de DLL . Presentación GSM . muesca azul Consultado el 31 de agosto de 2008. Archivado desde el original el 3 de diciembre de 2008. (indefinido)
- ↑ 12 Iczelión . Tutorial 24: Ganchos de Windows . Página de inicio de ensamblado de Win32 de Iczelion (agosto de 2002). Consultado el 31 de agosto de 2008. Archivado desde el original el 1 de agosto de 2008. (indefinido)
- ↑ Polea rocosa. Ampliación del Administrador de tareas con inyección de DLL . proyecto de código . CodeProject (19 de mayo de 2005). Consultado el 1 de septiembre de 2008. Archivado desde el original el 6 de febrero de 2009. (indefinido)
- ↑ 1 2 Nasser R. Rowhani. Tutorial de inyección de DLL e interceptación de funciones . proyecto de código . CodeProject (23 de octubre de 2003). Consultado el 31 de agosto de 2008. Archivado desde el original el 15 de junio de 2008. (indefinido)
- ↑ 1 2 3 Ivo Ivánov. Enlace de API revelado . proyecto de código . CodeProject (2 de diciembre de 2002). Consultado el 31 de agosto de 2008. Archivado desde el original el 14 de octubre de 2008. (indefinido)
- ↑ 1 2 3 Robert Kuster. Tres formas de inyectar su código en otro proceso . proyecto de código . CodeProject (20 de agosto de 2003). Consultado el 31 de agosto de 2008. Archivado desde el original el 20 de julio de 2008. (indefinido)
- ↑ Trabajar con el valor de registro AppInit_DLLs . Microsoft (21 de noviembre de 2006). Consultado el 28 de diciembre de 2021. Archivado desde el original el 1 de enero de 2017.
- ↑ Raymond Chen. AppInit_DLLs debe renombrarse como Deadlock_Or_Crash_Randomly_DLLs . Lo viejo nuevo . Microsoft (13 de diciembre de 2007). Consultado el 28 de diciembre de 2021. Archivado desde el original el 17 de diciembre de 2007.
- ↑ dllmain.c (inglés) (enlace inaccesible - historial ) . Reaccionar OS . Fundación React OS.
- ↑ 'AtomBombing' Microsoft Windows a través de inyección de código , Dark Reading (27 de octubre de 2016). Archivado el 17 de mayo de 2021. Consultado el 28 de diciembre de 2021.
- ↑ Trent Waddington. InjectDLL (inglés) (enlace descendente) (31 de agosto de 2008). Consultado el 28 de diciembre de 2021. Archivado desde el original el 30 de diciembre de 2019.
- ↑ Dll Injection (inglés) (enlace descendente) . DreamInCode.net . MediaGroup1 (31 de agosto de 2008). Archivado desde el original el 2 de septiembre de 2008.
- ↑ Greg Jenkins. Marco de inyección de DLL (inglés) (enlace no disponible) . Ring3 Circus (1 de noviembre de 2007). Consultado el 28 de diciembre de 2021. Archivado desde el original el 28 de junio de 2020.
- ↑ Drew Benton. Una solución de inyección de DLL más completa mediante CreateRemoteThread . proyecto de código . CodeProject (17 de agosto de 2007). Consultado el 28 de diciembre de 2021. Archivado desde el original el 28 de diciembre de 2021.
- ↑ Función SetWindowsHookEx . Plataforma SDK para Windows XP SP2 . Microsoft (31 de agosto de 2008). Consultado el 28 de diciembre de 2021. Archivado desde el original el 17 de agosto de 2016.
- ↑ Valor de registro AppInit_DLLs y Windows 95 . Ayuda y soporte técnico de Microsoft . Microsoft (1 de marzo de 2005). Consultado el 28 de diciembre de 2021. Archivado desde el original el 20 de marzo de 2016.
- ↑ Inyección de Dll usando el método SetWindowsHookEx() . Inversión del juego (3 de abril de 2008). Consultado el 28 de diciembre de 2021. Archivado desde el original el 4 de abril de 2016.
- ↑ Inyección de DLL SetThreadContext ( 16 de enero de 2007). Consultado el 28 de diciembre de 2021. Archivado desde el original el 28 de diciembre de 2021.
- ↑ Ben Botto. DLL Injector (inglés) (enlace no disponible) (6 de septiembre de 2008). Archivado desde el original el 7 de febrero de 2009.
- ↑ La carga insegura de la biblioteca podría permitir la ejecución remota de código . Microsoft (20 de abril de 2016). Consultado el 28 de diciembre de 2021. Archivado desde el original el 2 de julio de 2017.
- ↑ Carga segura de bibliotecas para evitar ataques de precarga de DLL . Microsoft (10 de junio de 2011). Consultado el 28 de diciembre de 2021. Archivado desde el original el 23 de septiembre de 2016.
- ↑ Aviso de seguridad de Microsoft: la carga insegura de la biblioteca podría permitir la ejecución remota de código . soporte.microsoft.com . Consultado el 28 de diciembre de 2021. Archivado desde el original el 28 de diciembre de 2021. (indefinido)
- ↑ Endpoint Protection: Symantec Enterprise . comunidad.broadcom.com . Consultado el 28 de diciembre de 2021. Archivado desde el original el 28 de diciembre de 2021. (indefinido)
- ↑ Torvalds, Linus; Linus Torvalds, David Engel, Eric Youngdale, Peter MacDonald, Hongjiu Lu, Lars Wirzenius, Mitch D'Souza. ld.so/ld-linux.so - enlazador/cargador dinámico (inglés) (enlace no disponible) . Páginas man de UNIX (14 de marzo de 1998). Archivado desde el original el 6 de febrero de 2009.
- ↑ Peter Goldsborough. El truco LD_PRELOAD . Peter Goldsborough . Consultado el 28 de diciembre de 2021. Archivado desde el original el 9 de diciembre de 2021. (indefinido)
- ↑ ¿ Inyección de código en una aplicación Linux en ejecución ? . CodeProject (12 de febrero de 2009). Consultado el 28 de diciembre de 2021. Archivado desde el original el 28 de diciembre de 2021. (indefinido)