T1055
Process Injection
Process Injection continues to be a versatile tool that adversaries lean on to evade defensive controls and gain access to sensitive systems and information.
Pairs with this song#7
Rank
13.8%
Percent of customers affected
447
Total threat volume
Threat Sounds
Code can inherit the privilege level of the process it’s injected into, so adversaries often run run run seemingly benign processes as proxies to have a little fun.
Editor’s note: While the detection opportunities and analysis on this page are still relevant, it has not been updated since 2023.
Analysis
Why do adversaries use Process Injection?
Note: Process Injection comprises multiple sub-techniques, but we largely map our detection analytics to the parent. As such, this section focuses generally on the overall technique and not on any individual sub-techniques.
Process Injection is a versatile technique that adversaries leverage to perform a wide range of malicious activity. It’s so versatile that ATT&CK includes 12 sub-techniques of Process Injection. Adversaries perform process injection because it allows them to execute malicious activity by proxy through processes that either have information of value (e.g., lsass.exe
) or that blend in with benign operating system activity.
In addition to being stealthy, code can inherit the privilege level of the process it’s injected into and gain access to parts of the operating system that shouldn’t be otherwise available. Another added benefit of process injection is that it allows payloads to be launched within the memory space of a running process without needing to drop any malicious code to disk.
For example, you may be able to build a high-fidelity detection analytic that triggers any time PowerShell makes an external network connection. However, to avoid this method of detection, an adversary might inject their PowerShell process into a browser. In doing so, they’ve taken a potentially suspicious behavior—PowerShell making an external network connection—and replaced it with a seemingly normal behavior—a browser making an external network connection. What was detectable based on process lineage and network connections before process injection now relies on a mix of command-line parameters and binary metadata, to name a couple of telemetry sources.
How do adversaries use Process Injection?
With 12 sub-techniques, there’s no shortage of ways that an adversary can perform Process Injection. However, most of the injection behaviors we detect can be classified into just two categories:
- Evasion: Adversaries inject into a process that is functionally necessary and can’t be killed, that naturally makes high volumes of network connections or module loads, or that allows an adversary to perform an action that seems suspicious in the context of one process but benign in the context of another (e.g., making a network connection).
- Data theft: Adversaries inject into a process that gives them the ability to harvest sensitive information like credentials or otherwise abuse the capabilities of that process.
Across our data set, PowerShell is the most common culprit of process injection, and it injects into many processes to achieve many different goals. Some other process injectors include Microsoft Office applications, regsvr32.exe
, rundll32.exe
, lsass.exe
, and spoolsv.exe
.
Inversely, we detect adversaries injecting into a long list of processes, including the following:
lsass.exe
(credential theft)calc.exe
(evasion)notepad.exe
(evasion)svchost.exe
(evasion and credential theft)backgroundtaskhost.exe
(application control bypass)dllhost.exe
(commonly used to host COM components, adversaries often inject into this process in order to blend in to a process that executes often and is expected to have a short lifetime)regsvr32.exe
(application control bypass and other evasion)searchprotocolhost.exe
(application control bypass and other evasion).werfault.exe
(evasion)wuauclt.exe
(evasion)spoolsv.exe
(evasion)- browser processes (normalizing network connections, info stealing/banking trojans)
The prevalence of process injection is buoyed in part by popular and widely available malware kits like Cobalt Strike, Metasploit, and other offensive tools that considerably lower the barrier of entry. What once existed mostly in the domain of more capable adversaries has since trickled down to nearly everyone else.
Associated threats
- Nitol botnet
- Qbot
- Cobalt Strike
- Mimikatz
- Dumpert
take action
There’s no easy way to broadly mitigate all forms of Process Injection because it’s a legitimate feature that was intentionally designed into the Windows operating system. However, on a strategic level, defenders can prevent certain kinds of arbitrary code execution with application control solutions like AppLocker and Windows Defender Application Control—and via Microsoft Defender’s Attack Surface Reduction (ASR) rules.
Another approach to mitigating Process Injection could include implementing Windows Defender Exploit Guard (WDEG), which includes features like Arbitrary Code Guard and Export/Import Address Table Access Filtering. Further, defenders can prevent certain forms of LSASS injection by implementing LSA Injection Prevention, which prevents all but protected processes from injecting into LSASS.
Visibility
Note: The visibility sections in this report are mapped to MITRE ATT&CK data sources and components.
Process access activity specifically offers visibility into cross-process events and process injection, but it’s false positive prone and there are many other data sources that you can combine to develop robust detection coverage. Most commercial EDR products and many other security tools will collect the following data sources.
Process monitoring
Process monitoring is a minimum requirement for reliably detecting process injection. Even though injection can be invisible to some forms of process monitoring, the effects of the injection become harder to miss once you compare process behaviors against expected functionality. The overwhelming majority of analytics we’ve developed to catch process injection look for at least one process, often a process executing without a corresponding command line.
Process access monitoring
Cross-process or process access events are an extremely rich source of visibility for process injection-related activity. However, this data source can also include a lot of noise, since there are many legitimate reasons for cross-process access.
Command monitoring
Monitoring for suspicious command-line parameters can be an effective way of observing and detecting potential process injection at scale. In some cases, specific command-line parameters may be an indicator of process injection. However, much of the time, it’s the absence of a command line in conjunction with certain processes that alerts us to process injection.
Network monitoring
Process injection-as-evasion sometimes includes a process that doesn’t usually make network connections (e.g., notepad.exe
) injecting into a process that does (e.g., a browser). In these and other cases, network connection telemetry can be a great source for detection enrichment.
Module loads
Since process injection occasionally involves DLLs, collecting information on modules can also help enrich your detection data.
Most commercial EDR products and many other security tools will collect the following data sources, and honestly are needed to effectively attempt to leverage injection telemetry as a detection source at scale.
Collection
Note: The collection sections of this report showcase specific log sources from Windows events, Sysmon, and elsewhere that you can use to collect relevant security information.
Sysmon Event ID 10: ProcessAccessed
Sysmon Event ID 10 tracks ProcessAccess or cross-process events, generating a log entry whenever one process opens another process. While malicious process injection necessarily involves one process accessing another, there are many legitimate reasons for process access as well. Therefore, this event ID will likely generate a lot of noise without filtering out known benign cross-process behavior.
Windows Event Event ID 4663: LSASS Access
Introduced in Windows 10, when a handle to lsass.exe
is granted, Windows will natively log a 4633 event to the Security log. Kernel object auditing must be enabled in order to surface these events.
Windows Security Event ID 4688: Process Creation
Process Creation (4688) events with command-line argument logging enabled is a great source of telemetry for process starts and commands lines—or, as is often the case with process injection, a lack thereof.
Sysmon Event ID 1: Process creation
Sysmon process creation events are another rich source of telemetry for detecting process injection. Like Windows Security Event ID 4688, process creation events track process starts and corresponding command lines.
LSASS System Access Control List (SACL) auditing
Added in Windows 10, LSASS SACL auditing records all processes that attempt to access lsass.exe
, a common target of process injection.
Endpoint Detection and Response (EDR) tools
Many EDR tools will gather telemetry from different sources—like those mentioned above and more—that can be cobbled together in search of malicious process injection.
Detection opportunities
We have more than 127 detection analytics that seek out various forms of process injection. By and large, these analytics look for legitimate processes doing unexpected things like making external network connections, writing files, or spawning with unexpected command-line arguments—including no command-line arguments at all.
PowerShell injecting into… anything
There’s some exceptions here—surely varying from one environment to the next—but, generally speaking, you’ll want to be wary of process access activity where PowerShell is accessing any other processes.
process == powershell.exe
&&
cross_process_handle_into [any other process]
Process executing sans command lines
One major tell for process injection is the absence of command lines. Detecting the absence of anything, including a command line, can be tricky, and this pseudo-analytic only works for processes where you expect corresponding commands. However, you may be able to iterate on the following amalgamation of detection logic to improve detection coverage. Hint: adding a network connection or child process execution to these may help you home in on malice.
process == ('backgroundtaskhost.exe' || 'svchost.exe' || 'dllhost.exe' || 'werfault.exe' || 'searchprotocolhost.exe' || 'wuauclt.exe' || 'spoolsv.exe' || 'rundll32.exe' || 'regasm.exe' || 'regsvr32.exe' || 'regsvcs.exe')
&&
command == (“”)*
*Empty quotes (i.e., “”) signify a blank command line.
Network connections where there shouldn’t be
Detecting purely on processes making network connections has the potential to generate a torrent of false positives. However, it can also identify suspicious injection activity—particularly if you tune the logic to filter out the eccentricities in your specific environment.
Process == notepad.exe
&&
has_network_connection
Injection into LSASS
Since injection into lsass.exe
is common, impactful, and frequently suspicious, it deserves to be called out individually. To that point, it would be worth your time to determine and enumerate the processes in your environment that routinely or occasionally obtain a handle to lsass.exe
. Any access outside of the baseline should be treated as suspicious. The following analytic offers a good starting place with a pattern of behavior that is very commonly malicious:
process == rundll32.exe
&&
cross_process_handle_into ('lsass.exe')
Weeding out false positives
The analytics that produced the most false positives in our dataset came from looking for CreateRemoteThread
calls. Many tools in Windows use process injection legitimately for debugging and virtualization. If you want to write analytics around this API call, focus them on unusual source processes, such as Microsoft Office products and tools that commonly deliver first-stage malware like scripts and Mshta.
Further, processes like lsass.exe
and svchost.exe
are both common targets for process injection and common processes in general. As such, baselining normal against abnormal will be an important step in fighting false positives:
- In some environments, you might be able to detect reliably on specific processes injecting into
lsass.exe
. However, you might achieve better detection outcomes by correlating cross processes with executing processes, including LOLBINs like MSbuild, PowerShell, Wscript, Cscript, Msiexec, Rundll32, and more. - Additionally, adversaries often attempt to use
svchost.exe
for process injection. Due to the large volume, taking the approach of identifying known processes that may execute code can help reduce the amount of noise generated.
Testing
Start testing your defenses against Process Injection using Atomic Red Team—an open source testing framework of small, highly portable detection tests mapped to MITRE ATT&CK.
Getting started
View atomic tests for T1055: Process Injection. In most environments, these should be sufficient to generate a useful signal for defenders.
Run this test on a Windows system using an elevated PowerShell prompt:
mavinject.exe ((Get-Process lsass).Id) /INJECTRUNNING C:\Windows\System32\vbscript.dll
What to expect
mavinject.exe
will inject vbscript.dll
into the running lsass.exe
process using Dynamic-link Library Injection. We chose to use mavinject.exe
as an example for its simplicity.
Useful telemetry will include:
Visibility | Telemetry | Collection |
---|---|---|
Visibility : Process monitoring | Telemetry: A | Collection: EDR, Sysmon Events ID 1 and 10, and Windows Event IDs 4688 and 4633 should collect relevant telemetry. |
Visibility : Command monitoring | Telemetry: Command-line logging will capture the context of what is executed. | Collection: EDR, Sysmon Event ID 1, and Windows Event ID 4688 should collect relevant telemetry. |
Visibility : Module monitoring | Telemetry:
| Collection: EDR and Sysmon Event ID 7 should collect relevant telemetry. |
A more detailed test
The mavinject.exe
test above offers defenders a really simple way to test their ability to observe and detect process injection. The following, however, is a more in-depth test that will inject and execute benign shellcode into a notepad.exe
process. This test replicates T1055.002: Portable Executable Injection. Copy it into a PowerShell prompt.
# Start a notepad process. This will be our injection target
$NotepadProcess = Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine = 'notepad.exe' }
# Compile and load Windows API functions that will be needed to inject into another process
Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;
namespace Win32 {
public class NativeMethods {
[DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr OpenProcess(int processAccess, bool bInheritHandle, int processId);
[DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, int flAllocationType, int flProtect);
[DllImport("kernel32.dll", SetLastError = true)] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, ref uint lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)] public static extern bool CloseHandle(IntPtr hObject);
[DllImport("ntdll.dll")] public static extern int RtlCreateUserThread(IntPtr ProcessHandle, IntPtr SecurityDescriptor, bool CreateSuspended, IntPtr StackZeroBits, IntPtr StackReserved, IntPtr StackCommit, IntPtr StartAddress, IntPtr StartParameter, ref IntPtr ThreadHandle, ref IntPtr ClientID);
}
}
'@
# Benign shellcode to inject into notepad - 0x90 (NOP), 0x90 (NOP), 0x90 (NOP), 0xC3 (RET)
[Byte[]] $Code = @(0x90, 0x90, 0x90, 0xC3)
# Obtain a handle to the open notepad process
$TargetProcessHandle = [Win32.NativeMethods]::OpenProcess(0x001FFFFF, $False, $NotepadProcess.ProcessId)
# Allocate read/write/execute memory in the notepad process for the shellcode
$TargetProcessBaseAddress = [Win32.NativeMethods]::VirtualAllocEx($TargetProcessHandle, [IntPtr]::Zero, $Code.Length, 0x3000, 0x40)
# Write the shellcode buffer to the notepad process
$BytesWritten = 0
$null = [Win32.NativeMethods]::WriteProcessMemory($TargetProcessHandle, $TargetProcessBaseAddress, $Code, $Code.Length, [Ref] $BytesWritten)
# Execute the shellcode in the notepad process
[IntPtr] $RemoteThreadHandle = [IntPtr]::Zero
[IntPtr] $CliendId = [IntPtr]::Zero
$null = [Win32.NativeMethods]::RtlCreateUserThread($TargetProcessHandle, [IntPtr]::Zero, $False, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero, $TargetProcessBaseAddress, [IntPtr]::Zero, [Ref] $RemoteThreadHandle, [Ref] $CliendId)
# Cleanup
$null = [Win32.NativeMethods]::CloseHandle($RemoteThreadHandle)
$null = [Win32.NativeMethods]::CloseHandle($TargetProcessHandle)
Stop-Process -Id $NotepadProcess.ProcessId
What to expect
powershell.exe
will inject shellcode into notepad.exe
and have notepad.exe
execute the shellcode.
Useful telemetry will include:
Visibility | Telemetry | Collection |
---|---|---|
Visibility: Process monitoring | Telemetry:
| Collection: EDR, Sysmon Event IDs 1 and 10, and Windows Event ID 4688 relevant telemetry. |
Visibility: Command monitoring | Telemetry: Command-line logging will capture the context of what is executed. | Collection: EDR, Sysmon Event ID 1, Windows Event IDs 4688, 4104, 4103, and 800, and AMSI should collect relevant telemetry. |
If you’d like to conduct more advanced testing for Process Injection, consider leveraging the Atomic Test Harness for Process Injection.
Review and repeat
Now that you have executed one or several common tests and checked for the expected results, it’s useful to answer some immediate questions:
- Were any of your actions detected?
- Were any of your actions blocked or prevented?
- Were your actions visible in logs or other defensive telemetry?
Repeat this process, performing additional tests related to this technique. You can also create and contribute tests of your own.