Codice Spazzatura: Junk Code Insertion (T1027.016)
L'inserimento di codice spazzatura è una tecnica di offuscamento in cui l'avversario aggiunge al binario malevolo istruzioni che non vengono eseguite oppure che, pur essendo eseguite, non alterano il comportamento reale del programma. L'esempio classico in assembly x86 è l'istruzione NOP (opcode 0x90), ma il concetto si estende a chiamate API fittizie, cicli infiniti irraggiungibili, blocchi matematici ridondanti e funzioni benigne intercalate al codice funzionale.
La tecnica ricade sotto TA0005 (Defense Evasion) e ha un duplice obiettivo: rallentare l'analista che deve avanzare passo-passo attraverso istruzioni inutili in un debugger, e ingannare i motori di analisi statica che valutano il rapporto tra funzionalità benigne e malevole di un binario. È particolarmente efficace quando combinata con Software Packing o Compression, perché la superficie di codice apparentemente legittimo diluisce le firme di rilevamento.
A differenza del Binary Padding (T1027.001), che mira solo a modificare l'hash del file, qui l'intento è offuscare la logica: il codice spazzatura è funzionalmente indistinguibile dal codice vero senza un'analisi semantica profonda. I dati MITRE ATT&CK documentano 5 gruppi APT e 14 famiglie malware che adottano questa pratica, tra cui ransomware come Maze e WastedLocker, stealer come StrelaStealer e impianti di gruppi statali come Gamaredon, APT32 e Kimsuky.
Per un red team, simulare l'inserimento di junk code serve a validare l'efficacia dei motori EDR basati su analisi statica e sandbox. L'approccio operativo si articola su tre livelli: sorgente, compilazione e post-compilazione.
A livello sorgente, in un progetto C/C++ puoi intercalare blocchi condizionali sempre falsi che il compilatore non ottimizzi. Un pattern comune è dichiarare una variabile volatile impostata a runtime da una funzione opaca e usarla in confronti che il compilatore non può ridurre. In assembly inline con GCC, l'istruzione asm volatile("nop"); ripetuta genera padding 0x90 preservato dall'ottimizzatore.
A livello compilazione, il progetto Obfuscator-LLVM (open source) e il suo fork attivo Hikari offrono passi di offuscamento tra cui bogus control flow e instruction substitution, che espandono il grafo di controllo con blocchi mai raggiungibili. Per binari .NET, tool come ConfuserEx (open source) inseriscono metodi wrapper e istruzioni IL ridondanti, replicando lo stile osservato in Gamaredon.
A livello post-compilazione, framework come Donut (open source) generano shellcode con opzioni di padding, mentre packer commerciali come VMProtect o Themida (a pagamento) combinano virtualizzazione e junk code massivo. Per test lab-safe si può usare UPX (open source) come baseline di packing, sapendo però che è banalmente riconosciuto.
Una catena tipica per emulare il comportamento di Maze o WastedLocker parte da un loader in C che decodifica il payload solo dopo aver eseguito centinaia di operazioni matematiche fittizie (moltiplicazioni modulari, hashing di stringhe mai usate). Questo pattern, osservato in StrelaStealer, ha l'effetto collaterale di esaurire il timeout di molte sandbox automatizzate (tipicamente 60-120 secondi).
Per verificare l'efficacia in laboratorio, calcola l'entropia del binario risultante con ent (open source) o binwalk -E (open source): valori sopra 7.5 suggeriscono packing/cifratura, mentre distribuzioni anomale di opcode 0x90 si evidenziano con objdump -d binario | grep -c nop. Il conteggio dei NOP relativo al totale delle istruzioni è la metrica base che i detection engineer useranno contro di te — se superi il 5-10% ti fai notare, se stai troppo basso l'offuscamento è inefficace.
Per red team su ambienti Linux, la stessa logica si applica agli ELF: usa readelf -x .text per ispezionare la sezione di codice e verificare il rapporto istruzioni utili/istruzioni morte.
Vuoi diventare un Ethical Hacker ma non sai da dove iniziare?
Accedi alle lezioni gratuite e segui il percorso corretto fin dal primo passo