Il 29 ottobre 2014 il team Security Infrastructure di Facebook ha pubblicato su GitHub osquery, uno strumento che rappresenta lo stato di un sistema operativo come un insieme di tabelle SQL interrogabili. Processi in esecuzione, moduli del kernel caricati, connessioni di rete aperte e porte in ascolto diventano righe di un database relazionale, leggibili con la stessa SELECT che si scriverebbe su una qualsiasi tabella applicativa.
Contesto
La visibilità sullo stato di un endpoint è storicamente frammentata fra strumenti eterogenei: ps per i processi, netstat o ss per i socket, lsmod per i moduli kernel, find per il file system, parser ad hoc per i log. Ciascuno ha un output suo, opzioni sue, un formato suo da normalizzare a valle. Su un parco di decine di host, raccogliere lo stesso dato richiede uno script per piattaforma e una pipeline di parsing per ogni comando.
L’idea di osquery è ridurre questa eterogeneità a un’unica interfaccia dichiarativa. Invece di ricordare quali flag passare a quale binario, si scrive una query sul nome di una tabella. L’annuncio di rilascio mostra l’esempio canonico: trovare i processi la cui immagine su disco non esiste più, indicatore frequente di codice eseguito da binari cancellati dopo l’avvio.
SELECT name, path, pid FROM processes WHERE on_disk = 0;
La colonna on_disk è un attributo calcolato a tempo di query: osquery risolve il path del binario associato a ciascun PID e verifica se il file c’è ancora. Non è un campo che il sistema operativo espone direttamente; è il risultato di una correlazione che, fuori da osquery, vorrebbe dire unire l’output di ps a una serie di stat.
Architettura
Il progetto si articola in due eseguibili.
osqueryi è una console interattiva: una REPL che apre una sessione SQL sull’host locale e lascia provare query, ispezionare lo schema delle tabelle, esplorare lo stato della macchina senza un piano prefissato. Lo si usa per il lavoro estemporaneo, per l’analisi durante un incidente, per una verifica a mano.
osqueryd è un daemon che schedula query a intervalli definiti e ne registra i risultati. Nel monitoraggio interessa la differenza fra esecuzioni successive più della singola fotografia: il daemon confronta il risultato di una query con quello precedente e scrive a log le righe aggiunte e quelle rimosse. Una query schedulata su listening_ports produce così un flusso di eventi “porta aperta” / “porta chiusa” invece della lista completa a ogni ciclo.
Il motore SQL è SQLite, usato attraverso il meccanismo delle tabelle virtuali. Una tabella virtuale non contiene dati persistenti: ogni SELECT invoca codice C++ che raccoglie lo stato al momento dell’interrogazione e lo restituisce come righe. Le tabelle di osquery sono quindi sempre coerenti con lo stato corrente dell’host, ma il costo di una query è il costo della raccolta sottostante, non quello di una lettura da indice.
Le query correlate si raggruppano in pack, file di configurazione che associano a ciascuna query un nome, un intervallo e una piattaforma di destinazione. In un pack si distribuisce e si versiona una collezione di controlli.
Punto critico
La join fra tabelle separa osquery da una raccolta di comandi avvolti in SQL. L’annuncio porta l’esempio dell’associazione fra porte in ascolto e processo proprietario.
SELECT DISTINCT process.name, listening.port, listening.address, process.pid
FROM processes AS process
JOIN listening_ports AS listening
ON process.pid = listening.pid;
Ottenere lo stesso risultato a riga di comando vuol dire correlare a mano l’output di netstat -lnp con quello di ps, allineando i PID uno per uno. La join SQL rende esplicita la chiave di correlazione (pid) e lascia l’incrocio al motore. Lo stesso schema vale per altre relazioni dello stato di sistema: un utente e le sue sessioni attive, un file e gli eventi che lo hanno modificato, un processo e i socket che ha aperto.
Il limite di questo modello va detto chiaro: una JOIN su tabelle virtuali può materializzare entrambi i lati prima di correlarli, perché il motore non ha per forza indici sulle tabelle generate al volo. Su un host con migliaia di processi una query scritta male paga in raccolta ciò che un database tradizionale pagherebbe in lettura. Le query schedulate vanno quindi tarate sull’intervallo e sul costo della tabella interrogata, non solo sulla correttezza logica.
Implicazioni
L’interfaccia uniforme riduce il lavoro di normalizzazione a valle. Una regola di detection scritta come query — processi senza binario su disco, moduli kernel non firmati, porte in ascolto non previste — resta la stessa frase SQL qualunque sia la distribuzione sottostante, finché la tabella esiste su quella piattaforma. Il dato esce già strutturato, in JSON nei log di osqueryd, pronto da spedire a un sistema di aggregazione senza un parser dedicato a ogni comando.
Chi si occupa di sicurezza lavora meno alla raccolta e più alla formulazione delle domande giuste. La libreria di query diventa l’artefatto da mantenere e versionare; lo strumento di raccolta resta lo stesso su ogni host.
Limiti
Al rilascio osquery gira su Ubuntu, CentOS e Mac OS X. Per Windows non c’è ancora niente: l’annuncio non lo cita, e una parte consistente delle tabelle dipende da meccanismi specifici di Linux e OS X. Chi ha un parco eterogeneo con host Windows non può, oggi, usare la stessa frase SQL ovunque.
Lo strumento, poi, osserva soltanto. Raccoglie e registra; non blocca, non mette in quarantena, non interviene sul processo che ha segnalato. La risposta resta delegata a ciò che consuma i log a valle. E il modello a differenza fra esecuzioni vede solo ciò che è presente nell’istante della query schedulata: un processo nato e morto fra due cicli non lascia traccia in una query periodica su processes. Le tabelle di eventi attenuano il problema per alcuni domini, ma il principio resta — la frequenza di campionamento decide cosa si vede.
Resta da vedere come crescerà la copertura delle tabelle e quanto la community esterna a Facebook contribuirà schemi per piattaforme e domini ancora scoperti.
- https://engineering.fb.com/2014/10/29/security/introducing-osquery/
- https://osquery.io/
- https://github.com/facebook/osquery
- https://www.sqlite.org/vtab.html
- https://www.helpnetsecurity.com/2014/10/30/facebook-open-sources-osquery-an-os-analysis-tool/
Immagine di copertina: Un ingegnere di Facebook tiene in mano una scheda madre server in un data center, con file di rack sullo sfondo — foto di Intel Free Press, CC BY 2.0 — https://commons.wikimedia.org/wiki/File:Facebook_Data_Center_Server_Board.jpg