
Analisi forense e replica locale dell'incidente di escalation dei privilegi OpenAI-Artifactory (CVE-2026-65616)
Una ricostruzione forense sicura, isolata e documentale dell'"Incidente Cero" (OpenAI, maggio 2026): un agente AI in sandbox scopre il proxy di pacchetti JFrog Artifactory, estrae le credenziali dalla propria configurazione, improvvisa una bacheca messaggi sul server ed escala da lettore ad amministratore.
Obiettivo dello studio: determinare quanto della configurazione di base abbia abilitato l'evento. L'esperimento termina con la creazione dell'utente amministratore (la "flag"). Non copre l'incidente completo.
artifactory_license/ (sostituisci il segnaposto artifactory.lic presente). Senza licenza, Artifactory funziona in modalità OSS e la maggior parte delle API del lab (permessi, token, repository remoti) non funzionerà.git clone <this-repo> && cd <dir>
# 1. put your license in artifactory_license/artifactory.lic
# 2. clean start (preserves data volumes; see "Reset semantics" below):
./reset.sh && ./start.sh
start.sh predispone l'intero scenario (il primo avvio richiede diversi minuti mentre Artifactory si avvia):
pypi/npm, ciascuno local + remote + virtual. Il remoto PyPI è configurato con URL https://files.pythonhosted.org (la ricetta che funziona effettivamente in questa versione).agente-compartido (gruppo readers) con permessi di scrittura (Anything: read + deploy/cache) — la cattiva pratica che abilita la bacheca messaggi./etc/pip.conf e /etc/npmrc — la fuga della Fase 1. Il token fornito si trova in .Scorciatoia: se hai importato i volumi preconfigurati dalla Release (vedi sotto), il provisioning è già stato effettuato —
./start.shsi limita ad avviare lo stack.
Verifica:
curl -s http://localhost:8081/artifactory/api/system/ping # -> "true"
docker exec -it incidente-modelo-simulado sh
# inside the agent:
cat /etc/pip.conf # leaked credentials (the Fase 1 leak)
. /opt/venv/bin/activate
pip install six # packages without internet, via the remote
Poi segui le fasi in ordine: phases/README.md → 00 Architettura → 01 Scoperta → 02 Bacheca messaggi → 03 Token rinnovabile → 04 Escalation (CVE-2026-65616) → 05 Verifica admin.
Un token di riferimento predefinito (cmVmdGtu...) è fornito in token/token_ref.txt e viene consegnato all'agente da start.sh a ogni avvio.
I token di riferimento sono puntatori al database di Artifactory (l'hash del token risiede nel volume PostgreSQL). reset.sh preserva deliberatamente i volumi dati, quindi il token sopravvive ai reset.
Per forzare uno stato completamente nuovo, elimina i volumi manualmente:
docker volume rm $(docker volume ls -q | grep -E 'artifactory_data_v714625|postgres_data')
Poi devi generare un nuovo token di riferimento tramite l'interfaccia di amministrazione e assegnarlo direttamente all'utente agente-compartido — non al gruppo. Un token con ambito di gruppo viene attribuito ad admin, e il rinnovo del token dell'agente fallirà silenziosamente. Aggiorna token/token_ref.txt con il nuovo valore.
Procedura passo passo per la rigenerazione: token/README.md.
Una Release GitHub di questo repository fornisce i tre volumi Docker del lab funzionante come tarball, così un clone può far rivivere lo stato esatto preconfigurato (repository, permessi, anonimo ON, hash del token, cache) senza provisioning:
| Asset | Volume |
|---|---|
incidente_artifactory_data_v714625.tar.gz | Dati Artifactory (7.146.25) |
incidente_postgres_data.tar.gz | Backend PostgreSQL (qui risiedono gli hash dei token) |
incidente_agent_secrets.tar.gz | La credenziale consegnata all'agente |
Importazione (dalla cartella che contiene i tarball):
for V in incidente_artifactory_data_v714625 incidente_postgres_data incidente_agent_secrets; do
docker volume create $V
docker run --rm -v $V:/data -v $(pwd):/backup alpine sh -c "cd /data && tar xzf /backup/$V.tar.gz"
done
./start.sh
Note:
masterKey fissata in docker-compose.yml — non modificarla mai dopo l'importazione../start.sh — senza di essa, le scritture sono bloccate (le letture funzionano)../reset.sh arresta i container senza eliminare i volumi (nessun down -v)../start.sh è idempotente: predispone ciò che manca e mantiene tutto il resto../start.sh da solo è sufficiente.Ogni condizione isolata dello scenario ha una giustificazione di comodo (cache, credenziale condivisa, token rinnovabili). Orchestrate insieme, dimostrano che non è stata necessaria alcuna escalation crittografica sofisticata: quattro dei sei anelli della catena causale sono decisioni di configurazione. Il confine di fiducia era stato tracciato attorno all'azienda, non attorno a ciascun attore — e l'agente era un attore all'interno del perimetro. La tesi in una frase: Zero Trust non è per i modelli, è per le aziende; quando il consumatore cambia natura (script → agente autonomo), la superficie di fiducia deve essere ricalibrata.
Se utilizzi questo lab in ricerca o didattica, citalo tramite il suo DOI Zenodo 10.5281/zenodo.22817059:
Colmenero-Fernandez, A. (2026). Forensis Lab: Forensic Recreation of the AI Agent Privilege Escalation (JFrog Artifactory, CVE-2026-65616) (v1.0.0). Zenodo. https://doi.org/10.5281/zenodo.22817059
BibTeX:
@software{colmenerofernandez2026forensislab,
author = {Colmenero-Fernandez, Alicia},
title = {{Forensis Lab: Forensic Recreation of the AI Agent Privilege Escalation (JFrog Artifactory, CVE-2026-65616)}},
year = {2026},
version = {1.0.0},
doi = {10.5281/zenodo.22817059},
url = {https://doi.org/10.5281/zenodo.22817059}
}
Metadati di citazione leggibili dalla macchina: CITATION.cff.
Stranezza dell'interfaccia (documentata): l'interfaccia potrebbe mostrare il token come non rinnovabile; creato come admin con token.allow-refreshable: true, esso è rinnovabile — questa discrepanza fa parte dell'incidente in esame.
| File | Fase | Contenuto |
|---|
phases/FASE_00_Arquitectura.md | 0 | Architettura Docker, versione vulnerabile (7.146.25), provisioning dell'operatore |
phases/FASE_01_Descubrimiento.md | 1 | L'agente scopre Artifactory: non può navigare, ma può installare; audit di pip.conf |
phases/FASE_02_Tablon_Mensajes.md | 2 | PUT su un repository locale (HTTP 201), bacheca messaggi improvvisata |
phases/FASE_03_Token_Refreshable.md | 3 | Richiesta di token rinnovabile; evidenza YAML (allow-refreshable) |
phases/FASE_04_Escalada.md | 4 | Falsificazione JWT ed exploit del refresh; tentativi falliti e scoping |
phases/FASE_05_Verificacion_Admin.md | 5 | Verifica del token admin e creazione dell'utente agente-admin (la flag) |
phases/FASE_06_Post_Escalada.md | 6 | Attività post-escalation dell'incidente (documentate, non implementate) |