Caricamento Riflessivo di Codice: Reflective Code Loading (T1620)

Il Reflective Code Loading è una tecnica di Defense Evasion (TA0005) in cui il codice malevolo viene allocato ed eseguito direttamente nella memoria del processo corrente, senza passare da un file su disco né creare thread o processi figli agganciati a percorsi filesystem. A differenza della Process Injection classica, qui non esiste scrittura cross-process: il payload — che può essere un binario PE compilato, un file anonimo residente solo in RAM o shellcode position-independent — vive e muore nello stesso PID che lo carica.

L'esempio canonico è l'invocazione di Assembly.Load() da PowerShell, che accetta un array di byte e lo esegue come assembly .NET nel runtime CLR ospitato dal processo. Il vantaggio per l'attaccante è duplice: si evade il monitoraggio basato su creazione file (nessun artefatto su disco) e si mimetizza l'esecuzione all'interno di processi legittimi o firmati, spesso mantenendo il payload cifrato fino al momento del caricamento.

I dati MITRE censiscono 4 gruppi APT, 22 famiglie di malware o tool offensivi e 2 campagne che sfruttano questa tecnica, con zero mitigazioni formalmente mappate — un dato eloquente sulla difficoltà di prevenire un comportamento che, a livello di API, è indistinguibile da usi legittimi di runtime dinamici come .NET, JIT compiler o loader di plugin.

Per simulare T1620 in un red team lab, il punto di partenza più semplice è PowerShell con Reflection.Assembly. Il pattern classico legge un payload .NET codificato in Base64, lo decodifica e lo esegue in-process:

[System.Reflection.Assembly]::Load([Convert]::FromBase64String($payload)).EntryPoint.Invoke($null,$null)

Questo è esattamente il pattern osservato in Kimsuky e nella campagna SharePoint ToolShell Exploitation, dove System.Reflection.Assembly.Load è stato usato post-exploit per eseguire assembly senza toccare il filesystem.

Per payload nativi PE, PowerSploit (open source, archiviato ma ancora funzionante) fornisce Invoke-ReflectivePEInjection, che mappa un PE in memoria replicando il lavoro del loader Windows. La sintassi tipica in lab è Invoke-ReflectivePEInjection -PEBytes $bytes -ForceASLR. Sempre in ambito .NET, Donut (open source) genera shellcode position-independent a partire da EXE, DLL, VBScript o JScript, producendo payload adatti sia a reflective loading sia a process injection: donut -a2 -f1 payload.exe -o shellcode.bin.

Sul lato framework C2, Cobalt Strike (a pagamento) espone execute-assembly, che carica il CLR in un processo sacrificale e vi esegue un assembly .NET arbitrario in memoria — tecnica ripresa da alternative come SILENTTRINITY (open source) e Brute Ratel C4 (a pagamento). Per esercizi più minimalisti, sRDI (Shellcode Reflective DLL Injection, open source su GitHub) converte una DLL in shellcode auto-caricante, utile per testare la detection senza dipendere da framework commerciali.

Su Linux il pattern equivalente sfrutta memfd_create(2) per creare un file descriptor anonimo in RAM, seguito da execveat(2) per eseguirlo senza mai materializzarlo sul filesystem visibile. Un PoC minimo scrive il payload nel memfd e invoca execveat(fd, "", argv, envp, AT_EMPTY_PATH). Su macOS l'analogo è NSCreateObjectFileImageFromMemory seguito da NSLinkModule, esattamente il pattern documentato in ThiefQuest.

In laboratorio è utile confrontare tre varianti: caricamento in processo padre (auto-injection), caricamento in processo sacrificale spawnato ad hoc (pattern execute-assembly) e caricamento tramite hijack di KernelCallbackTable come fatto da Lazarus Group. Per validare la detection, alternare allocazioni RWX e allocazioni RW+VirtualProtect a RX permette di misurare quali regole EDR reggono e quali cadono. Isolare tutto in VM snapshottate con Sysmon e AMSI attivi.

Vuoi diventare un Ethical Hacker ma non sai da dove iniziare?

Accedi alle lezioni gratuite e segui il percorso corretto fin dal primo passo

TEST GRATUITO
2 minuti · 7 domande Che professionista cyber sei? Scopri il profilo più vicino al tuo modo di pensare e inizia dal percorso giusto.