Reflective Code Loading

Adversaries may reflectively load code into a process in order to conceal the execution of malicious payloads. Reflective loading involves allocating then executing payloads directly within the memory of the process, vice creating a thread or process backed by a file path on disk. Reflectively loaded payloads may be compiled binaries, anonymous files (only present in RAM), or just snubs of fileless executable code (ex: position-independent shellcode).[1][2][3][4][5]

Reflective code injection is very similar to Process Injection except that the "injection" loads code into the processes’ own memory instead of that of a separate process. Reflective loading may evade process-based detections since the execution of the arbitrary code may be masked within a legitimate or otherwise benign process. Reflectively loading payloads directly into memory may also avoid creating files or other artifacts on disk, while also enabling malware to keep these payloads encrypted (or otherwise obfuscated) until execution.[3][4][6][7]

ID: T1620
Sub-techniques:  No sub-techniques
Tactic: Defense Evasion
Platforms: Linux, Windows, macOS
Defense Bypassed: Anti-virus, Application control
Contributors: Joas Antonio dos Santos, @C0d3Cr4zy, Inmetrics; João Paulo de A. Filho, @Hug1nN__; Lior Ribak, SentinelOne; Rex Guo, @Xiaofei_REX, Confluera; Shlomi Salem, SentinelOne
Version: 1.0
Created: 05 October 2021
Last Modified: 21 April 2022

Procedure Examples

ID Name Description
S0154 Cobalt Strike

Cobalt Strike's execute-assembly command can run a .NET executable within the memory of a sacrificial process by loading the CLR.[8]

S0625 Cuba

Cuba loaded the payload into memory using PowerShell.[9]

S0695 Donut

Donut can generate code modules that enable in-memory execution of VBScript, JScript, EXE, DLL, and dotNET payloads.[10]

S0661 FoggyWeb

FoggyWeb's loader has reflectively loaded .NET-based assembly/payloads into memory.[11]

G0032 Lazarus Group

Lazarus Group has changed memory protection permissions then overwritten in memory DLL function code with shellcode, which was later executed via KernelCallbackTable hijacking. Lazarus Group has also used shellcode within macros to decrypt and manually map DLLs into memory at runtime.[12][13]

S0447 Lokibot

Lokibot has reflectively loaded the decoded DLL into memory.[14]

S0194 PowerSploit

PowerSploit reflectively loads a Windows PE file into a process.[15][16]

S0595 ThiefQuest

ThiefQuest uses various API functions such as NSCreateObjectFileImageFromMemory to load and link in-memory payloads.[17]

Mitigations

This type of attack technique cannot be easily mitigated with preventive controls since it is based on the abuse of system features.

Detection

ID Data Source Data Component
DS0011 Module Module Load
DS0009 Process OS API Execution
DS0012 Script Script Execution

Monitor for code artifacts associated with reflectively loading code, such as the abuse of .NET functions such as Assembly.Load() and Native API functions such as CreateThread(), memfd_create(), execve(), and/or execveat().[4][7]

Monitor for artifacts of abnormal process execution. For example, a common signature related to reflective code loading on Windows is mechanisms related to the .NET Common Language Runtime (CLR) -- such as mscor.dll, mscoree.dll, and clr.dll -- loading into abnormal processes (such as notepad.exe). Similarly, AMSI / ETW traces can be used to identify signs of arbitrary code execution from within the memory of potentially compromised processes.[18][1]

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.

References