Recently just found that process injection technique are quite widely used in malware (e.g. IcedID). However, there are a lot of process injection technique in the wild. Click here for more information.
In this post, I would like to demonstrate one of the process injection technique, PE injection with a simple PoC.
Here is the overall flow of my PoC.
- Spawn a new process that duplicate itself.
- Create a mutex to prevent the new child process from spawning itself again.
- VirtualAlloc to adjust the relocation table for the newly spawned process.
- Open process to create a handle form the spawned process
- VirtualAllocEx to allocate address to be written in spawned process address space.
- Writing payload to new process via write memory process.
- Create remote thread to write the payload into the newly spawned process and execute it by pointing it to the payload function address.
Descriptions
By uisng the Windows API, we can use CreateProcess() to a new process. To spawn a self identical process, use GetCommandLine() (It will be the full path of the file execution name,
e.g. C:\Users\user\Desktop\PoC.exe) as the second parameter in CreateProcess().
The newly spawned process will keep replicate itself as there is no proper control. Therefore, a mutex is needed to halt the self replication process. Shown as below:
Next, to allocate the memory that need to be inject into new process, some PE header parsing is needed to get the image size of the current process image. IMAGE_OPTIONAL_HEADER.SizeOfImage is the size of the loaded executable/dll in virtual memory.
Create a handle for the spawned Process using OpenProcess(). Then, use VirtualAllocEx() to allocate the memory on the spawned process that will allocate for the payload.
There is a problem arise here as when a new process starts, the base address of the module is unpredictable and different from each process.
In this case, there is a need to change the base address of all data described using full address pointer. For that, we are going to use the process relocation section.
Base Relocation
Base Relocation Table is a table of pointers to every absolute address used in the code. You may check here for more detailed explaination.
General steps for base relocation:
1. Get the base address of .reloc
section.
2. Calculate the number of relocation descriptors.
3. Locate the address of data that need to be reallocate.
4. Replace it with new offset.
localImage is the during the runtime execution.
relocationTable->VirtualAddress = Virtual address of the .reloc
block
relocationRVA[i].Offset = Offset of the descriptor items in the block
It will loop through the descriptor items in the .reloc
block to rebase all the address at the last 12bit of descriptor as the it is the offset into the VirtualAddress of the containing relocation block.
5. Move to next .reloc
block.
6. Repeat (1–5). 👆
Writing Process and Payload Execution
After relocation finished, call WriteProcessMemory() to write the address of the new relocated based address into the spawned process and call CreateRemoteThread() to start the execution of the payload.
Write process memory:
CreateRemoteThread:
Here is the short Demo:
This PoC really helps me to understand more about the PE structure and Process injection. It is very helpful when dealing with malware that using process injection technique.
Full code here.
Extra Notes:
One simple trick based on my experiment:
Always look for the “RWX” protection to find out the injected process in memory sections.
From VirtualAllocEx, we already able to identify the memory address that will used to allocate the injected code.
Mutant Created
From the main process, look for the Handles section to check for the created mutant. Since the mutant is already created in main process, the child identical process will not create it again.
PE header Structure:
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeader->e_lfanew);
The e_lfanew will skip to DOS Stub and points to the PE signature in the COFF (Common Object File Format) header. It will then points to the OptionalHeader to retrieve necessary PE information.