DLL-injektio
DLL-injektio ( eng. DLL-injektio ) - ohjelmoinnissa menetelmä, jota käytetään koodin suorittamiseen toisen prosessin osoiteavaruudessa, pakottamalla se lataamaan dynaamisesti linkitetyn kirjaston [1] . Ulkoiset ohjelmat käyttävät usein DLL-injektioita toisen ohjelman käyttäytymiseen vaikuttamiseen tavalla, jota sen kirjoittajat eivät tarkoittanut tai aikoneet [1] [2] [3] . Syötetty koodi voi esimerkiksi siepata järjestelmäkutsuja toimintoihin [4] [5] tai lukea salasanan tekstikenttien sisältöä, mitä ei voida tehdä tavalliseen tapaan [6] . Ohjelmaa, jota käytetään mielivaltaisen koodin lisäämiseen mielivaltaisiin prosesseihin, kutsutaan DLL-injektoriksi .
Microsoft Windows
Microsoft Windowsissa on monia tapoja pakottaa prosessi lataamaan koodia DLL-tiedostoon vastoin sovelluksen tekijän tahtoa:
- DLL-tiedostot, jotka on lueteltu järjestelmän rekisterissä avaimella HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs, ladataan jokaisessa prosessissa, joka lataa User32.dll- kirjaston sen ensimmäisessä kutsussa. [7] [8] [9]
- Avaintetut DLL -tiedostot HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDLLsladataan jokaiseen prosessiin, joka kutsuu CreateProcess-, CreateProcessAsUser-, CreateProcessWithLogonW-, CreateProcessWithTokenW- ja WinExec Windows API -funktioita. Tämä on yksi laillisista DLL-injektiomenetelmistä Windows 10:ssä, jos DLL-tiedosto on allekirjoitettu oikealla varmenteella.
- Prosessin manipulointitoiminnot, kuten CreateRemoteThread, tai koodin lisäysteknologiat, kuten AtomBombing [10] , joita voidaan käyttää DLL:n lisäämiseen ohjelmaan sen suorituksen jälkeen. [5] [6] [11] [12] [13] [14]
- Windows-puheluiden sieppaaminen, kuten SetWindowsHookEx. [2] [5] [6] [15] [16] [17]
- SuspendThread- tai NtSuspendThread-toimintojen käyttäminen kaikkien säikeiden keskeyttämiseen ja SetThreadContext- tai NtSetContextThread-funktioiden käyttäminen sovelluksen olemassa olevien säikeiden kontekstin muokkaamiseen, jotta voidaan suorittaa syötetty koodi, joka voi ladata DLL:n. [4] [18] [19]
- Hyödynnä Windowsin rajoituksia ja sovelluksia, jotka kutsuvat LoadLibrary- tai LoadLibraryEx-kutsuja määrittämättä polkua ladattavaan DLL-tiedostoon. [20] [21] [22]
- Toimii järjestelmätason kerrosten kanssa.
- Yhden sovelluksesta riippuvaisen DLL:n korvaaminen väärennetyllä DLL:llä, joka sisältää samat vietyt objektit kuin alkuperäinen. [23]
Unix-tyyppiset käyttöjärjestelmät
Unix -tyyppisissä käyttöjärjestelmissä voit ladata mielivaltaisia kirjastoja uuteen prosessiin käyttämällä dynaamista linkkeriä, joka perustuu ld.so- ( BSD :ssä ) ja ld-linux.so-pohjaisiin järjestelmiin ( Linuxissa ), määrittämällä polun kirjastoon ympäristön avulla. muuttuja LD_PRELOAD, joka voidaan määrittää globaalisti tai määrittää tietylle prosessille erikseen. [24]
Esimerkiksi Linux-järjestelmässä tämä komento käynnistää prosessin "prog" yhdessä jaetun kirjaston "test.so" kanssa, joka on yhdistetty siihen käynnistyksen yhteydessä:
LD_PRELOAD = "./test.so" prog
Tällaiset kirjastot luodaan samalla tavalla kuin jaetut objektit. Kirjastossa on pääsy ohjelmassa määritettyihin ulkoisiin symboleihin, kuten kaikki muutkin kirjastot.
macOS
: ssä tämä komento käynnistää "prog"-prosessin ja siihen käynnistyshetkellä yhdistetyn jaetun kirjaston "test.dylib": [25]
DYLD_INSERT_LIBRARIES = "./test.dylib" DYLD_FORCE_FLAT_NAMESPACE
= 1 ohjelmaUnix-tyyppisissä järjestelmissä on myös mahdollista käyttää debuggereihin perustuvia menetelmiä. [26]
Esimerkkikoodi
LoadLibrary API:n käyttäminen
Alla oleva esimerkkitoiminto käyttää DLL-injektiotekniikkaa, joka hyödyntää sitä tosiasiaa, että kernel32.dll on kartoitettu samaan osoitteeseen kuin melkein kaikki prosessit. Siksi myös LoadLibrary (joka on kernel32.dll:n funktio) on yhdistetty samaan osoitteeseen. LoadLibrary sopii myös CreateRemoteThreadin vaatimaan säikeen käynnistysrutiiniin.
#include <windows.h>
HANDLE inject_DLL ( const char * file_name , int PID )
{
HANDLE h_process , h_rThread ;
char fullDLLPath [ _MAX_PATH ];
LPVOID DLLPath_addr , LoadLib_addr ;
DWORD -poistumiskoodi ;
/* Hae kohdeprosessin kahva */
h_prosessi = OpenProcess ( PROCESS_ALL_ACCESS , EPÄTOSI , PID );
/* Hae koko polku DLL-tiedostoon */
GetFullPathName ( tiedoston_nimi , _MAX_PATH , fullDLLPath , NULL );
/* Varaa muisti kohdeprosessissa */
DLLPath_addr = VirtualAllocEx ( h_prosessi , NULL , _MAX_PATH ,
MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
/* Kirjoita polku DLL-tiedostoon juuri luotuun muistilohkoon */
WriteProcessMemory ( h_process , DLLPath_addr , fullDLLPath ,
strlen ( fullDLLPath ), NULL );
/* Hanki LoadLibraryA:n osoite (sama kaikille prosesseille) aloittaaksesi sen suorittamisen */
LoadLib_addr = GetProcAddress ( GetModuleHandle ( "Kernel32" ), "LoadLibraryA" );
/* Aloita etäsäike LoadLibraryA:ssa ja välitä polku DLL:ään argumenttina */
h_rThread = CreateRemoteThread ( h_prosessi , NULL , 0 , ( LPTHREAD_START_ROUTINE ) LoadLib_addr , DLLPath_addr , 0 , NULL );
/* Odota sen valmistumista */
WaitForSingleObject ( h_rThread , äärimmäinen );
/* Hanki poistumiskoodi (eli LoadLibraryA:n kutsun palauttaman kahvan arvo */
GetExitCodeThread ( h_rThread , & exit_code );
/* Vapauta upotetun streamin isäntä. */
CloseHandle ( h_rThread );
/* Sekä DLL:n polulle varattu muisti */
VirtualFreeEx ( h_prosessi , DLLPath_addr , 0 , MEM_RELEASE );
/* Ja myös kohdeprosessin hand-id */
CloseHandle ( h_prosessi );
return ( HANDLE ) exit_code ;
}
Muistiinpanot
- ↑ 1 2 James Shewmaker. DLL-injektion analysointi . GSM-esitys . bluenotch. Haettu 31. elokuuta 2008. Arkistoitu alkuperäisestä 3. joulukuuta 2008. (määrätön)
- ↑ 12 Iczelion . Oppitunti 24: Windowsin koukut . Iczelionin Win32 Assemblyn kotisivu (elokuu 2002). Haettu 31. elokuuta 2008. Arkistoitu alkuperäisestä 1. elokuuta 2008. (määrätön)
- ↑ Rocky Pulley. Tehtävienhallinnan laajentaminen DLL-injektiolla . koodiprojekti . CodeProject (19. toukokuuta 2005). Haettu 1. syyskuuta 2008. Arkistoitu alkuperäisestä 6. helmikuuta 2009. (määrätön)
- ↑ 1 2 Nasser R. Rowhani. DLL-injektion ja toimintojen sieppauksen opetusohjelma . koodiprojekti . CodeProject (23. lokakuuta 2003). Haettu 31. elokuuta 2008. Arkistoitu alkuperäisestä 15. kesäkuuta 2008. (määrätön)
- ↑ 1 2 3 Ivo Ivanov. API-kiinnitys paljastettiin . koodiprojekti . CodeProject (2. joulukuuta 2002). Haettu 31. elokuuta 2008. Arkistoitu alkuperäisestä 14. lokakuuta 2008. (määrätön)
- ↑ 1 2 3 Robert Kuster. Kolme tapaa syöttää koodisi toiseen prosessiin . koodiprojekti . CodeProject (20. elokuuta 2003). Haettu 31. elokuuta 2008. Arkistoitu alkuperäisestä 20. heinäkuuta 2008. (määrätön)
- ↑ AppInit_DLLs-rekisteriarvon käyttäminen . Microsoft (21. marraskuuta 2006). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 1. tammikuuta 2017.
- ↑ Raymond Chen. AppInit_DLL-tiedostot tulisi nimetä uudelleen Deadlock_Or_Crash_Randomly_DLLs . Vanha Uusi Asia . Microsoft (13. joulukuuta 2007). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 17. joulukuuta 2007.
- ↑ dllmain.c (englanniksi) (pääsemätön linkki - historia ) . React OS . React OS Foundation.
- ↑ "AtomBombing" Microsoft Windows Via Code Injection , Dark Reading (27. lokakuuta 2016). Arkistoitu 17. toukokuuta 2021. Haettu 28.12.2021.
- ↑ Trent Waddington. InjectDLL (englanniksi) (downlink) (31. elokuuta 2008). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 30. joulukuuta 2019.
- ↑ Dll-injektio (englanniksi) (downlink) . DreamInCode.net . MediaGroup1 (31. elokuuta 2008). Arkistoitu alkuperäisestä 2. syyskuuta 2008.
- ↑ Greg Jenkins. DLL Injection Framework (englanniksi) (linkki ei saatavilla) . Ring3 Circus (1. marraskuuta 2007). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 28. kesäkuuta 2020.
- ↑ Drew Benton. Täydellisempi DLL-injektioratkaisu CreateRemoteThreadin avulla . koodiprojekti . CodeProject (17. elokuuta 2007). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 28. joulukuuta 2021.
- ↑ SetWindowsHookEx- funktio . Alustan SDK Windows XP SP2:lle . Microsoft (31. elokuuta 2008). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 17. elokuuta 2016.
- ↑ AppInit_DLLs -rekisteriarvo ja Windows 95 . Microsoftin ohje ja tuki . Microsoft (1. maaliskuuta 2005). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 20. maaliskuuta 2016.
- ↑ Dll-injektio SetWindowsHookEx()- menetelmällä . Game Reversal (3. huhtikuuta 2008). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 4. huhtikuuta 2016.
- ↑ SetThreadContext DLL Injection ( 16. tammikuuta 2007). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 28. joulukuuta 2021.
- ↑ Ben Botto. DLL Injector (englanniksi) (linkki ei saatavilla) (6. syyskuuta 2008). Arkistoitu alkuperäisestä 7. helmikuuta 2009.
- ↑ Tietoturvaton kirjaston lataus saattaa sallia koodin suorittamisen etänä . Microsoft (20. huhtikuuta 2016). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 2. heinäkuuta 2017.
- ↑ Suojattu kirjastojen lataus estääksesi DLL-esilataushyökkäykset . Microsoft (10. kesäkuuta 2011). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 23. syyskuuta 2016.
- ↑ Microsoft Security Advisory: Tietoturvaton kirjaston lataus saattaa mahdollistaa koodin etäsuorittamisen . support.microsoft.com . Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 28. joulukuuta 2021. (määrätön)
- ↑ Endpoint Protection - Symantec Enterprise . Community.broadcom.com . Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 28. joulukuuta 2021. (määrätön)
- ↑ Torvalds, Linus; Linus Torvalds, David Engel, Eric Youngdale, Peter MacDonald, Hongjiu Lu, Lars Wirzenius, Mitch D'Souza. ld.so/ld-linux.so - dynaaminen linkki/lataaja (englanniksi) (linkki ei saatavilla) . UNIX-man sivut (14. maaliskuuta 1998). Arkistoitu alkuperäisestä 6. helmikuuta 2009.
- ↑ Peter Goldsborough. LD_PRELOAD temppu . Peter Goldsborough . Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 9. joulukuuta 2021. (määrätön)
- ↑ Koodin lisäys käynnissä olevaan Linux- sovellukseen ? . CodeProject (12. helmikuuta 2009). Haettu 28. joulukuuta 2021. Arkistoitu alkuperäisestä 28. joulukuuta 2021. (määrätön)