Standard process injection - Making the grunt work
Process injection is a method of executing arbitrary code in the address space of a separate live process. Running code in the context of another process may allow access to the process’s memory, system/network resources, and possibly elevated privileges. Execution via process injection may also evade detection from security products since the execution is masked under a legitimate process.
Process injection in windows
There are multiple approaches to injecting code into a live process. Windows implementations include Reference from ATT&CK:
Dynamic-link library (DLL) injection involves writing the path to a malicious DLL inside a process then invoking execution by creating a remote thread.
Portable executable injection involves writing malicious code directly into the process (without a file on disk) then invoking execution with either additional code or by creating a remote thread. The displacement of the injected code introduces the additional requirement for functionality to remap memory references. Variations of this method such as reflective DLL injection (writing a self-mapping DLL into a process) and memory module (map DLL when writing into process) overcome the address relocation issue.
Asynchronous Procedure Call (APC) injection involves attaching malicious code to the APC Queue of a process’s thread. Queued APC functions are executed when the thread enters an alterable state. A variation of APC injection, dubbed “Early Bird injection”, involves creating a suspended process in which malicious code can be written and executed before the process’ entry point (and potentially subsequent anti-malware hooks) via an APC. AtomBombing is another variation that utilizes APCs to invoke malicious code previously written to the global atom table.
Thread Local Storage (TLS) callback injection involves manipulating pointers inside a portable executable (PE) to redirect a process to malicious code before reaching the code’s legitimate entry point.
I am going to look at multiple different techniques of using process injection with this entry and show some demo’s on how this can be used. 3xpl01tc0d3r released a cool tool that will be able to perform the 4 techniques I want to cover in this blog.
- Windows 10 Victim - Patched & Running Windows Defender
- Kali Linux waiting to recieve shellz
- Preconfigured Covenant with docker
- Donut - latest release
- ProcessInjection by 3xpl01tc0d3r
For the demo’s we are going to run through I want to use something called Donut which will generate shellcode for us, and since this tool can take any .NET assembly input we will generate the payloads in Covenant C2 framework.
Donut is a position-independent code that enables in-memory execution of VBScript, JScript, EXE, DLL files and dotNET assemblies. A module created by Donut can either be staged from a HTTP server or embedded directly in the loader itself.
Covenant is a .NET command and control framework that aims to highlight the attack surface of .NET, make the use of offensive .NET tradecraft easier, and serve as a collaborative command and control platform for red teamers.
I am not going to show you how to setup Covenant, you can find the resources in the projects repository, but this is how I built the docker container:
//Build docker container $ ~/Covenant/Covenant > docker build -t covenant . $ ~/Covenant/Covenant > docker run -it -p 7443:7443 -p 80:80 -p 443:443 --name covenant covenant --username AdminUser --computername 0.0.0.0
Then we can login with our credentials and we will see Covenents GUI:
First process injection we are going to use is standard. We are going to take the covenant binary launcher, use donut to generate our shellcode and then inject the shellcode in to a process on the victim host.
Before we can start though we need to setup a listener within Covenent first:
Generate the binary and save the file to disk:
Then we need to use donut to generate the shellcode:
Then we can just identify the process we are trying to inject in to:
- We are going to use notepad.exe (PID 4932)
At this point we should see a connection coming back to our Covenant C2 instance. That is a pretty basic way to use Process injection with Covenant. Stay tuned for other entries!