
Piattaforma Capture-the-Flag con IA locale e lezioni guidate su prompt injection, abuso di tool-call e OSINT contro sei personaggi chatbot simulati.
Un AI Capture-the-Flag locale con lezioni guidate per professionisti nuovi al prompt injection. I giocatori possono anche esplorare sei AI personas (una nascosta) che proteggono 20 flag tramite prompt-injection, abuso di tool-call, manipolazione della business-logic, fingerprinting della supply-chain, web recon e OSINT.
Il percorso guidato copre l'injection diretta, l'autorizzazione dei tool e l'injection attraverso un articolo di knowledge modificabile. Fornisce suggerimenti, tentativi salvati, evidenze dei tool, feedback di completamento e confronti tra tool protetti. I laboratori di pratica originali mantengono il punteggio manuale degli eventi. L'inferenza del modello avviene localmente tramite Ollama; dopo la build e il download del modello, la piattaforma principale non necessita di connessione internet.
Email Joe in Product Sales aggiunge una casella di posta simulata e un desktop in stile Windows. Scrivi un'email che l'assistente di Joe leggerà, poi osserva il riepilogo effettivo del modello e le azioni registrate. Tre obiettivi coprono un brief di vendita fuorviante, la divulgazione di un file interno fittizio e uno sconto non autorizzato. Non sono richiesti mail server, Windows, Wine o modelli aggiuntivi.
ai-ctf/
├── README.md ← sei qui
├── LICENSE ← MIT
├── platform/ ← tutto ciò che gira in Docker
│ ├── flags.toml ← configurazione centrale: modifica questo per personalizzare i valori delle flag
│ ├── docker-compose.yml ← tre servizi: web, ollama, decoy
│ ├── Dockerfile ← l'immagine dell'app web
│ ├── app/ ← sorgente FastAPI (config, personas, tools, chat)
│ ├── data/init.sql ← schema SQLite + dati seed di dipendenti fittizi
│ ├── decoy/ ← nginx minimale con due pagine flag
│ └── scripts/
│ ├── apply_flags.py ← inserisce i valori di flags.toml nei file statici
│ ├── render_secret.py ← eseguito all'avvio del container
│ └── dump_chats.py ← esporta il log della chat come HTML (strumento per il giorno dell'evento)
├── external_artifacts/ ← ciò che pubblichi su GitHub / Gist / DNS
│ ├── README.md ← checklist di setup
│ ├── anvil_chatkit/ ← il pacchetto fittizio della supply-chain
│ ├── gist_content.md ← incolla questo in un Gist pubblico
│ └── dns_records.txt ← record TXT da aggiungere al tuo dominio
└── docs/ ← documentazione per gestire l'evento
├── ANSWER_KEY.md ← soluzioni guidate + risposte originali delle 20 flag
├── CHEAT_SHEET.md ← soluzioni funzionanti + suggerimenti a livelli (solo GM)
├── OPERATIONS.md ← aggiornamenti, backup e troubleshooting
├── SETUP_RUNBOOK.md ← checklist della settimana, passo dopo passo
└── EVENT_DAY_NOTES.md ← script di briefing + troubleshooting
Usa la quick start qui sotto per il percorso guidato. La guida operativa copre aggiornamenti, backup, ripristino e controlli pre-evento. La answer key, il cheat sheet, il setup runbook e le note sull'evento descrivono il formato CTF originale opzionale.
apply_flags.py e
dump_chats.py — l'app stessa gira dentro Docker).exiftool (necessario solo se modifichi la flag EXIF e vuoi che
apply_flags.py riapplichi il timbro al logo).pip install e il pull del modello Ollama).
Dopo di che lo stack locale principale funziona offline. La catena OSINT esterna opzionale richiede accesso a internet.git clone https://github.com/mubix/ai-ctf.git
cd ai-ctf/platform
# 1. Session secret
echo "SESSION_SECRET=$(python3 -c 'import secrets; print(secrets.token_hex(32))')" > .env
# 2. (Optional) Customize flag values — see "Customizing the flags" below.
# Default values work fine for a smoke test.
# 3. Build and start
docker compose build
docker compose up -d ollama
docker compose exec ollama ollama pull qwen2.5:7b-instruct-q4_K_M
docker compose up -d
# 4. Open the platform
open http://localhost:18080/ # or your-machine-ip:18080 on another laptop
Registra un username; la piattaforma genera una password di 12 caratteri e la mostra una sola volta. Salvala per dopo. Vieni autenticato automaticamente e puoi selezionare Start learning. I giocatori di ritorno possono effettuare il login per riprendere i progressi salvati.
Il progetto Compose si chiama ai-ctf e ha la propria rete e il proprio volume del modello.
Solo la web UI pubblica una porta sull'host: 18080 per impostazione predefinita. Imposta CTF_WEB_PORT
in platform/.env per scegliere un'altra porta. Ollama e il decoy non hanno porte host pubblicate;
l'app si connette al proprio container Ollama. Non è configurato alcun passthrough GPU. CPU e memoria
sono comunque condivise con altri carichi di lavoro sull'host.
Se aggiorni uno stack creato con un nome di progetto Compose diverso, mantieni quel
nome con docker compose -p YOUR_EXISTING_PROJECT ... per riutilizzare i suoi container
e il volume del modello. Cambiare i nomi dei progetti crea uno stack separato.
La lezione guidata Customer Service usa un token di audit nuovo per ogni tentativo anziché il token fisso dell'evento. Riconosce le divulgazioni in testo semplice e distingue la visualizzazione dell'esempio svolto dalla risoluzione senza di esso. I tentativi nuovi preservano le conversazioni precedenti e i progressi ottenuti. Il suo profilo principiante si fida deliberatamente di un presunto ruolo di operatore di supporto; il bot Customer Service originale per la pratica resta separato. I tentativi guidati esistenti mantengono il loro profilo precedente finché il giocatore non ricomincia da zero.
Altre due lezioni guidate usano fixture fittizie isolate: accesso ai tool HR, poi un articolo di knowledge modificabile che può reindirizzare una risposta simulata. Eseguono richieste di azione del modello validate da schema contro quei tool fixture, registrano le chiamate ai tool e ne validano i risultati. I giocatori possono riprodurre gli stessi argomenti attraverso un controllo dei permessi e ispezionare un controllo di uso legittimo. Questo confronto verifica il confine del tool, non una seconda esecuzione del modello. Nulla viene inviato via email e nessun servizio HR reale è connesso. Le personas originali restano laboratori di pratica autogestiti con le loro risposte originali e il punteggio manuale.
Lo scenario email è disponibile da All lessons → Email Joe. Il suo File Explorer
usa percorsi familiari come C:\Users\Joe\Documents\Sales; questi identificano
fixture in memoria e non accedono mai al filesystem dell'host. Ogni email riceve file fittizi nuovi,
una outbox e un record di vendita. Gli eventi della storia sono etichettati separatamente dall'attività osservata del modello
e dei tool. Gli obiettivi di divulgazione di file e modifica di record richiedono azioni eseguite,
non una dichiarazione nel riepilogo. Abilita Enforce Joe's tool permissions per rieseguire uno dei due
obiettivi tool con i controlli dell'applicazione, poi invia un esempio pulito per verificare l'uso normale.
Tentativi, suggerimenti, uso dell'esempio svolto e progressi vengono salvati.
Per un'installazione esistente, le modifiche ad applicazione/template richiedono la ricostruzione dell'immagine web; il solo riavvio non copia il codice aggiornato:
cd platform
docker compose up -d --build web
Le tabelle delle lezioni vengono create all'avvio senza eliminare account esistenti o cronologia chat. Segui la guida operativa per eseguire il backup di un'installazione esistente prima dell'aggiornamento e verificare che i giocatori possano riprendere le loro lezioni in seguito.
La piattaforma contiene autonomamente 16 delle 20 flag. Le restanti 4 (#14–17) richiedono
infrastruttura esterna che devi pubblicare tu — vedi
external_artifacts/README.md. Salta questo passaggio se vuoi solo la metà
in piattaforma.
Tutti i 20 valori delle flag risiedono in un unico file: platform/flags.toml. Modifica i valori
lì per dare al tuo evento un sapore proprio (diversi token flag{adjective_noun},
codice coupon diverso, stipendio del CEO diverso, ecc.).
Dopo la modifica:
cd platform
python3 scripts/apply_flags.py # stamps values into static files
docker compose up -d --build web decoy # copies updated assets into the images
apply_flags.py aggiorna i file che non vengono caricati da Python a runtime:
data/init.sql (stipendio del CEO, flag #4)decoy/html/private/index.html e decoy/html/internal-tools/index.htmlapp/static/logo.jpg (flag #20 — richiede exiftool nel PATH)external_artifacts/ (README di chatkit, contenuto del gist, record DNS,
messaggio di commit di setup-history.sh)Dopo aver modificato qualsiasi valore delle flag, aggiorna anche docs/ANSWER_KEY.md in modo che il tuo
foglio di verifica corrisponda.
La ricostruzione non aggiorna le righe dei dipendenti già presenti nel database SQLite: il seed usa
INSERT OR IGNORE. Modificare lo stipendio del CEO in un evento esistente richiede comunque una migrazione
mirata delle fixture. Non eliminare il database dei giocatori per applicare quella modifica.
Se vuoi aggiungere o rimuovere flag del tutto (cambiare quali personas esistono, eliminare
la catena esterna, aggiungere un nuovo tool), modifica direttamente platform/app/personas/__init__.py
e platform/app/tools.py. Non c'è un DSL — le personas SONO il
gioco.
platform/app/personas/__init__.py) — meno
clausole di guardrail, meno righe "NEVER", meno esempi espliciti di rifiuto.
Il tasso di successo al primo tentativo dei giocatori aumenta.OLLAMA_MODEL in docker-compose.yml, esegui il pull di quel modello,
e lancia docker compose up -d web per applicare la configurazione. La sola dimensione del modello non
stabilisce la difficoltà. Ricontrolla attività normali, esempi svolti, tool call native
e risposte di azione strutturate usando i controlli pre-evento.file:// tramite l'LLM.Il catalogo originale degli attacchi e gli esempi storici di prompt sono in docs/CHEAT_SHEET.md.
docs/SETUP_RUNBOOK.md è la checklist della settimana (build → artefatti esterni →
dry run → giorno dell'evento). docs/EVENT_DAY_NOTES.md contiene lo script di briefing per i giocatori,
il catalogo dei suggerimenti a livelli e una tabella di troubleshooting.
Per la forensics del giorno dell'evento — "chi ha effettivamente risolto cosa?" — esegui
platform/scripts/dump_chats.py contro il DB SQLite montato come bind per produrre
un report HTML autonomo con chip di rilevamento flag per messaggio. Questi sono
match di sottostringhe, non prova che un assistente abbia divulgato un segreto o eseguito un tool. Le lezioni
guidate mantengono i propri record di completamento validati.
L'export predefinito ctf_log.html, i dati di runtime, i file di ambiente locali e gli archivi
di release sono ignorati da Git. Mantieni gli export con nomi personalizzati e i backup di deployment fuori
dal checkout o nella directory ignorata platform/data/. I record dei giocatori, le credenziali
e gli export delle chat dovrebbero restare privati.
MIT. Vedi LICENSE.
Creato da Rob Fuller (mubix) per la formazione pratica sulla sicurezza AI. Codice in gran parte generato dall'AI; decisioni di design e contenuti di proprietà di un umano.