
Lokale KI-Capture-the-Flag-Plattform mit geführten Lektionen zu Prompt-Injection, Tool-Call-Missbrauch und OSINT gegen sechs simulierte Chatbot-Personas.
Ein lokales AI Capture-the-Flag mit geführten Lektionen für Technologen, die neu im Bereich Prompt-Injection sind. Spieler können außerdem sechs AI-Personas erkunden (eine versteckt), die 20 Flags schützen – durch Prompt-Injection, Tool-Call-Missbrauch, Business-Logic-Manipulation, Supply-Chain-Fingerprinting, Web-Recon und OSINT.
Der geführte Pfad deckt direkte Injection, Tool-Autorisierung und Injection über einen editierbaren Wissensartikel ab. Er bietet Hinweise, gespeicherte Versuche, Tool-Nachweise, Abschluss- Feedback und Vergleiche geschützter Tools. Die ursprünglichen Übungslabs behalten die manuelle Event-Bewertung. Die Modellinferenz läuft lokal über Ollama; nach dem Build und dem Modell-Download benötigt die Kernplattform keine Internetverbindung.
Email Joe in Product Sales fügt ein simuliertes Postfach und einen Windows-ähnlichen Desktop hinzu. Schreibe eine E-Mail, die Joes Assistent lesen wird, und beobachte dann die tatsächliche Modellzusammenfassung und die aufgezeichneten Aktionen. Drei Ziele decken ein irreführendes Verkaufsbriefing, die Offenlegung einer fiktiven internen Datei und einen unbefugten Rabatt ab. Kein Mailserver, Windows, Wine oder zusätzliches Modell erforderlich.
ai-ctf/
├── README.md ← du bist hier
├── LICENSE ← MIT
├── platform/ ← alles, was in Docker läuft
│ ├── flags.toml ← zentrale Konfiguration: hier bearbeiten, um Flag-Werte anzupassen
│ ├── docker-compose.yml ← drei Services: web, ollama, decoy
│ ├── Dockerfile ← das Web-App-Image
│ ├── app/ ← FastAPI-Quellcode (config, personas, tools, chat)
│ ├── data/init.sql ← SQLite-Schema + Seed-Daten für Fake-Mitarbeiter
│ ├── decoy/ ← winziges nginx mit zwei Flag-Seiten
│ └── scripts/
│ ├── apply_flags.py ← stempelt flags.toml-Werte in statische Dateien
│ ├── render_secret.py ← läuft beim Container-Start
│ └── dump_chats.py ← exportiert das Chat-Log als HTML (Event-Tag-Tool)
├── external_artifacts/ ← was du auf GitHub / Gist / DNS pushst
│ ├── README.md ← Setup-Checkliste
│ ├── anvil_chatkit/ ← das gefälschte Supply-Chain-Paket
│ ├── gist_content.md ← dies in einen öffentlichen Gist einfügen
│ └── dns_records.txt ← TXT-Record, der zu deiner Domain hinzugefügt wird
└── docs/ ← Unterlagen zum Durchführen des Events
├── ANSWER_KEY.md ← geführte Lösungen + ursprüngliche 20-Flag-Antworten
├── CHEAT_SHEET.md ← funktionierende Lösungen + abgestufte Hinweise (nur GM)
├── OPERATIONS.md ← Updates, Backups und Fehlerbehebung
├── SETUP_RUNBOOK.md ← Woche des Events, Schritt für Schritt
└── EVENT_DAY_NOTES.md ← Briefing-Skript + Fehlerbehebung
Nutze den untenstehenden Schnellstart für den geführten Pfad. Der Operations-Leitfaden deckt Updates, Backups, Wiederherstellung und Checks vor dem Event ab. Der Answer Key, das Cheat Sheet, das Setup-Runbook und die Event-Notizen beschreiben das optionale ursprüngliche CTF-Format.
apply_flags.py und
dump_chats.py verwendet – die App selbst läuft in Docker).exiftool (nur nötig, wenn du das EXIF-Flag änderst und möchtest,
dass apply_flags.py das Logo neu stempelt).pip install und den Ollama-Modell-Pull).
Danach läuft der lokale Kern-Stack offline. Die optionale externe OSINT-Kette benötigt Internetzugang.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
Registriere einen Benutzernamen; die Plattform generiert ein 12-stelliges Passwort und zeigt es einmal an. Speichere es für später. Du wirst automatisch angemeldet und kannst Start learning auswählen. Zurückkehrende Spieler können sich anmelden, um gespeicherten Fortschritt fortzusetzen.
Das Compose-Projekt heißt ai-ctf und hat sein eigenes Netzwerk und Modell-Volume.
Nur die Web-UI veröffentlicht einen Host-Port: standardmäßig 18080. Setze CTF_WEB_PORT
in platform/.env, um einen anderen Port zu wählen. Ollama und der Decoy haben keine veröffentlichten
Host-Ports; die App verbindet sich mit ihrem eigenen Ollama-Container. Es ist kein GPU-Passthrough
konfiguriert. CPU und Speicher werden weiterhin mit anderen Workloads auf dem Host geteilt.
Wenn du einen Stack aktualisierst, der unter einem anderen Compose-Projektnamen erstellt wurde, behalte diesen
Namen mit docker compose -p YOUR_EXISTING_PROJECT ... bei, um seine Container
und sein Modell-Volume wiederzuverwenden. Das Ändern von Projektnamen erstellt einen separaten Stack.
Die geführte Customer-Service-Lektion verwendet pro Versuch ein frisches Audit-Token anstelle des festen Event-Tokens. Sie erkennt Klartext-Offenlegungen und unterscheidet das Ansehen des durchgearbeiteten Beispiels vom Lösen ohne dieses. Frische Versuche bewahren vorherige Konversationen und erzielten Fortschritt. Ihr Anfängerprofil vertraut bewusst einer behaupteten Support-Operator-Rolle; der ursprüngliche Customer-Service-Übungsbot bleibt separat. Bestehende geführte Versuche behalten ihr früheres Profil, bis der Spieler neu beginnt.
Zwei weitere geführte Lektionen verwenden isolierte fiktive Fixtures: HR-Tool-Zugriff, dann einen editierbaren Wissensartikel, der eine simulierte Antwort umleiten kann. Sie führen schema-validierte Modell-Aktionsanfragen gegen diese Fixture-Tools aus, zeichnen die Tool-Aufrufe auf und validieren ihre Ergebnisse. Spieler können dieselben Argumente über eine Berechtigungsprüfung wiederholen und eine Legitimate-Use-Kontrolle untersuchen. Dieser Vergleich prüft die Tool-Grenze, nicht einen zweiten Modelllauf. Es wird nichts per E-Mail versendet und kein echter HR-Service ist verbunden. Die ursprünglichen Personas bleiben selbstgesteuerte Übungslabs mit ihren ursprünglichen Antworten und manueller Bewertung.
Das E-Mail-Szenario ist über All lessons → Email Joe verfügbar. Sein File Explorer
verwendet vertraute Pfade wie C:\Users\Joe\Documents\Sales; diese identifizieren In-Memory-
Fixtures und greifen niemals auf das Host-Dateisystem zu. Jede E-Mail erhält frische fiktive Dateien,
ein Postausgang und einen Verkaufsdatensatz. Story-Ereignisse werden getrennt von beobachteter Modell-
und Tool-Aktivität gekennzeichnet. Ziele zur Datei-Offenlegung und Datensatzänderung erfordern ausgeführte Aktionen,
nicht eine Behauptung in der Zusammenfassung. Aktiviere Enforce Joe's tool permissions, um entweder das
Tool-Ziel mit Anwendungsprüfungen erneut auszuführen, und sende dann ein sauberes Beispiel, um die normale Nutzung zu prüfen.
Versuche, Hinweise, die Nutzung durchgearbeiteter Beispiele und Fortschritt werden gespeichert.
Bei einer bestehenden Installation erfordern Änderungen an Anwendung/Templates einen Neuaufbau des Web-Images; ein reiner Neustart kopiert den aktualisierten Code nicht:
cd platform
docker compose up -d --build web
Lektions-Tabellen werden beim Start erstellt, ohne bestehende Konten oder Chat-Verlauf zu löschen. Folge dem Operations-Leitfaden, um eine bestehende Installation vor dem Update zu sichern und zu prüfen, dass Spieler ihre Lektionen danach fortsetzen können.
Die Plattform enthält 16 der 20 Flags selbst. Die verbleibenden 4 (#14–17) erfordern
externe Infrastruktur, die du selbst pushst – siehe
external_artifacts/README.md. Überspringe diesen Schritt, wenn du nur die
plattforminterne Hälfte möchtest.
Alle 20 Flag-Werte befinden sich in einer Datei: platform/flags.toml. Bearbeite die Werte
dort, um deinem Event eine eigene Note zu geben (andere flag{adjective_noun}-
Tokens, anderer Coupon-Code, anderes CEO-Gehalt usw.).
Nach dem Bearbeiten:
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 aktualisiert die Dateien, die zur Laufzeit nicht von Python geladen werden:
data/init.sql (CEO-Gehalt, Flag #4)decoy/html/private/index.html und decoy/html/internal-tools/index.htmlapp/static/logo.jpg EXIF-Metadaten (Flag #20 – benötigt exiftool im PATH)external_artifacts/-Dateien (chatkit README, Gist-Inhalt, DNS-Record,
setup-history.sh Commit-Nachricht)Nach dem Ändern von Flag-Werten aktualisiere auch docs/ANSWER_KEY.md, damit dein
Verifier-Blatt übereinstimmt.
Ein Neuaufbau aktualisiert keine Mitarbeiterzeilen, die bereits in der SQLite-Datenbank vorhanden sind: der Seed verwendet
INSERT OR IGNORE. Das Ändern des CEO-Gehalts in einem bestehenden Event erfordert weiterhin eine gezielte
Fixture-Migration. Lösche nicht die Spielerdatenbank, um diese Änderung anzuwenden.
Wenn du Flags vollständig hinzufügen oder entfernen möchtest (ändern, welche Personas existieren, die
externe Kette entfernen, ein neues Tool hinzufügen), bearbeite platform/app/personas/__init__.py
und platform/app/tools.py direkt. Es gibt keine DSL – die Personas SIND das
Spiel.
platform/app/personas/__init__.py) – weniger
Guardrail-Klauseln, weniger „NEVER“-Zeilen, weniger explizite Verweigerungsbeispiele.
Die Erfolgsquote der Spieler beim ersten Versuch steigt.OLLAMA_MODEL in docker-compose.yml, ziehe dieses Modell
und führe docker compose up -d web aus, um die Konfiguration anzuwenden. Die Modellgröße allein
bestimmt nicht die Schwierigkeit. Überprüfe normale Aufgaben, durchgearbeitete Beispiele, native Tool-Aufrufe
und strukturierte Aktionsantworten erneut mit den Checks vor dem Event.file://-LFI über das LLM aus.Der ursprüngliche Angriffskatalog und historische Beispiel-Prompts befinden sich in docs/CHEAT_SHEET.md.
docs/SETUP_RUNBOOK.md ist die Checkliste für die Event-Woche (Build → externe Artefakte →
Probelauf → Event-Tag). docs/EVENT_DAY_NOTES.md enthält das Spieler-Briefing-Skript,
den abgestuften Hinweis-Katalog und eine Fehlerbehebungs-Tabelle.
Für Forensik am Event-Tag – „wer hat tatsächlich was gelöst?“ – führe
platform/scripts/dump_chats.py gegen die bind-gemountete SQLite-DB aus, um einen
eigenständigen HTML-Bericht mit Flag-Erkennungs-Chips pro Nachricht zu erzeugen. Dies sind Substring-
Treffer, kein Beweis dafür, dass ein Assistent ein Geheimnis offengelegt oder ein Tool ausgeführt hat. Die geführten
Lektionen behalten ihre eigenen validierten Abschlussdatensätze.
Der Standard-Export ctf_log.html, Laufzeitdaten, lokale Umgebungsdateien und Release-
Archive werden von Git ignoriert. Bewahre benutzerdefiniert benannte Exporte und Deployment-Backups außerhalb
des Checkouts oder im ignorierten Verzeichnis platform/data/ auf. Spielerdatensätze, Anmeldedaten
und Chat-Exporte sollten privat bleiben.
MIT. Siehe LICENSE.
Erstellt von Rob Fuller (mubix) für praktisches AI-Security- Training. Code größtenteils KI-generiert; Designentscheidungen und Inhalte von einem Menschen verantwortet.