CALDERA (Cyber Adversary Language and Decision Engine for Red Team Automation) [1] è una piattaforma per automatizzare alcune pratiche come adversary emulation e red-teaming.
MITRE ha creato la piattaforma per ridurre le risorse necessarie per i test di routine per valutare la robustezza del proprio sistema. Ciò permette ai responsabili della sicurezza di concentrarsi su problemi più critici.
La piattaforma permette di testare le soluzioni di sicurezza adottate dagli endpoint e valutare la postura difensiva di una rete rispetto alle TTPs della ATT&CK Matrix [2]. Concentrandosi su scenari post-compromessi, Caldera assume che l’attaccante sia già presente all’interno della rete, trascurando le azioni precedenti alla violazione iniziale.
Caldera sfrutta il framework ATT&CK [3] per identificare ed emulare i comportamenti degli attaccanti come in una vera intrusione per valutare la loro probabilità di successo. Ciò permette alle organizzazioni di analizzare le difese del sistema rispetto ad una minaccia persistente avanzata (APT) che usi delle tecniche note. L’automatizzazione permette di ottimizzare più rapidamente i sistemi di rilevamento delle intrusioni basati sul comportamento man mano che essi vengono implementati. Caldera utilizza il linguaggio ATT&CK per la rappresentazione degli avversari (adversary profile), un planner per elaborare le informazioni raccolte e scegliere le azioni successive ed un agent, agent, per eseguire le operation [4].
Vista la sua forte relazione con il comportamento degli avversari, l’obiettivo di Caldera è di far adottare un comportamento proattivo dove la rilevazione delle intrusioni non è focalizzata sugli indicatori di compromissione ma sui comportamenti dell’attaccante durante l’intrusione. Ciò aumenta la probabilità di rilevare la penetrazione e risolve a priori il problema di aggiornare i database con gli indicatori di compromissione utilizzati dagli strumenti di rilevamento delle intrusioni.
Caldera: caratteristiche principali e versioni
Nel seguito per evitare ambiguità useremo sempre termini in inglese per indicare i componenti di Caldera.
Le caratteristiche principali
In Caldera la simulazione di un avversario, ovvero di un adversary profile, corrisponde con una operazione che può essere divisa in fasi. Ogni fase prevede l’esecuzione di ability. Poiché uno degli attributi di una ability è un frammento di codice, due ability in fasi diverse possono comunicare tramite fact prodotti dalla la prima. La seconda usa le informazioni del fact per inizializzare alcune variabili del proprio codice.
Caldera ha una architettura centralizzata, basata su due componenti principali: server e agent lato client. Ogni agent simula l’effettiva presenza di un attaccante sull’host che lo esegue. Il server amministra le operation, pianifica le azioni da eseguire durante le simulazioni e rende disponibili all’utente tutte le informazioni inviate dai vari agent. Dopo aver pianificato le azioni da eseguire, il server attende che gli agenti si connettano per comunicare loro cosa fare. Gli agent eseguono le azioni scelte dal server sull’host in cui sono in esecuzione. Un agent può essere avviato manualmente dall’utente oppure da un altro agent a seguito di movimenti laterali durante una operation.
Figura 1: struttura di Caldera
Il linguaggio di programmazione utilizzato per lo sviluppo di Caldera è Python.
Una breve storia
La prima versione di Caldera, rilasciata nel 2017, offriva una efficace strategia di planning delle azioni che utilizzava tecniche di intelligenza artificiale. Tuttavia, questa versione presentava notevoli limiti poiché poteva operare solo in reti Windows e l’installazione dei componenti, sia lato server che client, era complessa. Ad esempio, l’installazione lato client richiedeva due moduli: l’agent CAgent ed un remote trojan RAT. Il Cagent doveva essere attivo in tutti i nodi coinvolti nella simulazione ed interfacciava il RAT con il server. Il RAT poteva essere avviato manualmente o a seguito di movimenti laterali e doveva eseguire le azioni. Inoltre, il planning sul server era sofisticato ma lento e ciò limitava le simulazioni ad un massimo di 20 host. Infine, era molto complesso creare profili avversari ed implementare nuove tecniche. Tutto questo limitava l’uso della piattaforma ad ambienti di ricerca e sviluppo. Ciò ha portato al rilascio di una seconda versione che ha mantenuto solo la struttura centralizzata ed i riferimenti al framework ATT&CK.
La seconda versione di Caldera, rilasciata a metà 2019, aveva come principali obiettivi una elevata personalizzazione e la semplificazione di installazione ed uso. Questo ha portato a due profondi cambiamenti al sistema. Il primo è stata la scelta di una architettura a plug-in, con un nucleo (core) di funzionalità e servizi base, quali la gestione del database e l’autenticazione. Un plug-in è un repository indipendente che amplia ed estende le funzionalità esistenti usando i servizi del core.
Figura 2: architettura a plug-in di Caldera (v2.3.2)
Il secondo cambiamento ha introdotto la modalità operativa a catena (chain mode) che permette agli utenti di orchestrare e concatenare unità atomiche in sequenze di attacco. Rispetto alla strategia di pianificazione precedente, questa è meno dinamica e più dipendente dalla capacità dell’utente nel creare adversary profile. Ovviamente, queste semplificazioni hanno diminuito drasticamente la complessità computazionale, permettendo di includere centinaia di host nelle simulazioni e di eseguire il server anche su sistemi con prestazioni non elevate. Inoltre, lato client è previsto un solo agent che non è necessario preinstallare sui nodi del sistema target. Infine, Caldera è stato esteso anche ad ambienti Linux, macOS e Windows non aziendali.
L’architettura plug-in e la chiara modulazione del codice offrono un alto grado di personalizzazione: sviluppando nuovi plug-in o moduli Python è possibile introdurre propri agenti e proprie strategie di pianificazione. Inoltre, è stata semplificata la creazione di nuove ability e, di conseguenza, anche la definizione di nuovi adversary profile risulta facilitata.
Caldera è un progetto tuttora attivo e, dopo la 2.0, sono state rilasciate alcune nuove versioni, mantenendo sempre le caratteristiche introdotte dalla 2.0. L’ultima versione è la 2.7, ma nel seguito presenteremo alcune caratteristiche delle versioni precedenti e discuteremo solo alla fine alcune caratteristiche delle ultime versioni. Una revisione delle versioni successive della piattaforma permette di comprendere ed apprezzare al meglio le ragioni di alcune modifiche, l’abbandono di alcune scelte iniziali di progetto e la direzione in cui il progetto si sta muovendo. Inoltre, per completezza di informazione, ricordiamo che esiste anche una versione della piattaforma closed source con funzionalità aggiuntive ed una migliore scalabilità.
Concetti di Base
Presentiamo i concetti chiave [5] che Caldera utilizza per rappresentare il comportamento di un attaccante e gli elementi necessari per eseguire le operation.
Agent e group
Un agent è un modulo software, che non richiede particolari installazioni e che si collega al server ad intervalli regolari (di default ogni 60 secondi) ed invia un segnale di keepalive. Se l’agent è incluso in almeno una operation attiva, il server risponde con le prossime istruzioni da eseguire. Eseguite le istruzioni, l’agent restituisce i risultati al server. La piattaforma può interagire con un agent solo quando si collega, quindi, un agent che non si collega mai al server, non riceverà le azioni da eseguire.
Il plug-in Sandcat (54ndc47) è l’agent di default. È possibile sviluppare altri agenti che possono comunicare con il server mediante il protocollo definito da Caldera .
Un group è un insieme di agenti per l’esecuzione di operazioni su più nodi in parallelo. All’avvio, un agent si unisce automaticamente al group specificato nel comando di avvio, che può essere cambiato dall’utente in qualsiasi momento .
Ability
Una ability è un’implementazione di una tecnica ATT&CK. Poiché una tecnica può utilizzare strumenti e procedure diverse, ability distinte possono implementare una stessa tecnica. Le ability sono archiviate in formato YML all’interno del plug-in Stockpile, insieme agli adversary profile che le utilizzano, e vengono caricate da Caldera ad ogni avvio. Un esempio di ability è descritto in fig.3.
Figura 3: esempio di ability
Ogni ability ha un identificatore, un nome ed una descrizione e fa riferimento ad una tecnica e una tattica della matrice ATT&CK. Ad ogni ability è associato un insieme di piattaforme, che dovrebbe contenere almeno un sistema operativo (la piattaforma) supportato. Attualmente, è possibile creare ability per Darwin, Linux o Windows. Per ogni piattaforma, deve esistere un elenco di esecutori. Le piattaforme Darwin e Linux possono usare sh mentre Windows può utilizzare PowerShell, anche open source, il prompt dei comandi, o pwsh. Ad ogni piattaforma possono essere associate quattro sezioni: Command, obbligatoria, e tre opzionali, Payload, Cleanup e Parser.
La Command deve contenere il codice che si desidera eseguire e può contenere variabili. Caldera dispone di tre variabili globali:
- #{server}: l’indirizzo di rete del server. Poiché ogni agent può conoscere la posizione di Caldera in modo diverso, #{server} consente al sistema di determinare la posizione corretta del server per ogni agent.
- #{group}: è il group di un agent. Questa variabile è utile per i movimenti laterali, dove la sezione Command cerca di avviare un nuovo agent e di inserirlo nella operation in corso.
- #{location}: è la posizione dell’agent sul file system del client.
Le variabili globali sono sostituite con il loro valore prima che il comando dell’ability venga inviato all’agent. In alternativa, l’utente può definire variabili proprie su cui Caldera opera sfruttando i fact. Come accennato, un fact è un’informazioni che viene o fornita dall’utente prima dell’inizio di una operation o restituita dal parsing dell’output di una ability precedentemente eseguita.
La sezione Payload elenca i file necessari all’esecuzione dell’ability. Nell’esempio in fig.3, il payload per la piattaforma Windows è “wifi.ps1”. Prima che venga utilizzata l’abilità, l’agent scaricherà dal server “wifi.ps1” se già non presente nell’host client.
Le istruzioni in Cleanup ripristinano lo stato del sistema prima dell’utilizzo dell’abilità, ovvero prima dell’esecuzione di Command. Ad esempio, se Command crea un file, Cleanup lo può eliminare. Questa sezione non è necessaria per le ability che, come quella in fig.3, scaricano file attraverso il blocco Payload perchè essi vengono automaticamente rimossi dal client al termine dell’operation.
La sezione Parser permette di analizzare l’output del comando eseguito e trasformarlo in uno o più fact. Un esempio è mostrato in fig.4.
Figura 4: esempio di un parser interno ad una ability
Un Parser è identificato dal modulo Python che contiene il codice per analizzare l’output del comando. Il modulo di parsing può contenere i seguenti campi:
- source (obbligatorio): nome dei fact creati per ogni matching trovato dal parsing,
- edge (opzionale): una stringa che descrive la relazione tra source e target,
- target (opzionale): nome del fact con cui far instaurare una relazione, descritta da edge, con source. Il target può essere un fact utilizzato all’interno del comando, come nell’esempio della fig. 4.
Fact
Un fact è un’informazione su un nodo ed è correlato alle variabili che le ability utilizzano nella sezione Command. Tre suoi elementi sono:
- proprietà: un descrittore in tre parti che identifica il tipo del fact. Ad esempio “host.user.name” indica che il valore del fact è un nome utente. Questo formato permette di specificare i componenti principali (“host”), minori (“user”) e specifici (“name”) del fact.
- valore: una stringa arbitraria. Un valore appropriato per “host.user.name” può essere “Administrator” o “John”.
- score: un intero che indica l’importanza relativa del fact. Il valore predefinito è 1. Un fact con score minore o uguale a 0 è inserito nella black-list e non può essere utilizzato.
Come detto, quando il server invia una ability agli agent, scandisce i comandi e le istruzioni di cleanup per individuare eventuali variabili e controlla quali di esse può sostituire con i fact di cui dispone. Vengono sostituite le variabili che matchano i fatti in base alla proprietà. Caldera creerà quindi una istanza di ogni comando/istruzione di cleanup per ogni combinazione dei fact che matchano con le variabili. Ogni variante, indicata come link, verrà valutata in base al punteggio cumulativo di tutti i fact utilizzati per completare il comando. Le varianti così generate sono eseguite in ordine decrescente di score. Questo procedimento viene applicato per tutti gli agent di una operation. Ciò può generare alcuni scenari ambigui e controintuitivi. La fig.5 mostra i link generati da Caldera per una ability Z, che contiene alcune variabili.
Source
I source sono insiemi di fact che possono essere applicati all’avvio di una operation per sostituire alcune variabili. Queste raccolte possono essere generate manualmente, attraverso la creazione di un file YML, oppure tramite l’interfaccia grafica. Al termine di ogni operation, viene prodotto un source con i fact generati durante la sua esecuzione, permettendo di sfruttare la conoscenza raccolta nelle successive operation.
Figura 5: generazione dei link per una ability che utilizza variabili al suo interno
Adversary profile
Un adversary profile (o adversary) è una collezione di ability che rappresenta il comportamento e le capacità di un attaccante. Le ability di un profile sono raggruppate in fasi, eseguite dalle operation. Se una fase include più abilità, il planner di Caldera determinerà il loro ordine di esecuzione in base allo score delle informazioni (fact) che l’operation ha raccolto. La definizione di ability multipiattaforma permette di adattare ogni profile ad ambienti eterogenei. Caldera , tramite il planner, invia agli agenti solamente i comandi corrispondenti al sistema operativo dell’host in cui sono in esecuzione.
Planner
Un planner è un modulo che decide, durante una operation, quali ability usare e in quale ordine. In particolare, la logica di un planner rappresenta il processo decisionale per eseguire una singola fase di una operation. Caldera utilizza le funzionalità del planner per ogni fase dell’adversary profile da eseguire.
La scelta di incapsulare le decisioni in un singolo modulo semplifica sia la creazione da parte dell’utente dei planner sia il loro inserimento nel contesto di Caldera . L’unico vincolo da rispettare è che il planner implementi la funzione execute(), che Caldera invoca per eseguire le singole fasi delle operation in corso.
Il “Sequential planner” è il planner di default di Caldera . Quando viene invocato, il planner invia a ciascun agent del group della operation tutti i link generabili dalle ability nella fase che l’agent può eseguire. Il planner può scartare alcune ability per due motivi:
- l’ability in questione non copre il sistema operativo del nodo in cui l’agent è in esecuzione, o
- nessuna combinazione dei fact sostituisce tutte le variabili dell’ability.
I link vengono ordinati in maniera decrescente in base allo score cumulativo dei fact che utilizzano e poi spediti. Il Sequential planner attende che tutti gli agenti completino l’esecuzione dei link. Nella versione di Caldera descritta questa attesa è potenzialmente infinita.
La semplice logica del Sequential planner delega all’utente l’ordine di esecuzione delle ability nella costruzione degli adversary profile. Questa semplicità permette però l’esecuzione parallela delle operation anche su un grande numero di agent. MITRE vuole arricchire, in futuro, i planner con strategie di pianificazioni intelligenti, simili a quella presente nella prima versione di Caldera .
Operation
Una operation rappresenta l’effettiva emulazione di un attaccante. Per attivare una operation, Caldera deve disporre di un adversary profile e di un gruppo di agent attivi che ne eseguano le ability. Caldera può eseguire operation in parallelo e gli agenti possono partecipare contemporaneamente a più operation.
Le operation possono essere configurate in modo diverso:
- Planner: l’unico disponibile è il Sequential planner.
- Fact source: associando ad una operation un fact source l’utente può fornire una base di informazioni per sostituire le variabili nelle ability dell’operation.
- Jitter: dopo aver scoperto che appartiene ad una operation attiva ed aver ricevuto dal server una sequenza di link, l’agent inizia ad eseguirli. Dopo ogni esecuzione, l’agent attende un tempo variabile di jitter che, di default, varia tra i 2 e gli 8 secondi.
L’utente può interrompere manualmente una operation e riprenderla successivamente. Al termine delle operation, gli agenti ricevono, nell’ordine inverso, i Cleanup delle ability eseguite.
Operation: ciclo di vita
Possiamo ora analizzare il ciclo di vita di una operation. La fig.6 riassume la vita di una generica operation che utilizza le configurazioni standard di Caldera ed il Sequential planner.
Figura 6: ciclo di vita di una operation
La “conoscenza dell’operation” rappresenta l’insieme dei fact raccolti dall’operation.
La fig.7 descrive il processo di generazione link, valido anche per la creazione di quelli di cleanup.
Figura 7 generazione dei link
Alcune scelte progettuali, come l’attesa forzata che tutti gli agenti termino l’esecuzione dei link prima di passare alla fase successiva o la generazione dei link per tutte le ability dalla prima fase fino alla corrente provocano problemi e limitazioni.
Plug-in
I plug-in sviluppati da MITRE estendono il sistema principale con nuove funzionalità. Ogni plug-in deve contenere una funzione di inizializzazione. All’avvio, Caldera invoca la funzione di inizializzazione per ogni plug-in al fine di caricarlo nel sistema. La funzione deve collegare i plug-in al sistema principale ed ha due parametri di input:
- app: l’oggetto applicazione aiohttp, che consente al plug-in di manipolare qualsiasi componente del server Web / API
- services: l’elenco dei principali servizi offerti dal core
Nel seguito presenteremo i principali plug-in disponibili per Caldera e che sono presenti di default. Alcuni sono fondamentali per il funzionamento di Caldera.
GUI
Il plug aggiunge gli elementi di base di un’applicazione Web al core della piattaforma. Tra questi: home page dell’applicazione Web per utilizzare la piattaforma, l’autenticazione in memoria per le funzionalità di login e logout, un insieme di file CSS e JavaScript che gli altri plug-in utilizzano per mantenere, nell’interfaccia grafica, un tema coerente.
Stockpile
Repository di ability, adversary profile, planner e fact source. Caldera carica tutti questi componenti all’avvio.
Sandcat (54ndc47)
Questo plug-in, altrimenti noto come 54ndc47, è l’agent predefinito fornito da Caldera ed è scritto in GoLang per la compatibilità multipiattaforma che questo linguaggio offre. L’agent si connette a Caldera sulla porta 8888.
Per distribuire 54ndc47 in qualsiasi host, il plug-in fornisce tre comandi di delivery. Ognuno di questi comandi scarica l’eseguibile 54ndc47 compilato da Caldera e lo esegue immediatamente. All’avvio, è possibile configurare alcuni parametri dell’agent:
- Server: l’indirizzo di rete del server Caldera a cui l’agent deve poter connettersi,
- Group: il nome del group a cui l’agent si unirà. Di default è “my_group”.
- Executor: l’esecutore da utilizzare. Su MacOS e Linux, l’unica opzione è sh, su Windows le opzioni sono PowerShell, valore predefinito, e prompt dei comandi.
Chain
Offre le funzionalità per creare e modificare ability, profile e fact, source, cambiare group e ottenere dettagli sugli agent, avviare e visualizzare lo stato delle operation. L’utente può utilizzare queste funzionalità attraverso un’API REST a livello di codice, oppure tramite l’interfaccia grafica dell’applicazione Web.
SSL
Il plug-in supporta HTTPS per le comunicazioni tra Caldera e gli agent.
Adversary
Abilita la modalità adversary, che utilizza la strategia di pianificazione basata su AI della prima versione di Caldera . Il nome può essere fuorviante perché il plug-in non è collegato alle precedenti definizioni di “adversary” ed “adversary profile”.
Versioni Successive
Complessivamente, la piattaforma offre una base estremamente interessante e personalizzabile per attività di adversary emulation. Alcune scelte progettuali risultano però problematiche, tra cui:
- l’attesa forzata che tutti gli agent termino l’esecuzione dei link ricevuti prima di poter passare alla fase successiva. In questo modo, se un agent dovesse smettere di operare o di rispondere, l’intera operation si bloccherebbe in una attesa infinita.
- la mancanza di discriminazione tra fact che potrebbero essere utili a livello globale dell’operation (ovvero per tutti gli agent coinvolti in essa) rispetto ad un livello locale (ovvero per il singolo agent che ha raccolto tale informazione). Infatti, tutti i fact vengono trattati a livello globale, causando la generazione e l’esecuzione di molti link privi di senso per la maggior parte degli agent.
- Dare priorità alle fasi e poi agli agent nella logica delle operation. Questa scelta può causare scenari inaspettati o ambigui nel caso in cui un nuovo agent si unisse ad operazione in corso a causa di un movimento laterale di successo: esso non partirebbe dalla fase 1, ma bensì gli verrebbero inviati i link di tutte le abilità presenti dalla fase 1 alla fase corrente dell’operation. Conseguentemente, l’ordine delle fasi non viene garantito ed alcune ability potrebbero non essere eseguite a causa della mancanza di fact oppure ripetute o recuperate in fasi successive a seguito della creazione di nuovi fact.
I punti 1) e 2) sono stati risolti nelle versioni successive migliorando le caratteristiche dei fact ed introducendo il concetto di trust per gli agent. Ad esempio, nelle versioni attuali, un fact può essere locale ad un certo host e non più globale, limitando al numero corretto i link che possono essere generati. Inoltre, se un agent non dovesse connettersi al server per un tempo preconfigurato, esso verrà etichettato come untrusted, e l’operation non attenderà più le sue risposte. Quest’ultime migliorie appena discusse sono state originariamente proposte (e successivamente integrate) in 6.
Inoltre, sono state introdotte le rule, che permettono di scartare alcuni dei fact prodotti, e diversi nuovi plug-in. Ad esempio, sono attualmente disponibili plug-in che implementano una reverse shell o che permettono di resistere agli attacchi ad un certo nodo, installando agent che eseguono profili “difensivi”. Un altro plug-in consente di implementare l’attacco iniziale per penetrare nel sistema target. Cambiamenti minori hanno riguardato il “Sequential planner”, rinominato “Batch planner” ma con logica invariata, e le variabili globali utilizzabili all’interno della sezione Command delle ability, aggiungendone una quarta, #{paw}. Infine, alcuni plug-in come GUI e Chain sono stati integrati direttamente nel core di Caldera , mentre altri, come Adversary, non sono più disponibili nelle ultime versioni.
Nonostante i passi avanti, la problematica presentata al punto 3) non è ancora stata affrontata direttamente da MITRE. Ciononostante, è disponibile un plug-in esterno (compatibile con Caldera v2.3.2) che offre una soluzione [6] [7].
Riferimenti
[1] | M. Corporation, «Caldera ,» MITRE, [Online]. Available: https://github.com/mitre/Caldera #planning-system. |
[2] | E. Panti, F. Baiardi, «Adversary Emulation and The ATT&CK Matrix,» PenTest: MITRE ATT&CK in Practice, pp. 4-11, 2020. |
[3] | MITRE, «ATT&CK Matrix,» [Online]. Available: https://attack.mitre.org/. |
[4] | M. Corporation, «Caldera ,» [Online]. Available: https://www.mitre.org/research/technology-transfer/open-source-software/Caldera . |
[5] | M. Corporation, «Caldera ‘s documentation,» [Online]. Available: https://Caldera .readthedocs.io/en/latest/. |
[6] | E. Panti, «Adversary emulation e worm. Alcune estensioni al Sistema Caldera , Tesi di Laurea in Informatica, Università di Pisa» 2019. |
[7] | E. Panti, «CALDERA plugin: WORM,» [Online]. Available: https://github.com/EmilioPanti/worm/tree/Caldera -v2.3.2. |