Process Injection: Malware Lurking in the Shadows of Legitimate Programs (Part 1)
It's a Saturday afternoon, you're tinkering with your computer, and a random curiosity happens to pique your interest. You start taking a look at the current running processes on your computer as well as the network connections and other general information involving your PC. You happen to notice that explorer.exe, the process responsible for providing you with a graphic user interface (GUI) is responsible for a network connection to an IP address external to your network. You assume it's probably just part of some sort of Windows reporting functionality and move on.
To a threat hunter or incident response analyst, activity as described above would ring some alarm bells and warrant some investigation. At a glance, this would indicate some sort of process injection. In this part 1 of this 2-part blog series, we'll cover what process injection is and the variety of ways it can be achieved.
What is process injection?
As described by MITRE, "Process injection is a method of executing arbitrary code in the address space of a separate live process." There's a plethora of ways this can be achieved, and we'll be going over several of them below.
- Classic technique using CreateRemoteThread() and LoadLibraryA(): For this technique, the DLL must be written on disk. Let's say that Process B is the target process for injection. Using Process A, one can allocate memory in process B and provide the path to the malicious DLL. The path provided will be used by the LoadLibrary() function. From there, one will then get the address for the LoadLibrary() function and pass that information as an argument to CreateRemoteThread(). CreateRemoteThread() points to LoadLibrary(), and LoadLibrary() loads the DLL at the path it was provided. Adam Furmanek provides a simple and concise write up on this technique here.
- Reflective: Loading the DLL from memory rather than loading from disk. This method does not rely on a Windows loader and is therefore much stealthier than its counterparts.
- Loading DLLs via Registry: While this could be considered the "cheap shot" of DLL injection, since it's not really replacing any code or doing anything intricate, it's an effective way to get a program to load malicious code. At startup, Windows uses User32.dll to check the value of the following registry key:HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\LoadAppInit_DLLsIt does this because, if you recall earlier in the post, User32.dll is responsible for a lot of the graphic components that are loaded into Windows programs. If the value of this registry key is set to 1, then all of the DLLs found at the following registry key location will be loaded:HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLsFrom there, every program that uses User32.dll will load the DLLs listed at that registry location. This means that one could simply place the malicious DLL on that list and have it execute within the process memory; however it is worth noting that this would require administrative privileges.