Malware development: Process Injection with C++
·4 mins
Table of Contents
Introduction #
- In the previous article we explored how we can write a simple stageless C++ dropper. In this article we build upon the capabilities of the dropper by implementing process injection.
- Process injection is a well-known defense evasion technique that is used to hide code within the address space of another process. This allows an attacker to mask malicious code as a legitimate process in the system. It can also be used as a persistence technique by migrating to stable processes during post-exploitation.
High-Level Overview #
- We begin by selecting a target process i.e notepad.exe. We can select any standard process in the system provided we have the necessary permissions
- Open the process found and obtain a handle to it
- Allocate memory within that process through the handle we have
- Write our shellcode into the memory
- Execute the injected code.
- We can summarize the above into 2 main parts:
- Find a target process
- Injecting into the target process
- The final project file can be located here for quick reference: https://github.com/trevorsaudi/Process-Injection-cpp
1. Finding a Target Process #
CreateToolhelp32Snapshot #
- We use this function to create a snapshot of the specified processes in the system. This includes components and activities of the processes.
- Since we will be enumerating the processes in the system to find our target, we will utilize the
TH32CS_SNAPPROCESS
parameter that allows us to grab all processes in the system. The second parameter is ignored when we useTH32CS_SNAPPROCESS
so we place a0
for that - It returns a handle to the snapshot that’s why we define a
HANDLE
variable for it
PROCESSENTRY32 pe32 #
- This pre-defined windows data structure holds information about a single process when the snapshot was taken.
pe32
is an instance ofPROCESSENTRY32
.
pe32.dwSize
is a member of the PROCESSENTRY32 data structure. It represents the size of the structure in bytes. We grab the size of the structure usingsizeOf
Process32First and Process32Next #
- We will use these 2 APIs to enumerate through the running processes looking for a process with a specific name
- They both require the size of the structure to determine how much info to retrieve.
In line with the code block above, we get the first process from the snapshot we took, where,
hProcSnap
is a handle to the snapshot of processes andpe32
is aPROCESSENTRY32
structure which will get filled with information about a process.If the block of code fails to get a process for some reason, we close the handle.
We now proceed to find the target process below
- We use
Process32Next
, to get the information about the next process. This allows us to cycle through the snapshot. We then compare the name of the current process which is stored inpe32.szExeFile
with what we are looking forprocname
.
2. Injecting into the target process #
- This process involves us allocating memory to our target process, writing to it, and executing the shellcode from the process calling it.
VirtualAllocEx #
- We use this to allocate memory in the
target
process.
- The difference between the VirtualAllocEx and VirtualAlloc is that VirtualAlloc allocates memory within the address space of the
calling process
, while VirtualAllocEx lets youspecify a target process
to allocate memory.
WriteProcessMemory #
- We use this API to write into the memory in a specified address. We will utilize this to write our shellcode into the memory region we reserved in the target process.
CreateRemoteThread #
- This API is used to create a thread that runs in the address space of a target process. Our target is notepad.exe, this API will help us run our shellcode in that context
- We specify
hProc
, a handle to the process that we are injecting to. - We then use
WaitForSingleObject
to specify a timeout for the process.
3. Final Implant #
- The final process injection implementation:
- You can compile with cl.exe using the following flags
cl.exe /Ox /MT /W0 /GS- /DNDEBUG /Tcprocessinjection.cpp /link /OUT:processinjection.exe /SUBSYSTEM:CONSOLE /MACHINE:x64
Start notepad (or the process you are injecting into) before doing process injection.
- We can verify the messagebox was spawned in the context of Notepad using Process Hacker.
- Process Hacker is a tool that can help you monitor resources, debug software and detect malware.
- It has a functionality called “Find Window and Threads”, demonstrated below, which you can click then drag to a window to show the kind of resources (processes, threads, handles, etc) it is associated with.
- We can also see the memory region we had allocated for our target process, marked as RX (Read Executable) as shown below.
- This brings us to the end of our blog, hope you learned a ton!