Quando l'attaccante è un agente AI: Marimo CVE-2026-39987 e la catena di pivot in 60 minuti
Il 10 maggio 2026 Sysdig ha registrato il primo post-exploitation guidato da un agente LLM osservato in natura: da Marimo CVE-2026-39987 all'esfiltrazione di PostgreSQL in meno di un'ora, distribuita su 11 IP di egress.
Il 10 maggio 2026 il Sysdig Threat Research Team ha osservato un'intrusione che descrive come "guidata da un agente AI" per l'intera fase di post-exploitation. L'attaccante ha compromesso un notebook Marimo esposto su Internet sfruttando CVE-2026-39987, ha estratto due credenziali cloud dall'host, le ha replicate attraverso un pool di egress su 11 IP Cloudflare Workers, ha recuperato una chiave SSH privata da AWS Secrets Manager, ha aperto otto brevi sessioni SSH verso un bastion interno e ha esfiltrato schema e tabella credenziali di un database PostgreSQL interno. Tempo totale dall'handshake WebSocket al dump del database: meno di un'ora. Il lavoro tra un pivot e l'altro non è stato fatto da un umano e non è stato fatto da uno script precompilato — la ricostruzione comportamentale di Sysdig mostra che i comandi sono stati generati e concatenati da un agente LLM che leggeva l'output dei tool e decideva lo step successivo in tempo reale.
Non è un paper di ricerca e non è una demo di prompt injection. È una breach di produzione con un agente AI lato attaccante nel loop operativo. Chi calibra ancora i propri controlli su "cosa farebbe un red teamer umano in una giornata" deve ricalibrare.
Cos'è davvero CVE-2026-39987
Marimo è un notebook Python reattivo molto adottato dai team data e ML. CVE-2026-39987 è una RCE pre-autenticata sull'endpoint /terminal/ws: a differenza degli altri WebSocket del progetto, questo non chiamava validate_auth(), verificava solo run mode e supporto piattaforma, poi consegnava una PTY completa. CVSS 4.0 9.3 (CVSS 3.1 9.8), CWE-306 — autenticazione mancante per una funzione critica. Fix in 0.23.0; tutto ≤0.20.4 è vulnerabile. NVD ha pubblicato il 9 aprile 2026 e CISA l'ha aggiunto al KEV il 23 aprile 2026 con scadenza federale 7 maggio — un orologio di 14 giorni ormai scaduto.
Il vettore di ingresso è la parte noiosa. Un'istanza raggiungibile, un WebSocket non autenticato, una shell. Quello che conta è cosa è successo dopo.
I quattro pivot, in tempo attaccante
Ricostruzione dalla timeline di Sysdig:
| Fase | Orario (UTC) | Cosa è successo |
|---|---|---|
| Accesso iniziale | 18:23:44 | WebSocket verso Marimo vulnerabile da 157.66.54.26 (AS141892, ID) |
| Furto credenziali | 18:24:14 | Credenziali AWS estratte dai file di environment |
| Pivot AWS | 19:26:31 | Prima chiamata API AWS con la access key rubata (48 min dopo) |
| Secrets Manager | 19:26:52 | Chiave SSH privata recuperata via 12 richieste GetSecretValue ridondanti in 22 secondi |
| Bastion + esfiltrazione | 19:30:30 – 19:32:23 | 8 sessioni SSH in parallelo da 6 IP Cloudflare Workers distinti, schema + credenziali in 113 secondi |
Due dettagli da fissare. Il gap tra "credenziali in mano" e "prima chiamata AWS" è di 48 minuti — verosimilmente l'agente che ragiona sull'environment, sceglie target, decide come distribuire le richieste. L'esfiltrazione lato bastion è durata 113 secondi su otto sessioni parallele: l'estrazione effettiva del database è finita prima che qualsiasi regola SIEM ragionevole avesse aggregato e triaggato l'alert iniziale sul WebSocket.
La firma di un agente sul filo
La ragione per cui questa storia conta più di un ennesimo "RCE seguito da furto dati" è la firma comportamentale che Sysdig ha catturato. Quattro impronte strutturali distinguono questa esecuzione da uno script precompilato:
- Targeting improvvisato. Il dump PostgreSQL viene fatto su una tabella che l'attaccante non poteva conoscere in anticipo. Nessuna fase di staging, nessuna separazione tra recon ed esecuzione — l'agente scopre, ragiona e dumpa in una sequenza continua guidata dall'output dei tool.
- Artefatti di pianificazione nel command stream. Su sei IP distinti, in burst di frazione di secondo, compare un commento in cinese ("vediamo cos'altro possiamo fare") incastrato nel flusso di comandi. Un umano che esegue un playbook non si narra da solo attraverso sei sessioni SSH parallele. Un LLM che cuce comandi in real time sì.
- Sintassi ottimizzata per macchine. Separatori
echo '---'tra le probe,2>&1 | head -Nper output limitati,-P pager=offsu psql,2>/dev/nullovunque, HEREDOC con quoted-EOF che incapsulano sei statement SQL alla volta. È la forma dei comandi prodotti da qualcosa che deve rileggere il proprio output strutturato, non la forma dei comandi che un umano scrive in una shell. - Chaining guidato dall'output. Ogni comando successivo consuma un valore raccolto dallo stdout del precedente — non da una config di playbook hard-coded. È esattamente il loop di un agente: tool call → osserva → decide → tool call successivo.
Il fan-out su 11 IP Cloudflare Workers è l'altro indizio. Un operatore con script che vuole diversità di egress avrebbe configurato un pool fisso. Un agente che ragiona su rate limiting e correlazione di source-IP distribuisce istintivamente le richieste sui PoP disponibili, nel pattern che minimizza il segnale per-IP. Sysdig ha visto 8 sessioni SSH su 6 IP e 12 chiamate Secrets Manager sul resto, tutte coordinate in pochi secondi.
Cosa sta davvero cambiando
La versione onesta del discorso sui costi è nel framing di Sysdig. Un operatore con script ammortizza tempo di engineering su molti target — lo stesso playbook viene rigiocato con qualche tweak. Un operatore agent-driven ammortizza budget di inferenza, che costa meno ed è molto più flessibile. Aggiungere un nuovo tipo di target non richiede più scrivere un nuovo playbook; richiede solo lasciare che l'agente legga il nuovo environment e decida cosa fare.
Un red teamer umano impiega 6-12 ore per concatenare un furto di credenziali attraverso AWS Secrets Manager fino a un bastion SSH e poi a un dump PostgreSQL. L'agente di Marimo l'ha fatto in 60 minuti, senza preparazione per-target, senza un playbook fisso da fingerprintare, e con un pattern di egress che batte il rate limiting su singolo IP.
Due conseguenze:
- L'attaccante adesso può colpire qualsiasi cosa raggiungibile su Internet, non solo ciò per cui ha scritto tooling. Il software long-tail (Marimo, Langflow, ComfyUI, ogni nuovo strumento ML/data con UI web) diventa economicamente attraente da un giorno all'altro.
- Le finestre di rilevamento "minuti-ore" diventano "minuti-secondi". La catena end-to-end è durata meno di un'ora. Qualsiasi controllo che richieda un triage umano in quella finestra non ha fatto in tempo.
Perché lo stack tradizionale non lo prende
Andando per ordine:
- EDR/XDR sull'host. Il processo notebook fa fork di una shell. EDR vede process spawn e chiamate curl. Nessuna è malevola di per sé; la malvagità è nella sequenza. Le regole EDR non ragionano sulla finestra di 60 minuti né sui 11 IP di egress.
- Log di audit cloud. CloudTrail ha catturato tutte e 12 le chiamate
GetSecretValue. La domanda è se qualcuno le ha aggregate e correlate in 22 secondi. In un SOC tipico, "l'abbiamo trovato in CloudTrail" è quello che si dice in post-mortem, non quello che fa scattare la page. - Cadenza di patching. CISA ha aggiunto CVE-2026-39987 al KEV il 23 aprile con deadline federale 7 maggio. La vittima è stata compromessa il 10 maggio — tre giorni oltre la deadline. KEV è un pavimento, non un soffitto, e il pavimento non è stato raggiunto. È il gap del 21,3% sui CVE noti che ENISA ha segnalato nel Threat Landscape 2025, reso concreto.
- Pentest annuale o trimestrale. Il prossimo pentest in calendario avrebbe segnalato Marimo come superficie esposta solo se eseguito dopo il 9 aprile. Se fatto a marzo, non avrebbe trovato nulla — il CVE non esisteva. È il problema base della validazione point-in-time che ogni framework regolatorio (NIS2, DORA) sta spingendo a risolvere imponendo evidenza continua.
Cosa funziona davvero
Due livelli, accoppiati:
Validazione offensiva continua e AI-driven. Il difensore ha bisogno di un motore offensivo che si adatti ai nuovi CVE nella finestra tra disclosure ed exploitation, che ragioni sul tuo environment come ci ragiona l'agente dell'attaccante, e che riparta a ogni cambiamento del perimetro. I pentest trimestrali non possono modellare un attaccante che non ha bisogno di preparazione per-target; serve un difensore che a sua volta non ha bisogno di preparazione per-target.
Analisi del traffico comportamentale a velocità di linea. Il writeup di Sysdig è in pratica un esempio funzionante di cosa avrebbe dovuto firare durante l'attacco, non dopo. I segnali erano sul filo — un WebSocket anomalo da un ASN mai visto, un egress fan-out sostenuto su 11 IP in pochi secondi, un polling Secrets Manager a ritmo macchina, sessioni SSH in parallelo verso un bastion che storicamente ne ha una o due. Ognuno di questi è rilevabile comportamentalmente prima che si completi. Nessuno richiede conoscere il CVE in anticipo.
Dove si colloca Zero Hunt
Due dei tre pilastri di Zero Hunt parlano direttamente all'intrusione su Marimo.
Pilastro 2 — AI Traffic Analysis è quello portante per questo scenario. L'appliance esegue un modello deep-learning proprietario con quattro head di inferenza paralleli (traffico sospetto, classificazione malware, identificazione tipo di attacco, fingerprinting applicativo) addestrato su miliardi di sequenze PCAP, a 2,7+ Gbit/s su GPU locale. Il fan-out su 11 IP di egress, il burst di polling Secrets Manager in 22 secondi, le otto sessioni SSH simultanee verso un bastion che normalmente ne vede una sola — sono esattamente le anomalie di correlazione temporale su cui il modello di traffic è costruito per firare. Niente round-trip in cloud, niente digest SIEM del giorno dopo. Rilevamento nei 113 secondi di esfiltrazione, non nella review dell'incidente del mattino successivo.
Pilastro 1 — AI Generative Pentest risponde all'altra metà della domanda. Lo swarm a 10 agenti (Recon, Exploit, Web, Credential, Post-Exploit, Pivot, Tactic, Report e il Controller AI) genera catene di exploit per-target via LLM locale — non pescate da ExploitDB, non un playbook fisso. Backtestate nell'AI Gym (142+ skill auto-evolutivi, validati contro Vulhub e NYU CTF Bench) prima che qualunque nuova tecnica tocchi un environment di produzione. Il punto è simmetrico: se un attaccante può ragionare sul tuo environment con un agente LLM e pivottare in 60 minuti, la tua pipeline di validazione deve poter fare lo stesso — in continuo, firmata a ogni step, contro il tuo perimetro reale.
Il caso Marimo non è un episodio isolato. È il primo che Sysdig è riuscito a catturare con abbastanza dettaglio da pubblicarlo. Il prossimo arriverà contro una UI web long-tail diversa, con un CVE diverso, contro uno stack diverso, e l'unica cosa che resterà uguale sarà l'agente.