Dnes si priblížime fungovanie a spôsoby zavádzania obsahu infikovaných knižníc do bežiacích procesov, aneb metódy zavádzania modulov - Inline Hooking Dll.
Metóda "Inline Hook Dll" popisuje spôsoby zavedenia infikovaného kódu, ktorý sa nachádza v knižnici .dll, pripojením priamo na spustený proces.
Inline Hooking som popísal v prezentácii, ktorú je možno stiahnuť odtialto:
Pripojenie sa realizuje alokovaním pamäťového miesta v operačnej pamäti, na adrese obsahu spusteného procesu, na ktorý chceme knižnicu zavesiť. Do alokovaného miesta sa pripojí obsah knižnice.
Vloženie (injecting) knižnice do adresného pamätového miesta procesu umožňuje:
● pripojenie knižnice do práve bežiaceho procesu
● knižnica je načítaná vždy, pokým proces beží
● vstupný bod (entry point) knižnice je spúšťaný vždy pri pripojení alebo odpojení knižnice na/z bežiaceho procesu
a vždy pri pustený/ukončení vlákna procesu
● knižnica je odpojená z operačnej pamäte po ukončení procesu, na ktorom je pripnutá
Metódy pre Inline DLL Hooking:
Win.API - CreateRemoteThread()
NTApi - NtCreateThread(), ZwCreateThread()
Postup Hookovania knižnice do bežiaceho procesu:
1 - zistenie referencie na process, do ktorého chceme knižnicu pripojiť
2 - zistenie referencií knižníc, ktorých metódy na zavedenie knižnice použijeme (ntdll, kernel32)
3 - alokovanie pamäťi ového miesta pre
4 - vloženie kódu infikovanej knižnice do alokovaného miesta
5 - zvolenie metódy pre vytvorenie Inline Hooku (ZwCreateThread, NtCreateThread, CreateRemoteThread)
6 - spustenie injectovaného kódu - Routime
Pred Inline Hooku:
Po Inline Hooku:
Po IAT Hooku:
1 - zistenie referencie hookovaného procesu:
HANDLE dProcessHandle = ::GetProcessHandle("taskend.exe");
2 - zistenie referencií knižníc:
::HANDLE dModuleNTDll = ::GetModuleHandleA("ntdll");
::HANDLE dModuleKernel = ::GetModuleHandleA("Kernel32");
3 - alokovanie pamäť:
::LPVOID dMemoryAlloc = ::VirtualAllocEx(dProcessHandle, null, ::strlen("e:\\plugin\\plugin.dll"),
::MEM_COMMIT, PAGE_READWRITE);
4 - vloženie kódu infikovanej knižnice do alokovaného miesta:
::bool result = ::VriteProcessMemory(dProcessHandle, dMemoryAlloc, "e:\\plugin\\plugin.dll",
::strlen("e:\\plugin\\plugin.dll"), null);
5 - zvolenie metódy pre vytvorenie Inline Hooku:
NtCreateThreadExD = (NtCreateThreadExD) ::GetProcAddress(dModuleNTDll, "ZwCreateThreadEx");
/* For ZwCreateThreadEx() method) */
6 - spustenie injectovaného kódu:
DWORD dCurrentThread;
dCurrentThread = NtCreateThreadExD(&dCurrentThread, 0x1FFFFF, null, dProcessHandle,
(LPTHRED_START_ROUTIME)::GetProcAddress(dModuleKernel, "LoadLibraryA"),
dMemoryAlloc,
false,
null,
null, null,
&NtCreateThreadExStack);
Z popisu sme dospeli k názoru, že pre Inline Hooking, potrebujeme knižnicu obsahujúcu implementovaný kód, proces na ktorý chceme knižnicu privesiť a medzi-súbor - injector, ktorý hook zavedie.
Pri hookingu si je nutné uvedomiť, že môžeme hookovať procesy len s rovnakou autoritou, ktorú má náš injector. Pokiaľ nám injector beží na okruhu Ring3, nemôžeme hookovať procesy, s nižším okruhom, respektíve s vyššou prioritou.
Program spustený v režime Ring0 (kernel mode), má oprávnenie pristupovať, modifikovať,... všetky objekty vrátane systémových (csrss.exe, smss.exe,...).
O právach na úrovni Ring0 a podobne si popíšeme inokedy.
Obsah knižnice, ktorú chceme hookingom pripojiť na proces:
#include <windows.h>
bool APIENTRY DllMain(::HANDLE hModule, ::DWORD ul_reason_for_call, ::LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL, ::LPCWSTR(L"Dll was injected into process"), ::LPCWSTR(L"Injected"), MB_ICONWARNING);
/* execute code */
break;
case DLL_THREAD_ATTACH:
MessageBox(NULL, ::LPCWSTR(L"Dll detected start thread"), ::LPCWSTR(L"Thread detecting"), MB_ICONWARNING);
/* execute code */
break;
case DLL_THREAD_DETACH:
MessageBox(NULL, ::LPCWSTR(L"Dll detected stop thread"), ::LPCWSTR(L"Thread detecting"), MB_ICONWARNING);
/* execute code */
break;
case DLL_PROCESS_DETACH:
MessageBox(NULL, ::LPCWSTR(L"Injected process is terminating"), ::LPCWSTR(L"Terminate"), MB_ICONWARNING);
/* execute code */
break;
}
return true ;
}
Injector v akcii: