MITRE ATT&CK – T1055: Process Injection
By Austin Miller
Those of you who have been reading our previous MITRE ATT&CK articles closely will have noticed that process injection is an extremely common and essential part of the modern adversary’s attack arsenal. Simply loading malware to a system doesn’t work anymore because modern tools can identify it straight away. But when it is hidden inside another process, the adversary has much more freedom.
As can be expected, process injection has a varied and difficult to manage toolkit – a security engineer setting out to stop all process injection would certainly be the modern-day Sisyphus! But understanding how the adversary will generally approach injection is the best form of defense, especially in acquiring tools to bolster your defenses.
How does process injection work?
Automated cybersecurity systems are smart. They’re not perfect, but they’re certainly smart enough to know that a file titled computerdestroyingvirus.exe which has been added to a database of known viruses is not good news. They instantly stop malicious processes, protecting systems and networks against the adversary.
Of course, threat actors weren’t going to take this response lying down. Although systems are good at spotting known dangers, injecting and encapsulating a process inside legitimate services allows processes which would otherwise be stopped to get inside the system. How do they do that? According to Picus’s research, there are 11 common methods that the adversary uses. Here are the six most common techniques and how the adversary leverages them to attack victim systems.
T1055.001 – Dynamic-link Library Injection
If you have been following this series closely or digging through the detail in our malware analysis, you will have noticed plenty of dynamic-link library (DLL) injections. This technique is extremely popular with the adversary and is an easy way to bypass a number of standard defenses when initial infection has been made. For those who don’t know, a DLL is simply a Windows file that contains code and data which multiple programs access.
A DLL attack must first write the path to the code into another process’s virtual address space. When the target process is identified – generally through APIs such as CreateToolhelp32Snapshot, Process32First, or Process32Next – the DLL is attached to the process and allocated in memory. At this point, the DLL is copied and then executed by the system.
Although some APIs such as LoadLibraryA register the loaded DLL (in turn, allowing for automated detection), this is not true of every one of them. These holes in the Windows defensive arsenal always give the adversary a way in, putting the defensive professional in a difficult position.
T1055.002 – Portable Executable Injection
Windows executables, object code, and DLLs use a file format named Portable Executable (PE). As with DLL injection, PE injection exploits a weakness in this relationship. By injecting malware into a process that is already running, PE will execute it through a small shellcode or through CreateRemoteThread. In some ways, this is preferrable for the adversary as it does not require a DLL to be on the disk.
PE injection is not perfect, however, says the threat actor. Without meddling, the PE will gain a new base address when it enters the victim system. The general adversarial approach is to launch the PE attack while also locating the host process’s relocation table address and resolving the cloned image’s addresses with a loop.
T1055.003 – Threat Execution Hijacking
Hijacking is a bit vogue in the hacking community right now. If there’s an unsecured process that can be exploited, the adversary has found a way to hijack it. For that reason, thread execution hijacking is an obvious inclusion in this list. Using living off the land (LotL) attacks, the adversary can exploit APIs to hijack and remotely execute processes.
For example, using OpenThread, the adversary can access a victim process. This can be suspended with SuspendThread and lead attached malware to the process via VirtualAllocEx. Once this code is written to the thread, a threat actor may even change the pointer of the process with SetThreadContext and then set it off into the wild with ResumeThread.
T1055.004 – Asynchronous Procedure Call
When an asynchronous procedure call (APC) is run, the system queues it on a thread. When this happens, the system generates a software interrupt – this is when the adversary can strike by identifying a target process ID and allocating memory within the process for malware. When the code is written and the appropriate thread is identified, the system will automatically load the APC to execute whenever it is next called.
Whenever the thread starts up again, the APC is executed and any arbitrary code that threat actors have attached to it will load as well.
T1055.005 – Thread Local Storage
Threat local storage (TLS) is a legitimate process on many systems that allows callback injection through changing pointers with a portable executable (PE). By manipulating pointers, the adversarial malware is initialized on every thread and bypasses standard debugging processes.
When this happens, you find yourself facing the issues that infamous malware like TrickBot or Ursnif/Gozi-ISFB bring. Manipulated TLS callbacks allow malicious code to run by allocating and writing to offsets within the memory space of a process.
T1055.006 – Ptrace System Calls
Using the Linux ptrace() system call is another way of running a process without setting off the alarms. Although the call is usually used fo debugging breakpoints and tracing system calls, in this case it can be used to execute arbitrary code that is written to a running process and then calling it with PTRACE SETREGS, setting the register to execute the next instruction.
How can I defend my organization?
Due to the varied approach that the adversary takes with process injection, defense can be difficult. But thanks to an overlap in some techniques – especially DLL injection and PE injection, two of the most common attack types – there are two techniques which allow better defenses against injections.
M1026 – Privileged Account Management
Using Yama is effective with Linux systems as it mitigates the use of ptrace-based process injections. This works by stopping this call from working unless it is started by a privileged user, allowing better defenses process injections. Of course, that just leads to the security professional agonizing over whether privilege escalation is suitably difficult for the adversary…
M1040 – Behaviour Prevention on Endpoint
Endpoints should be configured to block types of injections by looking for common sequences of behavior. The easiest example to implement is using Attack Surface Reduction (ASR) rules to stop attacks through Office applications.