Injecție DLL
DLL injection ( ing. DLL injection ) - în programare, o metodă folosită pentru a rula cod în spațiul de adrese al unui alt proces, forțându-l să încarce o bibliotecă legată dinamic [1] . Injecțiile DLL sunt adesea folosite de programe externe pentru a afecta comportamentul unui alt program într-un mod în care autorii acestuia nu au intenționat sau nu au intenționat [1] [2] [3] . De exemplu, codul injectat poate intercepta apelurile de sistem către funcții [4] [5] sau poate citi conținutul câmpurilor de text de parolă, ceea ce nu se poate face în mod obișnuit [6] . Programul folosit pentru a injecta cod arbitrar în procese arbitrare se numește injector DLL .
Microsoft Windows
Pe Microsoft Windows, există multe modalități de a forța un proces să încarce codul într-un DLL împotriva voinței autorului aplicației:
- Fișierele DLL enumerate în registrul de sistem după cheie HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLsvor fi încărcate în fiecare proces care încarcă biblioteca User32.dll la apelul său inițial. [7] [8] [9]
- DLL-urile cu cheie HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDLLsvor fi încărcate în fiecare proces care apelează funcțiile API Windows CreateProcess, CreateProcessAsUser, CreateProcessWithLogonW, CreateProcessWithTokenW și WinExec . Aceasta este una dintre metodele legitime de injectare DLL pe Windows 10, cu condiția ca fișierul DLL să fie semnat cu certificatul corect.
- Funcții de manipulare a procesului, cum ar fi CreateRemoteThread, sau tehnologii de injectare de cod, cum ar fi AtomBombing [10] , care pot fi folosite pentru a injecta un DLL într-un program după ce acesta a fost rulat. [5] [6] [11] [12] [13] [14]
- Interceptarea apelurilor Windows, cum ar fi SetWindowsHookEx. [2] [5] [6] [15] [16] [17]
- Folosind funcțiile SuspendThread sau NtSuspendThread pentru a suspenda toate firele de execuție și utilizarea funcțiilor SetThreadContext sau NtSetContextThread pentru a modifica contextul firelor de execuție existente în aplicație pentru a rula codul injectat care poate încărca DLL-ul. [4] [18] [19]
- Exploați limitările și aplicațiile Windows care apelează LoadLibrary sau LoadLibraryEx fără a specifica calea către DLL de încărcat. [20] [21] [22]
- Funcționează cu straturi la nivel de sistem.
- Înlocuirea uneia dintre DLL-urile dependente ale aplicației cu una falsă care conține aceleași obiecte exportate ca și originalul. [23]
Sisteme de operare asemănătoare Unix
Pe sistemele de operare asemănătoare Unix , folosind un linker dinamic bazat pe ld.so (pe BSD ) și ld-linux.so (pe Linux ), puteți încărca biblioteci arbitrare într-un proces nou specificând calea către bibliotecă folosind un mediu variabilă .care LD_PRELOADpoate fi atribuită global sau atribuită unui anumit proces individual. [24]
De exemplu, pe un sistem Linux, această comandă pornește procesul „prog” împreună cu biblioteca partajată „test.so” mapată în ea la momentul pornirii:
LD_PRELOAD = "./test.so" prog
Astfel de biblioteci sunt create în același mod ca obiectele partajate. Biblioteca are acces la simbolurile externe specificate în program, la fel ca orice altă bibliotecă.
Pe macOS , această comandă pornește procesul „prog” împreună cu biblioteca partajată „test.dylib” mapată în ea la momentul pornirii: [25]
DYLD_INSERT_LIBRARIES = "./test.dylib" DYLD_FORCE_FLAT_NAMESPACE = 1 prog
Pe sisteme asemănătoare Unix este posibil să se utilizeze și metode bazate pe depanare. [26]
Exemplu de cod
Folosind API-ul LoadLibrary
Funcția exemplu de mai jos folosește o tehnică de injectare DLL care exploatează faptul că kernel32.dll este mapat la aceeași adresă ca aproape toate procesele. Prin urmare, LoadLibrary (care este o funcție din kernel32.dll) este, de asemenea, mapat la aceeași adresă. LoadLibrary este, de asemenea, potrivit pentru rutina de pornire a firelor cerute de CreateRemoteThread.
#include <windows.h>
HANDLE inject_DLL ( const char * nume_fișier , int PID )
{
HANDLE h_process , h_rThread ;
char fullDLLPath [ _MAX_PATH ];
LPVOID DLPath_addr , LoadLib_addr ;
DWORD exit_code ;
/* Preluați handle-ul procesului țintă */
h_process = OpenProcess ( PROCESS_ALL_ACCESS , FALSE , PID );
/* Obține calea completă către fișierul DLL */
GetFullPathName ( nume_fișier , _MAX_PATH , fullDLLPath , NULL );
/* Alocați memorie în procesul țintă */
DLPath_addr = VirtualAllocEx ( h_process , NULL , _MAX_PATH ,
MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
/* Scrieți calea către fișierul DLL către blocul de memorie nou creat */
WriteProcessMemory ( h_process , DLLPath_addr , fullDLLPath ,
strlen ( fullDLLPath ), NULL );
/* Obțineți adresa LoadLibraryA (aceeași pentru toate procesele) pentru a începe să o rulați */
LoadLib_addr = GetProcAddress ( GetModuleHandle ( "Kernel32" ), "LoadLibraryA" );
/* Porniți un fir de execuție la distanță în LoadLibraryA și transmiteți calea către DLL ca argument */
h_rThread = CreateRemoteThread ( h_process , NULL , 0 , ( LPTHREAD_START_ROUTINE ) LoadLib_addr , DLLPath_addr , 0 , NULL );
/* Așteptați să se finalizeze */
WaitForSingleObject ( h_rThread , INFINIT );
/* Obține codul de ieșire (adică valoarea mânerului returnat de apelul către LoadLibraryA */
GetExitCodeThread ( h_rThread , & exit_code );
/* Eliberează gazda fluxului încorporat. */
CloseHandle ( h_rThread );
/* Precum și memoria alocată pentru calea către DLL */
VirtualFreeEx ( h_process , DLLPath_addr , 0 , MEM_RELEASE );
/* Și, de asemenea, identificatorul de identificare al procesului țintă */
CloseHandle ( h_process );
return ( HANDLE ) exit_code ;
}
Note
- ↑ 1 2 James Shewmaker. Analizarea injecției DLL . Prezentare GSM . bluenotch. Preluat la 31 august 2008. Arhivat din original la 3 decembrie 2008. (nedefinit)
- ↑ 12 Iczelion . Tutorial 24: Windows Hooks . Pagina principală Win32 Assembly a lui Iczelion (august 2002). Consultat la 31 august 2008. Arhivat din original la 1 august 2008. (nedefinit)
- ↑ Rocky Pulley. Extinderea Task Manager cu DLL Injection . cod proiect . CodeProject (19 mai 2005). Consultat la 1 septembrie 2008. Arhivat din original pe 6 februarie 2009. (nedefinit)
- ↑ 1 2 Nasser R. Rowhani. Tutorial de injectare DLL și interceptare a funcției . cod proiect . CodeProject (23 octombrie 2003). Consultat la 31 august 2008. Arhivat din original la 15 iunie 2008. (nedefinit)
- ↑ 1 2 3 Ivo Ivanov. Conectarea API a fost dezvăluită . cod proiect . CodeProject (2 decembrie 2002). Consultat la 31 august 2008. Arhivat din original la 14 octombrie 2008. (nedefinit)
- ↑ 1 2 3 Robert Kuster. Trei moduri de a injecta codul într-un alt proces . cod proiect . CodeProject (20 august 2003). Preluat la 31 august 2008. Arhivat din original la 20 iulie 2008. (nedefinit)
- ↑ Lucrul cu valoarea de registry AppInit_DLLs . Microsoft (21 noiembrie 2006). Preluat la 28 decembrie 2021. Arhivat din original la 1 ianuarie 2017.
- ↑ Raymond Chen. AppInit_DLL-urile ar trebui redenumite Deadlock_Or_Crash_Randomly_DLLs . Vechiul Lucru Nou . Microsoft (13 decembrie 2007). Preluat la 28 decembrie 2021. Arhivat din original la 17 decembrie 2007.
- ↑ dllmain.c (engleză) (link inaccesibil - istoric ) . React OS . Fundația React OS.
- ↑ „AtomBombing” Microsoft Windows Via Code Injection , Dark Reading (27 octombrie 2016). Arhivat 17 mai 2021. Preluat la 28 decembrie 2021.
- ↑ Trent Waddington. InjectDLL (engleză) (downlink) (31 august 2008). Preluat la 28 decembrie 2021. Arhivat din original la 30 decembrie 2019.
- ↑ Dll Injection (engleză) (downlink) . DreamInCode.net . MediaGroup1 (31 august 2008). Arhivat din original pe 2 septembrie 2008.
- ↑ Greg Jenkins. DLL Injection Framework (engleză) (link indisponibil) . Ring3 Circus (1 noiembrie 2007). Preluat la 28 decembrie 2021. Arhivat din original la 28 iunie 2020.
- ↑ Drew Benton. O soluție de injecție DLL mai completă folosind CreateRemoteThread . cod proiect . CodeProject (17 august 2007). Preluat la 28 decembrie 2021. Arhivat din original la 28 decembrie 2021.
- ↑ SetWindowsHookEx Function . Platform SDK pentru Windows XP SP2 . Microsoft (31 august 2008). Preluat la 28 decembrie 2021. Arhivat din original la 17 august 2016.
- ↑ Valoarea de registru AppInit_DLLs și Windows 95 . Ajutor și asistență Microsoft . Microsoft (1 martie 2005). Preluat la 28 decembrie 2021. Arhivat din original la 20 martie 2016.
- ↑ Injectarea Dll folosind metoda SetWindowsHookEx() . Game Reversal (3 aprilie 2008). Preluat la 28 decembrie 2021. Arhivat din original la 4 aprilie 2016.
- ↑ SetThreadContext DLL Injection ( 16 ianuarie 2007). Preluat la 28 decembrie 2021. Arhivat din original la 28 decembrie 2021.
- ↑ Ben Botto. DLL Injector (engleză) (link indisponibil) (6 septembrie 2008). Arhivat din original pe 7 februarie 2009.
- ↑ Încărcarea nesigură a bibliotecii ar putea permite executarea codului de la distanță . Microsoft (20 aprilie 2016). Preluat la 28 decembrie 2021. Arhivat din original la 2 iulie 2017.
- ↑ Încărcarea securizată a bibliotecilor pentru a preveni atacurile de preîncărcare DLL . Microsoft (10 iunie 2011). Preluat la 28 decembrie 2021. Arhivat din original la 23 septembrie 2016.
- ↑ Microsoft Security Advisory: Încărcarea nesigură a bibliotecii ar putea permite executarea codului de la distanță . support.microsoft.com . Preluat la 28 decembrie 2021. Arhivat din original la 28 decembrie 2021. (nedefinit)
- ↑ Endpoint Protection - Symantec Enterprise . community.broadcom.com . Preluat la 28 decembrie 2021. Arhivat din original la 28 decembrie 2021. (nedefinit)
- ↑ Torvalds, Linus; Linus Torvalds, David Engel, Eric Youngdale, Peter MacDonald, Hongjiu Lu, Lars Wirzenius, Mitch D'Souza. ld.so/ld-linux.so - linker/loader dinamic (engleză) (link indisponibil) . Pagini de manual UNIX (14 martie 1998). Arhivat din original pe 6 februarie 2009.
- ↑ Peter Goldsborough. Trucul LD_PRELOAD . Peter Goldsborough . Preluat la 28 decembrie 2021. Arhivat din original la 9 decembrie 2021. (nedefinit)
- ↑ Injectarea de cod în aplicația Linux care rulează ? . CodeProject (12 februarie 2009). Preluat la 28 decembrie 2021. Arhivat din original la 28 decembrie 2021. (nedefinit)