Guardrail del Mutex: Execution Guardrails: Mutual Exclusion (T1480.002)

La tecnica Mutual Exclusion rappresenta un meccanismo di protezione che il malware utilizza per verificare se un sistema è già stato compromesso. Un mutex è essenzialmente un semaforo di sincronizzazione che garantisce l'accesso esclusivo a una risorsa condivisa. Quando il malware crea un mutex univoco nel sistema, può verificare la sua presenza prima di eseguirsi nuovamente, evitando così di creare istanze multiple che potrebbero destabilizzare il sistema o attirare l'attenzione.

Questa tecnica si colloca nella tattica TA0005 - Defense Evasion della kill chain, nella fase in cui l'attaccante cerca di mantenere la persistenza evitando la detection. APT38, il gruppo nordcoreano specializzato in operazioni finanziarie, ha utilizzato questa tecnica nelle sue campagne. Ben 15 famiglie di malware documentate implementano mutex per l'evasione, includendo ransomware come REvil e Black Basta.

I mutex possono essere implementati a livello di sistema (visibili tra processi diversi) o locali (confinati a un singolo processo). Su Linux, il concetto si traduce nell'acquisizione di lock su file mutex, mentre su Windows si utilizzano le API native per la gestione dei mutex. I nomi dei mutex possono essere hardcoded nel malware o generati dinamicamente tramite algoritmi predicibili.

Per testare la resilienza dei sistemi contro questa tecnica, iniziamo creando un mutex su Windows. Il comando PowerShell più diretto utilizza le API .NET per creare un mutex di sistema:

$mutex = New-Object System.Threading.Mutex($false, "Global\MyUniqueMutex2024")

Questo crea un mutex visibile a livello di sistema. Per verificarne l'esistenza prima di procedere con l'esecuzione, il codice malevolo tipicamente implementa questa logica: if ($mutex.WaitOne(0)) { "Mutex acquired, continuing execution" } else { "Mutex already exists, terminating"; exit }

Su Linux, l'approccio differisce sostanzialmente. Il malware BPFDoor, ad esempio, tenta di creare e bloccare un file specifico:

exec 200>/var/run/initd.lock && flock -n 200 || exit 1

Questa riga tenta di acquisire un lock esclusivo sul file. Se fallisce (perché un'altra istanza detiene già il lock), il processo termina immediatamente. Un approccio più sofisticato in Python potrebbe essere: import fcntl; lockfile = open('/tmp/.mylock', 'w'); fcntl.flock(lockfile.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)

Per simulare il comportamento di malware reali come GrimAgent, che calcola il nome del mutex basandosi sugli ultimi 64 byte del binario, possiamo utilizzare questo approccio in PowerShell: $bytes = [System.IO.File]::ReadAllBytes($MyInvocation.MyCommand.Path); $mutexName = [System.BitConverter]::ToString($bytes[-64..-1]).Replace("-","")

Su macOS, l'implementazione può sfruttare NSDistributedLock per coordinamento tra processi: if let lock = NSDistributedLock(path: "/tmp/guard.lock") { if !lock.try() { exit(1) } }

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

Scarica la guida gratuita e segui il percorso corretto fin dal primo passo