Non l’ho fatto per la prima live in coppia con Andrea, ho pensato di farlo per la seconda sessione di ieri sera sul canale di Security Cert. Come ho raccontato un paio di settimana fa abbiamo in testa questa idea da qualche tempo ormai: condividere delle sessioni di analisi di un target per definire una strategia di attacco (lato mio) e una strategia di difesa (lato Andrea). Nella prima puntata abbiamo visto il contesto e la base di partenza del lab, una tipica VPS che espone una web app con qualche vulnerabilità. Ieri, in occasione della seconda puntata, abbiamo iniziato ad analizzare il target ed il questo post faccio un po’ la sintesi di quello che ci siamo detti, ovviamente dal mio punto di vista.
Qualche info di servizio prima di iniziare a discutere le azioni intraprese:
il video della live è archiviato sul canale YouTube di SecurityCert e lo trovate qui
sul mio canale porterò avanti le fasi di preparazione alla live, trovate la programmazione qui
la prossima live è programmata per il 06/10/2022
se volete partecipare attivamente alla sessione assieme ad Andrea (nelle azioni difensive) o assieme a me (nelle azioni offensiva) i dati di accesso all’ambiente vengono condivisi con i partecipanti alla sessione
Cosa abbiamo di fronte
Tra le prime azioni intraprese abbiamo ovviamente eseguito una scansione del sistema target. Essendo una macchina di recente installazione che è solitamente off-line (il lab viene disattivato quando non siamo live) non vi è possibilità di utilizzare tecniche passive come l’analisi di precedenti versioni dell’applicazione (Wayback Machine) o i rilevamenti di scansioni terze (Shodan).
Con il più classico degli nmap abbiamo ottenuto l’elenco dei servizi:
porta tcp\22 (ssh)
porta tcp\80 (apache2)
porta tcp\3306v (mysql)
L’accesso al DB è stato subito dall’esterno è stato quasi subito inibito da Andrea, in effetti non aveva senso e come prima azione ci era venuto in mente di tentare un brute force attack.
L’applicazione web espone un sito in WordPress che abbiamo subito preso in esame. Come discusso il live la prima cosa che verrebbe in mente a chiunque è di utilizzare dirb per dare un occhio ai path esposti e wpscan per verificare lo stato dell’applicazione, cosa assolutamente sensata e lo faremo anche noi. Prima ho voluto lasciare spazio a qualche tools/servizio terze parti per vedere che tipo di info avrebbero portato all’attenzione. Ve ne cito alcuni tra quelli provati, dateci un occhio anche voi:
Qualche elemento interessante da queste scansioni è emerso ma nulla di particolare, qualche risultato lo abbiamo commentato assieme in live. La scansione tramite wpscan da invece dei risultati molto chiari:
vengono enumerati due utenti (admin e events)
vengono rilevate tre plugin segnalate come out of date
Da una ricerca su wpscan.com emergono le potenziali vulnerabilità per:
wp-advanced-search v3.3.3
social-warfare <= 3.5.2
wp-file-upload
Nel rilevare le informazioni base che ci consentiranno di definire un modello di attacco abbiamo discusso delle evidenze che le nostre azioni hanno generato, in particolare i log che Andrea riusciva chiaramente a ricondurre alle nostre azioni.
ToDo per la prossima sessione
E’ evidente che siamo stati troppo rumorosi e il parte questo era lo scopo della sessione. In un contesto di Penetration Testing potrebbe anche non essere un problema ma in ambito Red Team lo è. Quindi per la prossima sessione sicuramente dobbiamo dotarci di uno strumento per generare traffico realistico sul sistema.
Una volta che abbiamo la possibilità di confonderci nella mischia inizieremo a verificare la possibilità di utilizzare le vulnerabilità plausibili per costruire una tattica di attacco.
Qualche settimana fa rispetto a questo post Paolo Perego ha annunciato e pubblicato un video sull’analisi e l’exploiting di una macchina vulnhub: Breakout. In quel momento stavo valutando che contenuti presentare live su Twitch per il mese di agosto avendo previsto una minor partecipazione e volendo dedicare del tempo ad affinare un po’ le tecniche di red teaming. Ho quindi pensato di non guardare subito il video e di proporre live una sessione in cui eseguire lo stesso esercizio e, in un secondo momento, organizzare un confronto con Paolo per discutere i differenti approcci che possono essere utilizzati.
La scorsa settimana ho quindi tenuto la live in cui abbiamo, assieme ai presenti, giocato con la macchina fino a guadagnarci una shell come root. Da qui sono nate un po’ di riflessioni su come un attacker potrebbe agire in un contesto simile anche se, come discusso, per certi versi non proprio così realistico. Oltre al tema dell’accesso al sistema ci sono almeno altri due argomenti da approfondire: il post-exploiting e l’accesso permanente tramite un Command and Control (C2). Andiamo con ordine.
Scenario
La macchina è disponibile in formato OVA sul sito di vulnhub a questo link, è possibile quindi scaricare ed importare rapidamente il sistema sia su VMware Workstation/ESXi che su VirtualBox. La configurazione di default del sistema presenta una NIC configurata in DHCP, una volta accesa la macchina e collegata la NIC il sistema chiederà al DHCP server della rete in cui lo avrete posizionato un indirizzo IP usabile.
breakout console
Nel laboratorio presentato durante la live abbiamo fatto tutto praticamente solo con due VMs: la macchina Kali utilizzata come base di partenza delle azioni offensive e la macchina Breakout. Il laboratorio che utilizzeremo in questa sessione è lievemente più esteso per avvicinarci ad un contesto reale ed è composto da:
il mio laptop con la wls Kali dietro NAT
un server/host per ospitare le guest:
una VM ubuntu che utilizzeremo come macchina d’appoggio
la VM target
Fatta eccezione per la Kali tutte le altre VM connesse alla rete LAN del laboratorio e sono quindi nello stesso dominio di broadcast.
conf. di rete della macchina Kali
Ovviamente non ci sono particolari vincoli nella configurazione del laboratorio, accertatevi sono di avere almeno un sistema di grado di dialogare in modo bidirezionale con la macchina target in modo da lasciarci aperte più opzioni di comunicazione.
Rilevamento della macchina target e delle applicazioni
In questo caso è un’operazione superflua in quando siamo perfettamente a conoscenza dell’indirizzo IP della macchina target. In un contesto reale saremmo partiti da una serie di rilevamenti utilizzando tecniche di scansione passiva e attiva. Facendo un semplice scansione con nmap possiamo renderci conto di cosa c’è in rete, solitamente io inizio con qualcosa di molto leggero usando la funzione TCP Connect Scan o anche semplicemente con un hping:
Una volta individuata la macchina target ha sicuramente senso intensificare la scansione per raccogliere qualche info aggiuntiva sul sistema, in particolare ci interessa capire tutto ciò che espone a livello di servizi e, se possibile, qualche dato sulle applicazioni che stanno dietro. Continuiamo con nmap ma andiamo a verificare tutte le porte ed utilizziamo anche tutti gli script disponibili di default:
Per comodità l’output lo salviamo su in file in modo da annotare quanto rilevato e consultarlo in caso di necessità senza eseguire nuove scansioni.
output della scansione
Abbiamo un bel po’ di dati, andiamo con ordine e vediamo cosa ci racconta di se il nostro target.
Porta 80/tcp aperta
La porta 80 è tra le più famose e ci fa pensare che il sistema abbia un web server attivo che nmap rileva come Apache versione 2.4.51. Viene anche individuato il sistema operativo Debian. Se è veramente disponibile un web server possiamo verificarlo facilmente semplicemente aprendo il browser e puntando all’IP della macchina target:
La default page di Apache2 è sufficientemente eloquente.
Porte 139\tcp e 445\tcp
Viene identificato un servizio Samba versione 4.6.2 che ci potrebbe aiutare ad approfondire qualche dato utilizzando specifici tools di enumerazione e verifica delle configurazioni “disponibili”.
Porte 10000\tcp e 20000\tcp
Viene rilevata l’applicazione “Webmin” in due differenti versioni: sulla porta 10000 è attiva la versione 1.981, sulla porta 20000 è attiva la versione 1.830. Durante la live mi sono documentato sull’applicazione che non avevo mai incontrato, si tratta di un tool per gestire server e applicazioni di uso comune come sistemi di pubblicazione contenuti, database, job.
Le due porte tcp sono di fatto utilizzate per esporre le interfacce web dell’applicazione Webmin e possiamo dare una sbirciata a ciò che si vede semplicemente accedendo con il nostro browser in https e specificando la porta da utilizzare:
Interfaccia di accesso amministrativo per webmin
Mentre la porta 10000 presenta la schermata di login per l’area amministrativa, sulla porta 20000 si potrà notare un’interfaccia leggermente diversa che fa riferimento a Usermin. Si tratta di fatto di due diverse applicazioni con scopi differenti ma soprattutto i relativi utenti hanno privilegi di accesso al sistema molto differenti: la parte amministrativa potrebbe infatti accedere con privilegi di root.
Analisi dei contenuti web
Durante la mia live a questo punto sono passato ad analizzare ciò che era visibile, ovvero le pagine web e le relative componenti, cercando documentazione specifica sull’applicazione che evidentemente viene pubblicata dal sistema. Paolo nella sua analisi ha eseguito anche un altro controllo che sul momento a me non era venuto in mente: con GoBuster ha dato un’occhiata alle directory pubblicate.
Per usare tools come GoBuster è indispensabile disporre di qualche wordlist e se usate kali troverete un patrimonio di file in /usr/share/wordlist. Anche per questo lab sto utilizzando kali ma è una installazione minima su wls2, devo quindi prima installare il pacchetto:
Abbiamo tutto il necessario per iniziare la scansione. Vi suggerisco, vista la dimensione dell’output, di buttare tutto in un file dedicato. L’operazione potrebbe richiedere qualche minuto e non è detto che si trovino informazioni utili.
E’ interessante osservare l’effetto di un’attività di questo tipo sulla macchina target: nel mio caso ho creato una VM con una vCPU a cui è stato assegnato il 70% di un vCORE della macchina host. Con la scansione attiva la macchina guest si trova ad avere il 100% di CPU usage a testimoniare che alcune azioni possono essere anche molto invasive in termini di system load. Se un attacker utilizzasse una tecnica di questo tipo senza eseguire prima del tuning a livello di richieste per secondo è molto probabile che i sistemi di monitoraggio segnalino anomalie di carico.
htop della macchina host: è ben visibile il processo VirtualBoxVM della macchina target
Nota tecnica sui tools di Directory Discovery: che sia GoBuster, DirBuster, fuff, […] il principio non cambia, usate quello che vi pare.
Oltre alla directory è opportuno verificare il contenuto delle pagine web. In questo caso abbiamo tre contenuti html: la default page di apache e le due login page di Webmin. Su questi specifici contenuti è possibile dare una semplice occhiata al sorgente o, per analisi più approfondite, utilizzare tools come BurpSuite (nella versione pro) per eseguire una scansione dell’applicazione a caccia di specifiche vulnerabilità.
In questo caso siamo in un contesto CTF e non è raro che vengano disseminati piccoli indizi qua e la nei sistemi, una veloce verifica del sorgente HTML porta infatti in evidenza uno di questi indizi: alla default page di apache è stata fatta un’aggiunta.
Si tratta di un commento HTML che riporta un testo cifrato con un metodo noto come Brain F*ck. Google è vostro, non farete nessuna fatica a trovare un tool di decodifica da cui uscirà una stringa che qui in parte nascondo: .2uqPEfj3D<P’*** .
Ha l’aspetto di una password e visto il messaggio nel commento HTML probabilmente lo è ma non abbiamo idea dell’utente associato. Durante la live ho provato ad utilizzare questa potenziale password associata all’utente root e admin su entrambe le interfacce di login ma senza successo.
Analisi dei servizi SMB
La scansione delle porte ha riportato la presenza di un servizio Samba 4.6.2 attivo sul sistema per il quale possiamo fare diverse verifiche a caccia di ulteriori informazioni o anche di livelli di accesso specifici. Per fare enumeration di smb abbiamo moltissimi tools a disposizione, primo tra tutti citerei enum4linux che di fatto ho utilizzato per primo anche in questo caso:
enum4linux con opzione -a
In questo caso la caccia è andata bene, la verifica ha fatto emergere un utente smb: cyber.
Da notare che nell’analisi dei contenuti era saltata fuori quella che sembrava essere una password.
Analisi delle applicazioni
Ci siamo imbattuti in un’applicazione web-based per la gestione del server: Webmin. La scansione ci aveva indicato le versioni delle applicazioni esposte, ha quindi senso verificare se esistono vulnerabilità note ed eventuali exploit. Basta una rapida ricerca su exploit-db.com per accorgersi che di vulnerabilità ne esistono diverse:
Meglio ancora, senza neanche lasciare la nostra cli come fatto durante la live, una query con searchploit ci da subito lo status di cosa è disponibile subito:
Le vulnerabilità non mancano ma le versioni non corrispondono, in questo caso ha poso senso tentare questa strada in quanto la probabilità di successo è praticamente nulla salvo incappare per puro caso in una versione vulnerabile ma non documentata.
Anche in relazione alla versione di Apache è opportuno fare un approfondimento (non fatto durante la live). Nmap ha rilevato la versione 2.4.51 a cui sono associate un paio di CVE:
Su queste CVE non ci sono exploit noti ma esiste documentazione interessante in relazione ad un p-o-c per la vulnerabilità del modulo “mod_lua” che non abbiamo ancora avuto modo di verificare in questa installazione. In questo contesto non procedo oltre ma potrebbe essere interessante approfondire in futuro ovviamente in un contesto dove è presente uno script lua. Metto in ToDo 😉
Accesso all’applicazione
Come emerso dalle nostre ricerche abbiamo un utente ed una credenziale che a questo punto vale la pena provare. L’unico punto di accesso incontrato sono le due applicazioni Webmin e Usermin ed è qui che facciamo il primo tentativo. La login page dell’applicazione Usermin (porta tcp\20000) vi darà accesso al portale; navigando un po’ le funzionalità dell’applicazione ci si imbatte in una web-shell all’interno del menu Login >> Command Shell:
web shell all’interno dell’applicazione
In questa situazione la prima cosa da fare è raccogliere informazioni sul sistema cercando di capire come è configurato e che software è in uso. Partiamo con questa sequenza di comandi:
pwd && ls -l && id && ps ax
Per ottengo questo output:
> pwd && ls -l && id && ps ax
/home/cyber
total 616
-rwxr-xr-x 1 root root 531928 Oct 19 2021 tar
-rw-r--r-- 1 cyber cyber 48 Oct 19 2021 user.txt
uid=1000(cyber) gid=1000(cyber) groups=1000(cyber),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev)
PID TTY STAT TIME COMMAND
[...]
284 ? Ssl 0:00 /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -I -df /var/lib/dhcp/dhclient6.eth0.leases eth0
313 ? Ss 0:00 /usr/sbin/cron -f
314 ? Ss 0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
325 ? Ss 0:00 /usr/sbin/nmbd --foreground --no-process-group
329 ? Ssl 0:00 /usr/sbin/rsyslogd -n -iNONE
330 ? Ss 0:00 /lib/systemd/systemd-logind
385 tty1 Ss+ 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
392 ? Ss 0:00 /usr/sbin/apache2 -k start
524 ? Sl 0:00 /usr/sbin/apache2 -k start
525 ? Sl 0:00 /usr/sbin/apache2 -k start
596 ? Ss 0:00 /usr/bin/perl /usr/share/usermin/miniserv.pl /etc/usermin/miniserv.conf
598 ? Ss 0:00 /usr/bin/perl /usr/share/webmin/miniserv.pl /etc/webmin/miniserv.conf
668 ? Ssl 0:00 /lib/systemd/systemd-timesyncd
691 ? Ss 0:00 /usr/sbin/smbd --foreground --no-process-group
693 ? S 0:00 /usr/sbin/smbd --foreground --no-process-group
694 ? S 0:00 /usr/sbin/smbd --foreground --no-process-group
696 ? S 0:00 /usr/sbin/smbd --foreground --no-process-group
774 ? I 0:00 [kworker/u2:0-flush-8:0]
793 ? I 0:01 [kworker/0:0-events]
872 ? S 0:00 /usr/share/usermin/shell/index.cgi
875 ? S 0:00 sh -c /bin/su cyber -c cd\ \/home\/cyber\ \&\&\ pwd\ \&\&\ ls\ \-l\ \&\&\ id\ \&\&\ ps\ ax 2>&1
876 ? S 0:00 /bin/su cyber -c cd /home/cyber && pwd && ls -l && id && ps ax
878 ? Ss 0:00 /lib/systemd/systemd --user
879 ? S 0:00 (sd-pam)
897 ? Rs 0:00 ps ax
Siamo della home dell’utente cyber dove troviamo due file: un binario di tar (già questo è curioso) ed il file user.txt.
Altra cosa che mi viene naturale fare è buttare un occhio alla /usr/bin per rendermi conto di che utility possiamo disporre:
Stessa cosa per la /var a caccia di info nei logs e dove si nota una directory backups:
> ls -la /var/backups
total 32
drwxr-xr-x 2 root root 4096 Aug 26 18:33 .
drwxr-xr-x 14 root root 4096 Oct 19 2021 ..
-rw-r--r-- 1 root root 1467 Oct 19 2021 apt.extended_states.1.gz
-rw------- 1 root root 17 Oct 20 2021 .old_pass.bak
Salta abbastanza all’occhio il file .old_pass.bak in un path che spesso cerco volutamente, ovvero tutto ciò che ha a che fare con backup e dump. Il file è accessibile solo per l’utente root.
Teniamo sempre presente che il contesto in cui siamo è quello di una macchina preparata appositamente per essere compromessa, sono quindi presenti delle tracce o degli indizi più o meno visibili. In questo caso quel “tar” nella home dell’utente salta anche fin troppo all’occhio e, considerando le funzionalità del tool, potrebbe tornare utile se volessimo “leggere” in modo alternativo il contenuto di un file.
Esistono diversi modi per accedere ad un file che è accessibile solo all’utente root senza essere root: il più noto è forse l’utility sudo che ci consente di eseguire un comando con i privilegi super user (Super User DO) con il “problema” di concedere forse troppo agli utenti. Un altro metodo, che personalmente utilizzo poco, è quelle di assegnare ad un eseguibile (e quindi al suo processo) delle capacità aggiuntive chiamate appunto capabilities.
Quanto abbiamo a disposizione – la shell dell’utente cyber – ci consente di eseguire questo tipo di verifica:
utilizzo del comando getcap
Con il comando getcap possiamo verificare che capabilities sono state assegnato ad uno specifico file/processo, in questo caso abbiamo come output cap_dac_read_search=ep. Diamo un occhio alla documentazione ufficiale in tema di capabilities:
Molto eloquente direi, l’eseguibile tar è stato dotato della capacità di leggere un file a prescindere dai permessi a questo associati, in parole povere il nostro /home/cyber/tar può leggere qualsiasi file e noi abbiamo un file da leggere che richiede di essere super user. Idee?
Privilege escalation
Il nome del file a cui stiamo puntando è “old_pass.bak”, la nostra speranza è quindi quella di trovare le info per accedere come root al sistema. Visto che il nostro tar può leggere questo file proviamo a creare un archivio:
L’archivio viene comunque creato e l’owner è ovviamente l’utente cyber, possiamo quindi procedere ad una estrazione del contenuto usando anche l’utility tar di sistema visto che la letture del file ormai è avvenuta correttamente e l’archivio è di proprietà del nostro utente:
I più attenti noteranno che viene estratta una directory (var), tutto corretto visto che quando abbiamo creato l’archivio abbiamo puntato ad un path assoluto (/var/backups) e non solo al file di nostro interesse. Dentro la directory troveremo finalmente il nostro file a cui sono ora attribuiti i permessi sufficienti per essere letto anche dall’utente cyber:
Non resta che provare questa potenziale password per l’utente root, la prima verifica è per la web-shell che abbiamo utilizzato sino ad ora:
Passando la password al comando “su” evitiamo che ci venga chiesta a livello prompt, azione necessario visto che tramite la web-shell poi non potremmo inserirla. In live avevamo subito utilizzato una reverse shell quindi fu possibile inserire la password dopo aver dato il comando “su”.
Abbiamo però appurato che la password è corretta avendo come output del comando “id” la stringa “uid=0(root)”. Possiamo quindi sicuramente dare comandi come root da questa web-shell ma ancora meglio potremmo utilizzare questa credenziale per accedere alla parte amministrativa dell’applicazione disponibile sulla porta tcp\10000.
Welcome to Webmin 🙂
Anche in questa sezione dell’applicazione abbiamo un comoda web-shell che questa volta accede al sistema come root:
root web-shell
A questo punto la macchina è nostra.
Prossimi step
Come da premesse in questo post volevo illustrare gli step e le analisi che ci hanno condotto ad ottenere un accesso root al sistema. Possiamo andare ben oltre e iniziare a lavorare sulla macchina per comprendere il contesto in cui si trova, le configurazione base e come potrebbe essere governata da remoto.
Ovviamente alcuni di questi ragionamenti li farò assieme ai presenti alle prossime live (questa sera, 16 settembre, affrontiamo parte dell’argomento) e seguiranno gli articoli di resoconto.
Un po’ per gioco, un po’ per esercitarmi ho ripreso in mano un progetto molto utile a chi deve affrontare, a livello di studio e comprensione, il mondo delle vulnerabilità delle applicazioni web. Damn Vulnerable Web Application (DVWA) è una piccola applicazione web scritta in Php che mette a disposizione varie componenti dotate delle più classiche delle vulnerabilità. Una delle caratteristiche molto utili che ho trovato è il fatto di avere a disposizione il codice della parte di applicazione vulnerabile ed un sistema a livelli, ovvero la piattaforma, per ogni vulnerabilità, propone più versioni:
Low, che corrisponde ad un codice scritto veramente male e facile da sfruttare
Medium, dove compaiono i primi controlli
High, dove i controlli sono robusti (oggetto di questa serie di articoli)
Impossible, che rappresenterebbe la versione non vulnerabile
Qualche giorno fa, in una delle recenti live, abbiamo affrontato il primo test relativo ad un attacco brute force. Nulla di particolare, la tecnica è anche abbastanza desueta ma in molti scenari continua ad essere un problema reale, soprattutto a causa dell’assenza di controlli specifici. Il codice Php del livello high (che come accennavo è il livello con cui ho deciso di affrontare sia le live che le spiegazioni in questi brevi articoli) presenta un controllo specifico per impedire a tools come Hydra di tentare attacchi di “forza bruta” in quanto la pagina di login, ad ogni richiesta, genera anche un token CSRF che viene controllato in fase di verifica delle credenziali.
In pratica l’applicazione si accerta che la richiesta di login provenga effettivamente dalla pagina che ha generato il login form e non da sistemi terzi (come un software per il brute force delle credenziali).
Per aggirare l’ostacolo dobbiamo quindi fare in modo che il sistema che esegue le richieste possa eseguire i tentativi di login sapendo il valore del token che la login page genera e solo dopo eseguire la chiamata alla funzione di login con il relativo token. Analizzando il codice HTML del login form è possibile verifica come tali dati vengono inviati all’applicazione:
E’ ben visibile la GET per l’invio di username e password ed il campo nascosto – input type=”hidden” – user_token con relativo valore.
Il nostro processo di cracking della credenziale deve quindi tenere in considerazione diversi elementi per eseguire dei test ricorsivi:
E’ necessaria una sessione valida per eseguire le prove con relativo phpsessid;
Per ogni tentativo di invio delle credenziali è necessario generare un nuovo user_token da inviare alla pagina per verifica;
Se provassimo semplicemente ad eseguire il brute forcing con Burp Suite, ad esempio usando il Repeater, non otterremo mai un esito positivo in quanto non saremmo in grado di inviare anche lo user_token generato dalla pagina una volta caricata la login form.
Il flusso deve quindi prima ottenere la generazione della pagina, leggere lo user_token e poi eseguire il tentativo di login con una credenziale definita ad esempio da un dizionario. Il phpsessid potremmo provare a generarlo dinamicamente, in questa mia prima versione dello script lo prendiamo direttamente dall’applicazione con un primo tentativo di accesso tramite Burp Suite.
Intercettando il traffico del browser di un tentativo di login possiamo facilmente prelevare un ID di sessione valido, nel mio esempio:
Il brute force verrà eseguito utilizzando quindi questa sessione valida.
Lo script è semplicissimo, per prima cosa ho definito un paio di variabili di comodo e qualche parametro da passare via command line:
Inizialmente mi ero “intestardito” con il voler raccogliere il primo token prima di generare la sessione e per questo utilizzavo una chiamata wget esterna (fu il primo tentativo durante una live su Twitch). Ho poi cambiato strada ma ho voluto mantenere questo passaggio commentato nello script.
Una volta preparati gli ingredienti principali lo script deve solo eseguire le operazioni di generazione token e richiesta login per ogni password in lista:
for p in passwords:
# get token
content = session.get(url_index, cookies=cookie)
lines = content.text.splitlines()
for line in lines:
if 'user_token' in line:
line = line.split("'")
user_token = line[5]
data = { 'username': 'admin', 'password': p, 'Login': 'Login', 'user_token': user_token }
test = session.get(url_login, cookies=cookie, params=data)
res = test.text
# print(res) #### only for debug output
print("Test-- \t password: {} \t token: {} \t cookie: {}".format(p, user_token, cookie))
if 'Username and/or password incorrect.' in res:
print("Fail-- \t Username and/or password incorrect.")
print("-"*20)
if 'Welcome to the password protected area admin' in res:
print("Good Job! The correct password in \"{}\"".format(p))
print("-"*20)
La versione completa dello script è disponibile nella mia repository GitHub. Trovate una ulteriore versione della soluzione in questo post su medium che ho trovato molto interessante.
In definitiva lo script non fa altro che eseguire un tentativo di accesso per ogni credenziale fornita generando, ad ogni iterazione, il nuovo user_token da utilizzare nella richiesta, aggirando così il controllo.
In esecuzione il risultato dovrebbe essere qualcosa di simile:
Di seguito una breve clip dimostrativa del lab:
Approfitto dell’occasione di questo post per segnalare che inizierò probabilmente a caricare alcune clip dimostrative sul mio canale YouTube per mantenere un archivio dei nostri esperimenti.
Prossimi step
Probabilmente aggiungerò allo script a possibilità di utilizzare un file come elenco password e vorrei portare dentro anche la definizione dell’ID di sessione da utilizzare.
DVWA ha diversi altri esercizi che meritano uno spazio, ho recentemente parlato in live delle SQL Injection su cui sicuramente tornerò assieme alla possibilità di eseguire Code Injection.
Ci sono molti scenari che varrebbe la pena di provare, in questa sessione, con riferimento alla Twitch Live del 17 giugno, partiamo dalla base di questa tecnica.
net schema
La struttura del lab base è molto semplice ma ben mette in evidenza l’utilità della tecnica in se. Lo schema mostra, da sinistra verso destra, il laptop del potenziale attacker posizionato sul segmento di rete di un server Windows (ws1) di cui abbiamo le informazioni di base restituite dalla scansione nmap:
nmap
Oltre il primo server Windows vi è un altro sistema, anch’esso Windows con hostname ws2, che condivide una rete con ws1 ma non con il sistema dell’attacker che in questo esempio è la più classica delle Kali.
Ciò che vogliamo ottenere è “toccare” il sistema ws2 passando per ws1 utilizzando appunto l’arsenale che abbiamo a disposizione sul sistema dell’attacker. Non potendo comunicare direttamente con ws2 dobbiamo prima accedere a ws1 per utilizzare la macchina come “ponte” per le nostre azioni. Per prima cosa dobbiamo guadagnarci un accesso al sistema ws1; in questo semplice lab abbiamo utilizzato O.S. volutamente vulnerabili per praticità ed in particolare le macchine presentano la vulnerabilità a tutti nota per il famigerato exploit EternalBlue:
set exploit in metasploit
Senza dilungarci troppo sull’utilizzo di metasploit (mi avete già in molti chiesto una sessione su questo strumento, la preparerò), utilizzeremo la vulnerabilità CVE-2017-0144, che consente una Remote Code Execution (RCE) sul sistema target al quale faremo eseguire uno specifico payload: una reverse shell di meterpreter.
conf. payload
La configurazione delle opzioni del payload è in questo caso molto semplice, è infatti sufficiente definire l’IP del target ed essere certi di essere su un segmento di rete che il target possa raggiungere direttamente per consentire alla sessione della reverse shell di instaurarsi. Il comando per definire l’host target è il seguente:
set rhost <IP>
Come ultima azione con il comando “run” verrà lanciato l’exploit:
esempio tratto da un altro lab. con la stessa vulnerabilità
Meterpreter mette a disposizione moltissimi comandi/strumenti che possono essere eseguiti sulla macchina target, ne cito alcuni:
load: consente di avviare/caricare ulteriori plugin e relative funzionalità (es kiwi)
ps: presenta l’elenco dei processi attivi sulla macchina target
clearev: cancella gli eventi dai registri della macchina target
shell: accede alla command shell della macchina target
ipconfig: visualizza le configurazioni delle NIC della macchina target
Una volta ottenuto un accesso sul sistema target è necessario ottenere rapidamente informazioni di base come la configurazione di rete del sistema. Con il comando ipconfig possiamo visualizzare la configurazione delle NIC a bordo macchina. Il sistema presenta, come capita spesso, più device di rete, ma in questo caso ci interessano solo i device associati alle reti locali:
meterpreter > ipconfig
Interface 11
============
Name : Connessione di rete Intel(R) PRO/1000 MT
Hardware MAC : 00:0c:29:34:1e:11
MTU : 1500
IPv4 Address : 192.168.1.10
IPv4 Netmask : 255.255.255.0
[...]
Interface 16
============
Name : Connessione di rete Intel(R) PRO/1000 MT #2
Hardware MAC : 00:0c:29:34:1e:1b
MTU : 1500
IPv4 Address : 192.168.19.163
IPv4 Netmask : 255.255.255.0
IPv6 Address : fe80::356c:5658:599c:5774
IPv6 Netmask : ffff:ffff:ffff:ffff::
L’interfaccia 11 è configurata sullo stesso dominio di broadcast della macchina da cui stiamo simulando gli attacchi (192.168.1.0/24) e la macchina target presenta almeno un’altra subnet configurata: 192.168.19.0/24. Questa subnet non è raggiungibile direttamente dal sistema Kali in quanto non abbiamo un gateway che ci consenta di raggiungere la porzione di rete individuata.
conf. di rete dell’attacker: la seconda network non è raggiungibile direttamente
Essendo un’intera /24 è plausibile ipotizzare che vi siano altri endpoint all’interno del segmento di rete ed è quindi utile indagare ulteriormente. Alcune informazioni possono essere rilevate direttamente dalla macchina target con semplici comandi locali: è probabile che il sistema a cui abbiamo avuto accesso abbia fatto traffico verso altri sistemi della rete e ne potremmo trovare traccia nella arp-table:
arp cache tramite il comando “arp”
Dalle informazioni in nostro possesso possiamo ipotizzare che vi siano effettivamente altri sistemi sulla rete “interna” ed è quindi utile indagare ulteriormente attraverso una scansione di rete. Per eseguire questa operazione dovremmo poter lanciare la scan dalla macchina compromessa in quando ha diretta visibilità della rete. Questa operazione, per quanto fattibile, non è particolarmente comoda. Il pivoting ci consente di utilizzare la macchina “esterna” come ponte per la rete interna esattamente come farebbe un router. Con il comando “background” possiamo uscire dalla sessione di meterpreter senza chiuderla ed aggiungere una nuova rotta al solo sistema affinché la rete 192.168.19.0/24 sia raggiungile a Level 3.
session background
Il comando per aggiungere la rotta è “route add”:
route add
Una volta definita la sessione da utilizzare per instradare il traffico (la reverse shell in questo caso) è possibile eseguire azioni direttamente verso la macchina interna. Un modulo comodo potrebbe essere il portscan per eseguire ulteriori scansioni all’interno della rete:
> use auxiliary/scanner/portscan/tcp
> set RHOSTS 192.168.19.170-179
> set PORTS 445
> run
Una volta lanciata la scansione (potrebbe richiedere un po’ di tempo) verranno riportati i risultati direttamente nell’output di metasploit:
scan attraverso la sessione meterpreter
Nel caso specifico la scansione ha individuato un sistema raggiungibile dalla macchina compromessa con il 192.168.19.175 con la porta 445 in ascolto. Una prova per verificare questo risultato potrebbe essere un tentativo di comunicazione dalla macchina target, sarà sufficiente tornare nella sessione meterpreter relativa:
ping internal host
Il risultato dell’operazione è quindi la possibilità di eseguire azioni sulla macchina interna alla rete sfruttando il canale aperto della sessione meterpreter sul sistema di “periferia”.
La tecnica consente di proseguire nelle azioni di ricognizione da una posizione estremamente comoda: se la visibilità della rete lo consente il sistema potrebbe essere utilizzato per individuare apparati interni come network appliance o altri device, con il semplice comando “arp” possiamo farci un’idea dei sistemi con cui la macchina target comunica così da tentare di ricostruire una topologia.
Di solito è normale che i sistemi interni di una rete siano in grado di comunicare tra loro. Questa tecnica ci ricorda però quanto sia indispensabile la segregazione con particolare riferimento alle policies che devono, di fatto, bloccare il traffico proveniente da reti “untrusted”. In uno scenario come quello analizzato la visibilità tra una ipotetica rete DMZ e la rete LAN rappresenterebbe un reale problema: concedere ai sistemi “esposti” di dialogare direttamente con i sistemi interni porta inevitabili rischi per la sicurezza cyber.
Il passaggio successivo è solitamente quello di mantenere una presenza all’interno della rete target senza dover eseguire ripetutamente l’exploiting della macchina vulnerabile. Questa parte del laboratorio, con la relativa costruzione di un rudimentale C2, è stata trattata nelle live di fine giugno per le quali scriverò un altro post dedicato.
Osservare alcune specifiche tecniche di attacco consente di comprendere meglio quanto possa entrare in profondità un attacker. Uno scenario abbastanza tipico che mi capita di analizzare è relativo alla presenza di reti relativamente “piatte”, ovvero segmentate a livello di subnet/vlan ma talvolta non segregate e lasciate molto libere di comunicare tra loro.
Il disegno di una rete impatta notevolmente sulle opzioni che un attacker ha a disposizione una volta individuata una breccia. Lasciandoci alle spalle l’irrazionale pensiero che “a noi non capiterà mai”, una strategia di difesa efficace deve tener conto della possibilità che un attacco abbia successo con la conseguenza di trovarci con elementi interni della rete compromessi almeno in parte. Esistono decine di scenari esplorabili in tal senso: in generale nel momento in cui un attacker dovesse guadagnare una posizione all’interno della rete, non sapendo come la rete è strutturata, andrebbe a caccia di nuove informazioni con l’obiettivo di utilizzare il sistema compromesso come “base” per altre azioni.
Il pivoting è una delle classiche tecniche per entrare ancor più in profondità nella rete target in quanto consente all’attacker, se ve ne sono le condizioni, di passare da una rete all’altra estendendo il suo raggio d’azione. Ho volutamente evidenziato l’esigenza di specifiche condizioni perché questo avvenga in quanto, di fatto, un buon disegno della rete ed opportuni controlli possono limitare enormemente l’attività dell’ospite indesiderato.
A me piace mescolare, quindi nella live di questa sera tiriamo su un piccolo lab per provare la tecnica citata per vedere come un attacker potrebbe comportarsi e poi analizziamo le possibili azioni correttive da adottare per limitare l’azione dell’attacker.
Nella prima parte ci eravamo fermati all’analisi della memoria subito dopo il crash del nostro servizio a seguito di una nostra specifica azione: abbiamo inviato un contenuto al server composto da una serie di “A” e abbiamo scoperto di poter andare a sovrascrivere il contenuto del registro EIP e anche l’area di memoria destinate alle variabili locali che fa riferimento all’ESP.
Visto che la vulnerabilità ci ha consentito di scrivere “A” ovunque possiamo calcolare la dimensione dell’area di memoria a cui abbiamo avuto accesso. Con Immunity possiamo analizzare il DUMP della memoria semplicemente facendo “tasto destro” sull’ESP e selezionando l’opzione Follow in DUMP:
Nel riquadro in basso a sinistra verrà presentato lo stato della memoria e andando in cima all stack è possibile vedere l’area di memoria in cui iniziamo a scrivere (0x0097F200). In modo simile, andando sul fondo dello stack, possiamo vedere dove ci siamo fermati (0x0097FDA8). Semplicemente facendo la differenza tra questi due valori avremo la dimensione di memoria sovrascritta:
Questo dato, 2984 byte, è estremamente importante per le fasi di analisi e stesura del codice del nostro exploit: ora sappiano che se inviamo questa quantità di informazioni il servizio andrà in crash e possiamo verificarlo con un piccolo script:
Siamo quindi arrivati a governare il contenuto della memoria, EIP ed ESP compresi, tramite un nostro script. Il prossimo passo è scriverci qualcosa di sensato partendo proprio dall’instruction pointer. Dobbiamo prima di tutto capire come riempire il buffer senza mettere delle “A” anche del EIP. Una tecnico abbastanza semplice è mandare in crash il programma utilizzando caratteri che non abbiamo un pattern così da identificare successivamente cosa è stato scritto all’interno del registro ed avere così la possibilità di individuare il numero di byte necessari a riempire il buffer.
Possiamo utilizzare l’utility msf-patter_create per creare una stringa di 2984 caratteri:
Utilizzando la stringa all’interno del payload, al posto del carattere “A” ovviamente, otterremo nuovamente il crash del servizio ma il contenuto del registro sarà molto diverso:
L’EIP è stato infatti sovrascritto dai caratteri del pattern che qui vediamo ovviamente visualizzati con il corrispettivo byte esadecimale visto che all’interno del registro non è possibile inserire delle “stringhe” nel loro formato. Non resta che scoprire quanti caratteri – e quindi byte – sono stati scritti nel buffer prima di arrivare a sovrascrivere l’EIP. Utilizziamo questa volta l’utility msf-patter_offset a cui chiederemo il numero di byte di offset in relazione alla stringa, opportunamente convertita, corrispondente all’esadecimale che vediamo dell’EIP:
$ msf-pattern_offset -l 2984 -q 386F4337
[*] Exact match at offset 2003
Abbiamo trovato la dimensione del buffer: 2003 byte. Per verificare il nostro calcolo possiamo quindi modificare il nostro prototipo di exploit al fine di riempire il buffer per tutti i suoi 2003 byte e poi utilizzare un altro carattere per sovrascrivere ciò che viene subito dopo, ovvero il registro EIP.
Riavviando il server tramite Immunity dovremmo ottenere il seguente comportamento:
Il contenuto del registro EIP è ora l’esadecimale “42 42 42 42” che corrisponde esattamente al carattere che abbiamo scelto per la variabile new_eip del nostro script. Ora controlliamo l’instruction pointer e si nota come l’ESP sia ora vuoto in quanto ci siamo fermati all’invio della stringa che doveva sovrascrivere l’EIP. Se nel nostro payload andiamo ad aggiungere un altro set di caratteri, ad esempio una serie di “C”, fino a riempire i restanti byte a disposizione dovremmo ottenere la sovrascrittura controllata anche dell’ESP.
Si seguito lo stato dei registri con questa modifica:
Siamo quindi nella condizione di poter scrivere ciò che vogliamo nelle tre aree di memoria a disposizione. Non stiamo però controllando l’esecuzione del programma che infatti va in crash. Questo perché non stiamo gestendo correttamente il contenuto del EIP (stiamo utilizzando dei semplici caratteri) ed il programma non può eseguire la sua JUMP nella corretta posizione di memoria dove si trova l’ESP.
Dobbiamo quindi capire in che area della memoria far puntare EIP per gestire correttamente la JUMP verso ESP. Immunity mette a disposizione diverse plugin tra cui una è MONA (https://github.com/corelan/mona). Non mi soffermo sull’utilizzo del tool e vi suggerisco il manuale scritto dall’autore; tramite il comando jmp -r ESP il tool ci mostra tutti i “pointers” di tipo “jmp esp”:
Ovviamente il servizio quando è in esecuzione ha diverse JUMP verso ESP in quanto ci sono più funzioni che vengono chiamate. A noi interessa individuare quella di cui stiamo abusando con il nostro exploit. Da notare che delle varie JUMP le ultime due contengono riferimenti a contenuti ascii… interessante visto che noi stiamo proprio inviando questo tipo di dato al programma. Potremmo quindi ipotizzare che una di queste JUMP sia quella che vogliamo controllare.
Per appurarlo dobbiamo annotarci il valore del registro (0x62501203 nel mio lab.) ed utilizzarlo come contenuto per l’EIP del nostro exploit. E’ ovviamente da considerare che questo valore è la rappresentazione esadecimale dei byte che sono effettivamente presenti del registro, dobbiamo quindi a nostra volta mandare il corretto valore opportunamente convertito.
Utilizziamo la libreria struct di cui nella live su Twitch abbiamo parlato per un abbondante quarto d’ora e qui non ci soffermiamo. Per convertire correttamente il dato il comando, da utilizzare al posto delle “B”, è il seguente:
new_eip = struct.pack('<I', 0x62501203)
Lo script ora sarà in grado di eseguire la JUMP in una posizione legittima dell’ESP dove, nell’ultima esecuzione, abbiamo posizionato una serie di “C”. Per verificare cosa accade a runtime possiamo impostare un breakpoint su Immunity così da fermare il programma subito prima della JUMP:
Eseguendo ora l’exploit dovremmo ottenere qualcosa di simile a questo:
Il valore dell’EIP è quello da noi impostato e se andiamo a verificare lo stato dello stack possiamo controllare il contenuto della memoria dove sono ben visibili i caratteri “A” che stiamo utilizzando per il buffer, il contenuto dell’EIP opportunamente convertito ed i caratteri “C”.
Grazie al breakpoint l’esecuzione è interrotta ma possiamo utilizzare i tasti F6 ed F7 per andare indietro ed avanti una istruzione alla volta. In questo momento siamo fermi sulla JUMP quindi andando avanti di una istruzione la JUMP verrà eseguita verso un’area di memoria legittima, quella dell’ESP.
Possiamo quindi osservare il contenuto delle prossime posizioni della memoria che corrisponde all’esadecimale 43, ovvero il carattere “C” con cui abbiamo riempito l’ESP. In pratica abbiamo raggiunto il principale obiettivo: possiamo governare la JUMP in un’area della memoria che possiamo controllare. Ora dobbiamo decidere cosa far eseguire e posizionare le istruzioni opportune in quest’area di memoria.
Nota: in questa occasione saltiamo il controllo di eventuali caratteri non ammessi, si prenda atto che non utilizzeremo istruzioni “\x00” nel nostro shellcode.
E’ da considerare che questa operazione, in contesti più complessi rispetto al nostro vuln-server, presenta delle incertezze ed è quindi opportuno costruire le condizioni per favorire l’esecuzione del nostro shellcode. Tipicamente viene utilizzata una specifica istruzione: \x90, la famigerata NOP. Di base diremo al processore di non fare nulla per qualche iterazione prima di incontrare il nostro shellcode.
Come shellcode useremo un altro famigerato strumento: meterpreter. Per utilizzare questa reverse shell nel nostro exploit dobbiamo inserire le istruzioni necessarie all’interno del payload. Con msfvenom possiamo fare esattamente questo:
L’exploit è pronto e il payload è stato opportunamente modificato per aprire una shell verso la macchina attaccante. Ovviamente dobbiamo predisporre la macchina da cui eseguiremo l’exploit affinché sia in grado di accettare la connessione remota. Per comodità di laboratorio possiamo usare metasploit e configurare l’handler per meterpreter:
Una volta avviato il servizio sul sistema target potremo lanciare l’exploit. Se tutto funziona correttamente il server questa volta non andrà in crash ma resterà in esecuzione senza dare messaggi specifici. Accedendo alla console di metasploit dovremmo invece vedere la sessione della shell attiva:
L’argomento exploiting è per me molto affascinante e lo ritengo molto utile per comprendere diversi aspetti del funzionamento dei sistemi e delle applicazioni. Quando ho annunciato la mia volontà di dedicare uno spazio in quelle che poi sono state due live per un totale di 5 ore di video e due articoli qualcuno ha etichettato l’argomento come anacronistico probabilmente non riuscendo a vedere il lato formativo del tema.
Incontro molte persone che sulla carta sono “esperti” in cyber security e che non hanno mai neanche provato ad analizzare una vulnerabilità. Ritengo che questo trend sia pericoloso, si tende a dare per scontata la conoscenza intima dei sistemi ma è evidente che c’è qualcosa che non sta funzionando nella formazione delle nuove figure professionali. Ci sono delle lacune a livello di nozioni base e questo fatto è un evidente limite che gli attacker non è detto che abbiano.
Premessa doverosa: tratto il tema perché mi piace e appassiona molto ma non sono certo un esperto, mi rivolgo quindi a chi come me è affascinato dall’argomento ed ha interesse ad approfondire passando per un esercizio pratico.
Durante una sessione live di qualche settimana fa (l’argomento era una simulazione di attacco) si è un po’ discusso e sono emerse domande circa lo sfruttamento delle vulnerabilità e le tecniche di exploiting. Ho quindi pensato di dedicare una live (ma ne serviranno almeno due) all’argomento con lo scopo di semplificare il semplificabile e fare qualcosa di molto pratico. La live di giovedì 5 maggio, ancora disponibile sul mio canale Twitch, introduce quindi l’argomento con un piccolo laboratorio estremamente realistico che chiunque può replicare. In questo post provo a mettere “in fila” i vari step visti durante la prima parte in live.
Intro: un grammo di teoria
Resistete, sono due cose ma fondamentali. Dobbiamo necessariamente capire come si manifesta un buffer overflow. Partiamo da un esempio molto semplice ed immaginiamo un programma base che ha una funzione main() dove avvengono “cose” ed una funzione task() che fa altre “cose”:
int main() {
task();
other_task();
}
int task() {
char buff[42];
...
}
Cose succede nella memoria del nostro elaboratore quando un programma come questo viene eseguito? L’area di memoria interessata è chiamata stack (pila) perché si comporta proprio come una pila di byte nel momento in cui viene riempita di informazioni.
Sul “fondo” viene posizionata la funziona main() e le relative variabili locali, subito sopra si trova l’area di memoria che contiene l’indirizzo a cui andare per tornare alla funzione main() ed infine l’area dedicata alla funzione task().
Ciò che avviene quando il programma viene eseguito è sintetizzabile con i seguenti step:
la funzione main() viene eseguita
viene chiamata la funzione task()
viene salvato il return address nel registro così da riprendere la funzione main() da dove si è fermata una volta eseguita la funzione task()
viene eseguita la funzione task()
viene letto il valore del return address
il programma prosegue dall’istruzione successiva alla chiamata della funzione task()
Se tutto procede senza errori il programma terminerà con successo. In questo passaggio è importante comprendere che durante l’esecuzione della funzione task() l’area di memoria allocata dipende dalle esigenze della funzione in termini di “consumo”. Come si nota dallo pseudo-codice la variabile buff[42] è un array che può contenere 42 elementi. Cosa succederebbe se provassimo a scrivere 200 caratteri e non controllassimo questo evento a livello di codice?
Il contenuto del registro dove era stato salvato il return address viene sovrascritto ed il programma tenterebbe di riprendere da una posizione di memoria (AAAA nell’esempio) inesistente o non valida con relativo crash.
Exploiting
Capita la teoria vediamo come è potenzialmente sfruttabile questo meccanismo. Se potessimo controllare il valore del return address potremmo indirizzare il programma altrove ed eseguire le istruzioni presenti in altre aree di memoria. Con la stessa logica se potessimo scrivere istruzioni arbitrarie, invece delle “AAAA…”, nelle aree di memoria disponibili potremmo impostare il return address così da eseguire un jump esattamente dove sono state posizionate le nostre istruzioni arbitrarie.
Per ottenere questo risultato dobbiamo ovviamente sapere quanti byte scrivere nelle differenti aree di memoria. Ci serve quindi calcolare l’esatta dimensione del buffer, l’esatta posizione del registro EIP che contiene il citato return address ed infine l’inizio e la fine dalla successiva area di memoria.
Per ottenere tutte queste informazioni bisogna lavorare un po’ di debug e qualche calcolo esadecimale. Il modo migliore per comprenderlo è vederlo dal vivo, quindi il prossimo step è mettere le mani in pasta in un lab.
Lab Setup
Come accennato ad inizio post il laboratorio in questione ha il vantaggio di essere molto il linea con la realtà. Abbiamo un sistema che ospita un’applicazione vulnerabile la quale espone un servizio contattabile remotamente. Per mettere in piedi il sistema target dobbiamo quindi semplicemente predisporre una VM con sistema operativo Windows e scaricare l’applicazione vulnerabile.
Una volta preparata la vostra VM target dovete procurarvi l’applicazione che presenta la vulnerabilità: https://github.com/stephenbradshaw/vulnserver. Di base è un eseguibile che può essere lanciato direttamente dal prompt dei comandi:
Abbiamo quindi la nostra applicazione avviata e pronta a ricevere delle connessioni. Per fare qualche prova e come base anche per le successive operazioni di analisi possiamo usare la solita Kali che ci darà un mano anche successivamente grazie ad alcuni tools comodi. In questo scenario è necessario che le due VMs siano in comunicazione. Nel mio laboratorio condividono anche la stessa network ma non è un requisito.
Testing dell’applicazione
Dalla nostra Kali possiamo quindi provare a connetterci al server che risponde sulla porta 9999 utilizzando semplicemente netcat:
nc 192.168.1.7 9999
Il risultato dovrebbe essere qualcosa di simile:
A sinistra la sessione netcat, a destra la console del servizio.
Il servizio mette a disposizione diversi comandi in grado di ricevere dei valori. Nel caso specifico noi sappiano già qual è la funzione vulnerabile mentre in una situazione reale l’analista dovrebbe andare a caccia prima di tutto della vulnerabilità o del bug da sfruttare. In questa sessione non tocchiamo il tema bug hunting quindi ci limitiamo a saltare al momento in cui, tramite una tecnica molto usata che è il fuzzing, scoviamo il bug nella funziona TRUN del programma.
Mettiamoci quindi per un attimo nei panni del bug hunter (tra l’altro attività meravigliosa che richiede molta abilità) che arriva al test del comando TRUN del server ed utilizziamo un tool della nostra Kali: generic_send_tcp. Questo piccolo software ci consente di creare ed inviare pacchetti TCP al target per vedere cosa succede, dobbiamo prima definire le istruzioni da passare al programma che possiamo mettere in un file di configurazione che io chiamerò fuzz.spk:
Il file ha tre semplici direttive abbastanza chiare:
leggiamo l’output del server così da vedere cosa risponde alle nostre sollecitazioni
chiamiamo il comando TRUN
“spariamo” del contenuto per vedere come reagisce
Una volta pronto il file con le configurazioni possiamo fare fuoco:
generic_send_tcp 192.168.1.7 9999 fuzz.spk 0 0
Dovremmo ottenere il crash dell’applicazione sul server Windows:
A sinistra lo script di fuzzing in esecuzione, a destra il servizio andato in crash.
Il programma va in crash e abbiamo quindi la conferma del bug. Nel nostro caso sappiamo già essere un buffer overflow e in questo lab ci comporteremo di conseguenza cercando questo specifico comportamento.
Analisi della memoria
Abbiamo un servizio che va in crash se sollecitato in un certo modo… andiamo a vedere cosa succede in memoria quando si verifica il crash. Per questo lab utilizzo sulla macchina Windows il software Immunity Debugger; è una scelta di comodo che assolve al compito specifico di farci vedere cosa viene caricato in memoria quando il programma è in esecuzione e quando va in crash.
Immunity consente di avviare il servizio direttamente dalla propria interfaccia così da “pilotarne” ed analizzarne i singoli step, anche una istruzione alla volta. Avviamo quindi il servizio da Immunity ed avviamo il servizio:
Sulla destra troviamo lo stato dei registri del processore e in questa fase è interessante vedere che, oltre a non esserci errori, il registro EIP contiene una posizione di memoria che corrisponde a dove “mandare” il puntatore delle istruzioni una volta eseguita l’istruzione in gestione. E’ quini il return address di cui si parlava prima.
Vediamo cosa succede quando lanciamo il nostro fuzzer e mandiamo in crash il programma:
Su questo screenshot si potrebbe parlare per diverse ore. Cosa sta succedendo?
Subito in cima vediamo chiaramente la nostra richiesta: la chiamata alla funzione TRUN arriva direttamente da nostro fuzzer e subito dopo vediamo i valori passati alla funzione, una serie di caratteri “A”.
Altro elemento da notare è il contenuto dell’area a cui punta il registro ESP, porzione di memoria destinata alle variabili locali del programma in esecuzione. Anche qui vediamo una serie di caratteri “A”.
Infine, forse l’elemento più interessante, il contenuto del registro EIP: 41414141 ovviamente esadecimale. A cosa corrisponde 41 esadecimale? Al carattere “A”. Interessante! Le “A” che abbiamo sparato con il fuzzer sono andate praticamente dappertutto: hanno riempito la porzione di memoria destinata alle variabili della funzione, hanno sovrascritto il registro EIP e sono arrivate a riempire l’area di memoria destinata alle variabili del programma. Quale delle precedenti immagini vi ricorda? Siamo chiaramente davanti ad un buffer overflow.
Per questa prima parte mi fermo qui. Nella seconda parte vediamo come manipolare in modo preciso il contenuto dei registri ed iniziare a scrivere il nostro exploit ora che abbiamo individuato la vulnerabilità.
A seguito di specifici Security Assessment è normale che emergano vulnerabilità anche gravi per le quali, tipicamente, si suggerisce di eseguire un patching del sistema o altre azioni di mitigazione. Purtroppo va considerato che in alcune situazioni in patching non è applicabile, spesso per ragioni non tecniche. Per portare un esempio particolarmente emblematico basta far riferimento all’evoluzione dei sistemi di automazione industriale, macchine o intere linee di produzione realizzate per restare operative per decenni e che spesso presentano componenti software che, semplicemente, non si possono aggiornare perché non è mai stata rilasciata una nuova versione. In questi casi non è raro trovare sistemi operativi particolarmente datati con tutti i problemi a livello di gestione della sicurezza che questo comporta.
E’ opportuno essere pragmatici ed agire in un’attica di gestione del rischio, cosa che non significa – purtroppo – necessariamente eliminare ogni tipo di rischio. Una volta rilevata una possibile debolezza per la quale non è possibile applicare le più classiche remediation potrebbe essere utile approfondire l’analisi per cercare di stimare nel modo più preciso possibile quanto sia sfruttabile la falla ed i possibili impatti sul business del potenziale target.
Progettare e realizzare simulazioni di attacco può essere un utile strumento di verifica in quanto da la possibilità di esplorare realisticamente ciò che potrebbe avvenire e come gli eventuali sistemi di sicurezza reagirebbero a certe sollecitazioni. Inoltre, in caso di detection, l’attività è utile anche per verificare l’efficienza delle procedure di incident responce dei team operativi.
In questi giorni sto preparando uno scenario molto semplice che coinvolgerà parte del team target in qualità osservatori al fine di comprendere alcuni aspetti delle attività offensive. Vista la natura in parte didattica dell’attività ho pensato di condividere parte dello scenario ed approfittare di una delle sessioni live su Twitch per giocare un po’ con lo scenario.
Elementi base del lab
Come accennavo lo scenario è molto semplice in quanto presenta sistemi molto obsoleti che devono necessariamente esporre servizi vulnerabili. Nel caso specifico si tratta di sistemi Microsoft Windows fuori supporto e non aggiornabili che presentano le vulnerabilità note Blue Keep (CVE-2019-0708) e Ethernal Blue (CVE-2017-0144), le macchine server utilizzano proprio uno dei servizi vulnerabili in quando espongono delle share folder.
I sistemi vulnerabili sono confinati in una rete server (blue network nello schema) e sono raggiungibili solo da alcuni sistemi client che per ragioni operative devono accedere alle share dei citati server. La visibilità tra le reti è garantita da un firewall che, nella configurazione di base, non applica controlli specifici per il controllo delle minacce.
Per il lab di base utilizzo quindi i seguenti sistemi:
Virtual Machine “client” con sistema operativo Microsoft Windows 7
Virtual Machine “server” con sistema operativo Microsoft Windows 7
Virtual Machine “server” con sistema operativo Ubuntu Linux 22.04 LTS
Virtual Machine “firewall” con vAppliance Endian (v3.3.2) Community Edition
Preparazione macchina client
Il sistema client è veramente base, una semplice installazione di Windows 7 va benissimo. Le uniche configurazione della macchina sono a livello rete e gli utenti. La configurazione di rete del mio sistema è la seguente:
Dettaglio conf. di rete
Nel mio lab il gateway della rete client è il Firewall che a sua volta ha un gateway per le reti esterne. In questo modo dando ai sistemi che compongono il laboratorio un DNS è possibile farli accedere alla rete internet. La configurazione rispecchia lo scenario reale.
Traceroute dalla macchina client
Per quanto riguarda gli utenti l’esigenza è di avere un utente amministratore locale ed un utente non privilegiato. Nello scenario reale questo sistema sarebbe membro di un dominio Active Directory ma in questo caso ci accontentiamo della doppia utenza. E’ ovviamente previsto, in fase di attacco, l’accesso fisico al sistema con una sessione attiva dell’utente non privilegiato.
Nota a margine: il client nello scenario reale potrebbe essere una macchina Windows 7 o Windows 10. In questa sessione ci accomodiamo sul sistema operativo più datata.
Preparazione macchina server Windows
Di base si tratta di una macchina praticamente identica alla macchina client se non per la posizione nella rete (come da schema), la configurazione della share e le relative regole del firewall locale. A dire il vero nello scenario reale il firewall locale è disabilitato, quindi questa sarà la configurazione di partenza anche nel lab.
Preparazione macchina server Linux
Si tratta di un semplice ambiente LAMP basato su Ubuntu Linux e in questo scenario probabilmente non verrà utilizzato, ma visto che l’obiettivo è sfruttare il laboratorio anche per altre sessioni ha senso tenerla pronta.
Preparazione macchina Firewall
Come accennato nel mio caso ho scelto una semplice vAppliance Endian per la quale ho configurato tre zone e relative reti:
Green: corrisponde alla LAN della rete di laboratorio e su questa interfaccia è anche attiva la Management Console disponibile alla URL https://ip:10443
Blue: corrisponde al segmento SERVER della rete di laboratorio
Uplink: corrisponde alla WAN della rete di laboratorio
Endian Console
In configurazione di default la zone Green e la zona Blue sono in piena visibilità, quindi il sistema client potrà dialogare da subito con il sistema server e il traffico potrà essere registrato nei logs del firewall:
Preparazione macchina c&c
Come accennato anche nella live del 21 aprile (online ancora per qualche giorno) per pura comodità la macchina che utilizzeremo come c&c sarà il sistema Kali del mio lab ma, visto l’utilizzo che vogliamo farle nei primi test, va benissimo una qualsiasi macchina linux che sia in grado di ospitare un web server. Nel laboratorio utilizzerò Apache con Php e Python.
Questo sistema verrà utilizzato come una macchina già compromessa o comunque sotto il controller dell’attacker che è in grado di accedervi remotamente e comodamente via ssh.
Prima fase dell’attacco
Come anticipato lo scenario prevede un accesso fisico al sistema client da cui si dovrà poi sviluppare l’attacco. Partirei quindi da una serie di rilevamenti sul sistema di partenza per poi usare la macchina come base per una scansione mirata nella rete target.
Una delle ipotesi di partenza è che l’attacker sia ragionevolmente certo di trovare le vulnerabilità citate, il sistema di scansione dovrà quindi operare in modo chirurgico. Una volta individuati i sistemi potenzialmente vulnerabili si dovrà procedere con l’exploiting del sistema con lo scopo di creare un accesso permanente alla macchina.
Oltre alla definizione dei singoli strumenti per eseguire le azioni offensive l’obiettivo di questa prima fase è quello di costruire i tools da eseguire rapidamente sul sistema su cui si ha la possibilità di accedere fisicamente. Per verificare l’efficienza dell’operazione l’azione verrà cronometrata.
Il base ai risultati della prima fase, che in parte potremo discutere nella prossima live del 28 aprile, valuteremo le attività della seconda fase in cui coinvolgeremo il sistema c&c.
Un post di riflessione in merito ai corretti (a mio parere) spunti che Paolo Perego propone in questo sui articolo. Non ripeto quello che ha scritto Paolo, leggetelo e valutate voi stessi, il suo post merita. Parto direttamente dalle sue conclusioni: dove sta la debolezza di una passphrase rispetto ad una password complessa?
Provo ad affrontare il tema dal punto di vista dell’attacker che ha ovviamente l’obiettivo di eseguire il cracking di un accesso ad un sistema o ad una applicazione. Nel post di Paolo si fa riferimento al contesto dei portali e siti web ma il tema della verifica della robustezza prescinde il contesto. Per procedere quindi con le specifiche prove utilizzo un piccolo lab composto dalla solita kali (per comodità) che farà sia da base offensiva che da target con un utente “test” per il quale ho configurato un semplice accesso SSH. Come password utilizzeremo quella proposta da Paolo: “Il colore della mia stanza è blu”.
Wordlist
Partiamo dalle basi dell’attacco ad una credenziale: il brute forcing utilizzando un elenco di parole predefinite. In questo caso i tipici dizionari presenti nei diversi tools (kali compresa) riportano tipicamente un elenco di parole, non di frasi. Una wordlist classica sarebbe quindi poco efficace verso una passphrase salvo la creazione di diverse combinazioni di words obiettivamente molto onerosa da costruire in termini di tempi di generazione e volumi di dati. Escluderei quindi questa tecnica tra quelle efficaci.
Generazione di credenziali
E’ probabilmente più funzionale tentare di generare una credenziale partendo da un dato che non ci è però dato sapere in anticipo, ovvero il fatto di essere di fronte ad una passphrase e non una password.
Se l’attacker partisse da questo assunto (cosa di per se non particolarmente realistica senza dati a supporto della tesi) potrebbe valutare l’utilizzo di varie combinazioni di parole comuni a formare una frase semplice da ricordare. Non mi stupirebbe scoprire che molti utenti, in questo scenario, potrebbero voler utilizzare delle citazioni famose o frasi che possano essere in qualche modo riferibili al sistema a cui si sta accedendo.
In tal senso un potenziale approccio potrebbe essere l’utilizzo di tools come cewl per creare una lista si parole partendo dal sito del target o da altri contenuti (es: racconti o testi comuni) per provare a costruire poi delle frasi.
Plausibile ma sicuramente non comodo e credo, anche in questo caso, poco efficace.
Un altro approccio, visto che le passphrase di base sono stringhe relativamente lunghe, è il brute force più tradizionale con calcolo delle varie combinazioni. Mettiamoci in un caso relativamente comodo dove la frase è tipicamente composta da caratteri alfabetici con degli spazi come separatori. Assumiamo anche di conoscere la lunghezza della passphrase del target, un metodo realistico in alcuni scenari di attacco è contare ad orecchio le digitazioni dell’utente. Nell’esempio di Paolo ci troviamo comunque davanti ad un frase di 32 caratteri.
Cosa succedere se proviamo a generare frasi di 32 caratteri alfabetici con crunch?
Non impossibile ma decisamente improbabile.
Crack degli hash
Qualche giorno fa ho parlato di credential stuffing. Supponiamo quindi che a causa di un Data Breach gli hash delle passphrase siano disponibili all’attacker. Ai nostalgici verrà subito in mente di utilizzare tools come John the Ripper ma di base le difficoltà saranno le stesse descritte nei precedenti due casi in quanto le tipiche modalità di utilizzo di questi tools prevedono l’impiego di wordlist o utilizzano funzioni di generazione di stringhe.
Le mie conclusioni
Ho voluto scrivere questo post per non rischiare di generare una “battaglia di opinioni”. Paolo ha proposto una riflessione corretta che ho voluto mettere alla prova con qualche esempio reale e ritengo che non vi siano motivazioni che rendano una passphrase meno sicura di una “strong password”… anzi in un certo senso la lunghezza gioca un ruolo a favore non banale.
Quella che voglio fare è una prima riflessione ad “alta voce” su un tema che, per una serie di coincidenze, ho toccato in diverse occasioni negli ultimi giorni. Scrivo quindi di getto qualche pensiero e annoto pubblicamente qualche risorsa per dar seguito poi a qualche approfondimento.
Parto dallo scenario: molte aziende ed organizzazioni hanno spostato – e continuano a spostare – workload e dati in cloud sfruttando i vantaggi ed i servizi dei diversi provider ed in particolare dei tre big: AWS, Azure, GCP. Osservo due principali comportamenti: chi “sposta” ciò che fino a ieri gestiva con una Virtual Machine nella sua forma più simile, come una instance, e chi (a mio parere più saggiamente) approfitta dell’occasione per rivedere anche la forma dei propri workload e fa uso di containers, soluzioni as-a-Service per storage e basi dati, soluzioni/implementazioni serverless. Non è questa l’occasione per discutere di quale sia la strategia migliore per spostare i workload in cloud, parlatene con i vostri cloud architect che sapranno consigliarvi a dovere, il tema che voglio affrontare è come gestire la sicurezza dei dati e dei servizi una volta che li avete spostati… tema che sarebbe meglio affrontare prima di spostare i workload, giusto per non andare poi a mettere pezze.
Parto da qualche domanda che credo dovremmo porci:
Nella realizzazione del nuovo scenario sono state considerate le linee guida del provider in termini di sicurezza dei sistemi e dei dati? (Security by design)
Una volta spostati i dati ed i servizi, dobbiamo ancora preoccuparci di verificare l’esposizione a minacce? (Security Assessment e Security Test)
Come gestiamo la detection di eventuali attività sospette? Le procedure e gli strumenti che abbiamo implementato per i sistemi “on prem” sono ancora valide? E le competenze?
Come reagiamo ad eventuali incident? Abbiamo adeguato le procedure e le strategie di incident management? Ci siamo dotati di strumenti coerenti al nuovo assetto tecnologico?
Discutendo con qualche addetto ai lavori è emerso che non tutte le scelte fatte per i sistemi ospitati “tra le mura aziendali” conservino la loro validità una volta spostati e trasformati i workload. Inoltre capita frequentemente di approcciale la gestione di ciò che è in cloud adattando procedure storicamente applicate per i workload attivi presso i Data Center dell’organizzazione. E’ sicuramente vero che la gestione di alcuni aspetti va in delega al provider ma è altrettanto vero che la delega non piò essere totale: molte configurazioni degli ambienti restano a discrezione dell’organizzazione a partire dagli accessi ed i profili degli utenti, l’eventuale software che chiediamo di eseguire alle piattaforme cloud ha le stesse esigenze del software che facciamo girare all’interno del nostro (Virtual) Data Center, temi come la riservatezza e l’integrità dei dati restano in buona parte in carico al cliente della piattaforma. Per farla breve la sicurezza delle informazioni va gestita in ogni caso, cambiano probabilmente alcuni dettagli operativi ma le metodologie base non cambiano.
Ovviamente gli aspetti da considerare sono moltissimi, in questa prima riflessione volevo partire dagli argomenti che recentemente mi è capitato di affrontare: Assessment e Detection.
Security Assessment
Sul fronte dei security assessment l’esigenza è forse palese: probabilmente non ci si metterà ad eseguire scansioni delle vulnerabilità delle piattaforme cloud (o forse si, io un check lo farei comunque o quanto meno farei delle valutazioni di merito) ma indubbiamente ha senso verificare la coerenza delle configurazioni applicate in fase di attivazione dei servizi al fine di non esporre vulnerabilità logiche e by desing. Inoltre, come accennavo, è probabile che l’organizzazione debba utilizzare componenti software di terze parti o auto-prodotte all’interno della propria piattaforma cloud, questi elementi avranno le stesse esigenze di gestione e manutenzione di prima anche se sarà probabilmente un po’ più semplice agire mitigation e remediation grazie agli strumenti che i cloud provider stessi mettono a disposizione.
Nota a margine. Il tema degli strumenti di gestione o a supporto delle applicazioni in cloud non è banale, disporre di molte opzioni anche a livello di soluzioni di protection rapidamente implementabili è un indiscutibile vantaggio di gestione. Un esempio banale: un security test mette in evidenza una vulnerabilità software in una applicazione web per la quale non esiste una fix e si mitiga con una configurazione a livello di Web Application Firewall probabilmente già disponibile tra le funzionalità attivabili all’interno dell’ecosistema cloud.
Proviamo a ragionare sulla metodologia e per questa prima analisi restiamo sui classici: NIST, Security Testing and Assessment Methodologies. Il documento, che credo non abbia bisogno di presentazioni, illustra metodologia e fasi per un security assessment e ci ricorda le motivazioni per il quale ha senso condurre questo tipo di analisi:
Conferma se i sistemi sono stati opportunamente resi sicuri
Identifica eventuali requisiti di sicurezza dell’organizzazione non soddisfatti (*)
Soddisfa il requisito di eseguire una valutazione/misurazione periodica del sistema
Non sostituisce i controlli si di e la gestione della sicurezza dei sistemi
(*) Da notare che il framework parte da un assunto: che l’organizzazione abbia definito dei requisiti di sicurezza. Partiamo quindi da questo punto, abbiamo definito dei requisiti di sicurezza per ciò che stiamo implementando in cloud? Ci sono scelte e valutazioni che le organizzazione devono necessariamente eseguire in autonomia ma qualche spunto, se non sapete da dove partire, spesso viene dato proprio dai cloud provider.
Detection
Il secondo argomento parte da una domanda facile: come gestire il rilevamento dei security incident per un workload in cloud? Ovviamente rilevare l’icident è solo la scintilla di tutto ciò che riguarda poi la gestione dell’incident stesso, ma in questo momento restiamo solo sul tema della detection e, sempre per semplicità, restiamo ancora su NIST come riferimento.
NIST – Framework for Improving Critical Infrastructure Cybersecurity
Chiaramente la funzione di detection ha lo scopo di individuare eventuali eventi di interesse per la gestione della sicurezza dell’infrastruttura e dei dati da essa gestiti. Per gestire la detection dobbiamo quindi necessariamente accedere agli eventi che interessano i workload tenendo in considerazione il fatto che in molti casi non si parla più di Syslog e Windows Events. Le diverse piattaforme mettono infatti a disposizione in forme diverse gli eventi che interessano i vari servizi, di solito grazie a delle API che consentono di interrogare i sistemi oggetto di interesse.
Va anche considerato che strumenti che tipicamente vengono utilizzati dalle organizzazioni come SIEM e XDR devono disporre di opportune funzionalità per accedere a questo patrimonio di informazioni e devono anche sapere cosa farci con quei dati. Provo a chiarire il tema con un esempio: se il nostro SIEM deve analizzare i log provenienti da una istance o da un container probabilmente poco cambia rispetto a ciò che arrivava dalla virtual machine (sui container ci sarebbe di più da dire, eventualmente ne parlo in una live), ma se gli eventi sono prodotti dalla piattaforma che gestisce le nostre applicazioni in modalità serverless (es: procedure di integrazione, scripts di automazione) i nostri sistemi sono in grado di analizzare correttamente eventi di questo tipo?
Tecnologicamente è più che fattibile, è necessario tenere a mente che il passaggio di un workload in cloud richiede ancora che venga gestita la detection e che potremmo dover adeguare procedure e strumenti.
Best Practices
Nella maggior parte dei casi parliamo dei tre big player citati, ma in generale tutti i provider di servizi mettono a disposizione delle linee guida per affrontare diversi aspetti della sicurezza dei sistemi e dei dati all’interno dell’universo cloud.
In questa prima parte vorrei quindi dare un’occhiata a cosa suggeriscono a livello di best practices i tre provider di riferimento: AWS, Azure e GCP.
I titolo sono più che eloquenti. Il tema Identity e Access Management è evidentemente un argomento cruciale per una piattaforma cloud dove dovranno probabilmente accedere più utenti con credenziali di servizio per la gestione delle diverse componenti. E’ quindi opportuno proteggere opportunamente questo livello di accesso e profila correttamene gli utenti in modo da non dare privilegi elevati a chiunque.
AWS dedica inoltre uno spazio dedicato al tema della Detection dove cita una soluzione interna alla piattaforma – Security Hub – che consente di gestire alcune minacce (solitamente quelle più comuni) con delle azioni preimpostate (playbook); su questo elemento siamo già su un altro tema che in realtà ha un capitolo dedicato: le azioni di mitigation e remediation. Viene inoltre citata un’altra componente che dalla documentazione mi sembra più “core” per la funziona di detection che è GuardDuty.
Anche per Azure abbiamo a disposizione molta documentazione, devo dire tantissima ma anche molto sparsa. Ho trovato utile partire da un documento di sintesi con una top 10 di argomenti con i relativi rimandi alla documentazione dedicata: https://docs.microsoft.com/…/cloud-adoption-framework/secure/security-top-10.
Noto subito un certo allineamento di argomenti: anche Azure parte dal tema degli utenti suggerendo formazione specifica e ovviamente una corretta gestione delle profilazioni. Si fa quindi riferimento a role-base access control e identity and key management.
Su fronte della detection trovo un approccio interessante che titola “Integrate native threat detection”. In sintesi si parla di integrare le funzionalità di detection di Azure direttamente all’interno del proprio SIEM di riferimento. In questo caso si sta facendo riferimento, se comprendo bene, alle funzionalità di Microsoft Defender for Cloud, componente che vale quindi la pena di indagare meglio.
Anche per Google Cloud esiste una montagna di documentazione con una main page che raccoglie le best practice: https://cloud.google.com/security/best-practices. La struttura della documentazione di BigG è ovviamente differente rispetto ad Azure e AWS e anche in questo caso bisogna andare un po’ a caccia dei temi. Già nella main page li parla però di moltissimi aspetti tra cui il già citato tema dell’Access Management e un interessante documento che titola “Security best practice checklists”.
Sul tema Detection anche Google risponde con una propria soluzione: https://chronicle.security/. Di fatto un SIEM “cloud-native” (su questa denominazione potremmo discutere all’infinito) per le operazioni di detection and response.
Qualche conclusione non concludente
Come scrivevo l’obiettivo di questo primo post era far(mi/ci) un’idea come si stanno muovendo i big player sul fronte della gestione delle minacce in un contesto che varia rapidamente ed è sicuramente molto diverso da quello che le aziende tipicamente gestiscono internamente.
Partire dalla letteratura mi aiuta a organizzare le idee per andare poi a selezione gli argomenti da approfondire. Quindi per ora mi fermo qui e agli interessati lascio il link al mio canale Twitch dove questa sera – giovedì 14 aprile – alle 21:30 faccio una sessione di studio in cui leggiamo e chiacchieriamo a ruota libera su questo tema: https://www.twitch.tv/roccosicilia.