Process Injection

The most popular covert launching technique is process injection. As the name implies, this technique injects code into another running process, and that process unwittingly executes the malicious code. Malware authors use process injection in an attempt to conceal the malicious behavior of their code, and sometimes they use this to try to bypass host-based firewalls and other process-specific security mechanisms.

Certain Windows API calls are commonly used for process injection. For example, the VirtualAllocEx function can be used to allocate space in an external process’s memory, and WriteProcessMemory can be used to write data to that allocated space. This pair of functions is essential to the first three loading techniques that we’ll discuss in this chapter.

DLL Injection

DLL injection—a form of process injection where a remote process is forced to load a malicious DLL—is the most commonly used covert loading technique. DLL injection works by injecting code into a remote process that calls LoadLibrary, thereby forcing a DLL to be loaded in the context of that process. Once the compromised process loads the malicious DLL, the OS automatically calls the DLL’s DllMain function, which is defined by the author of the DLL. This function contains the malicious code and has as much access to the system as the process in which it is running. Malicious DLLs often have little content other than the Dllmain function, and everything they do will appear to originate from the compromised process.

Figure 12-1 shows an example of DLL injection. In this example, the launcher malware injects its DLL into Internet Explorer’s memory, thereby giving the injected DLL the same access to the Internet as Internet Explorer. The loader malware had been unable to access the Internet prior to injection because a process-specific firewall detected it and blocked it.

DLL injection—the launcher malware cannot access the Internet until it injects into iexplore.exe.

Figure 12-1. DLL injection—the launcher malware cannot access the Internet until it injects into iexplore.exe.

In order to inject the malicious DLL into a host program, the launcher malware must first obtain a handle to the victim process. The most common way is to use the Windows API calls CreateToolhelp32Snapshot, Process32First, and Process32Next to search the process list for the injection target. Once the target is found, the launcher retrieves the process identifier (PID) of the target process and then uses it to obtain the handle via a call to OpenProcess.

The function CreateRemoteThread is commonly used for DLL injection to allow the launcher malware to create and execute a new thread in a remote process. When CreateRemoteThread is used, it is passed three important parameters: the process handle (hProcess) obtained with OpenProcess, along with the starting point of the injected thread (lpStartAddress) and an argument for that thread (lpParameter). For example, the starting point might be set to LoadLibrary and the malicious DLL name passed as the argument. This will trigger LoadLibrary to be run in the victim process with a parameter of the malicious DLL, thereby causing that DLL to be loaded in the victim process (assuming that LoadLibrary is available in the victim process’s memory space and that the malicious library name string exists within that same space).

Malware authors generally use VirtualAllocEx to create space for the malicious library name string. The VirtualAllocEx function allocates space in a remote process if a handle to that process is provided.

The last setup function required before CreateRemoteThread can be called is WriteProcessMemory. This function writes the malicious library name string into the memory space that was allocated with VirtualAllocEx.

Example 12-1 contains C pseudocode for performing DLL injection.

Example 12-1. C Pseudocode for DLL injection

  hVictimProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, victimProcessID );

  pNameInVictimProcess = VirtualAllocEx(hVictimProcess,...,sizeof(maliciousLibraryName),...,...);
  WriteProcessMemory(hVictimProcess,...,maliciousLibraryName, sizeof(maliciousLibraryName),...);
  GetModuleHandle("Kernel32.dll");
  GetProcAddress(...,"LoadLibraryA");
 CreateRemoteThread(hVictimProcess,...,...,LoadLibraryAddress,pNameInVictimProcess,...,...);

This listing assumes that we obtain the victim PID in victimProcessID when it is passed to OpenProcess at in order to get the handle to the victim process. Using the handle, VirtualAllocEx and WriteProcessMemory then allocate space and write the name of the malicious DLL into the victim process. Next, GetProcAddress is used to get the address to LoadLibrary.

Finally, at , CreateRemoteThread is passed the three important parameters discussed earlier: the handle to the victim process, the address of LoadLibrary, and a pointer to the malicious DLL name in the victim process. The easiest way to identify DLL injection is by identifying this trademark pattern of Windows API calls when looking at the launcher malware’s disassembly.

In DLL injection, the malware launcher never calls a malicious function. As stated earlier, the malicious code is located in DllMain, which is automatically called by the OS when the DLL is loaded into memory. The DLL injection launcher’s goal is to call CreateRemoteThread in order to create the remote thread LoadLibrary, with the parameter of the malicious DLL being injected.

Figure 12-2 shows DLL injection code as seen through a debugger. The six function calls from our pseudocode in Example 12-1 can be seen in the disassembly, labeled through .

DLL injection debugger view

Figure 12-2. DLL injection debugger view

Once you find DLL injection activity in disassembly, you should start looking for the strings containing the names of the malicious DLL and the victim process. In the case of Figure 12-2, we don’t see those strings, but they must be accessed before this code executes. The victim process name can often be found in a strncmp function (or equivalent) when the launcher determines the victim process’s PID. To find the malicious DLL name, we could set a breakpoint at 0x407735 and dump the contents of the stack to reveal the value of Buffer as it is being passed to WriteProcessMemory.

Once you’re able to recognize the DLL injection code pattern and identify these important strings, you should be able to quickly analyze an entire group of malware launchers.

Direct Injection

Like DLL injection, direct injection involves allocating and inserting code into the memory space of a remote process. Direct injection uses many of the same Windows API calls as DLL injection. The difference is that instead of writing a separate DLL and forcing the remote process to load it, direct-injection malware injects the malicious code directly into the remote process.

Direct injection is more flexible than DLL injection, but it requires a lot of customized code in order to run successfully without negatively impacting the host process. This technique can be used to inject compiled code, but more often, it’s used to inject shellcode.

Three functions are commonly found in cases of direct injection: VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread. There will typically be two calls to VirtualAllocEx and WriteProcessMemory. The first will allocate and write the data used by the remote thread, and the second will allocate and write the remote thread code. The call to CreateRemoteThread will contain the location of the remote thread code (lpStartAddress) and the data (lpParameter).

Since the data and functions used by the remote thread must exist in the victim process, normal compilation procedures will not work. For example, strings are not in the normal .data section, and LoadLibrary/GetProcAddress will need to be called to access functions that are not already loaded. There are other restrictions, which we won’t go into here. Basically, direct injection requires that authors either be skilled assembly language coders or that they will inject only relatively simple shellcode.

In order to analyze the remote thread’s code, you may need to debug the malware and dump all memory buffers that occur before calls to WriteProcessMemory to be analyzed in a disassembler. Since these buffers most often contain shellcode, you will need shellcode analysis skills, which we discuss extensively in Chapter 19.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.36.38