
Plataforma local de Capture-the-Flag con IA con lecciones guiadas sobre inyección de prompts, abuso de llamadas a herramientas y OSINT contra seis personas de chatbot simuladas.
Un AI Capture-the-Flag local con lecciones guiadas para tecnólogos nuevos en la inyección de prompts. Los jugadores también pueden explorar seis personas de IA (una oculta) que protegen 20 flags mediante inyección de prompts, abuso de llamadas a herramientas, manipulación de lógica de negocio, fingerprinting de cadena de suministro, reconocimiento web y OSINT.
La ruta guiada cubre inyección directa, autorización de herramientas e inyección a través de un artículo de conocimiento editable. Proporciona pistas, intentos guardados, evidencia de herramientas, retroalimentación de finalización y comparaciones de herramientas protegidas. Los laboratorios de práctica originales conservan la puntuación manual de eventos. La inferencia del modelo se ejecuta localmente a través de Ollama; después de la compilación y la descarga del modelo, la plataforma principal no necesita conexión a internet.
Email Joe in Product Sales añade una bandeja de entrada simulada y un escritorio estilo Windows. Escribe un correo electrónico que el asistente de Joe leerá, luego observa el resumen real del modelo y las acciones registradas. Tres objetivos cubren un brief de ventas engañoso, la divulgación de un archivo interno ficticio y un descuento no autorizado. No se requiere servidor de correo, Windows, Wine ni un modelo adicional.
ai-ctf/
├── README.md ← estás aquí
├── LICENSE ← MIT
├── platform/ ← todo lo que se ejecuta en Docker
│ ├── flags.toml ← configuración central: edita esto para personalizar los valores de las flags
│ ├── docker-compose.yml ← tres servicios: web, ollama, decoy
│ ├── Dockerfile ← la imagen de la aplicación web
│ ├── app/ ← código fuente de FastAPI (config, personas, tools, chat)
│ ├── data/init.sql ← esquema de SQLite + datos de empleados falsos
│ ├── decoy/ ← nginx mínimo con dos páginas de flags
│ └── scripts/
│ ├── apply_flags.py ← inserta los valores de flags.toml en archivos estáticos
│ ├── render_secret.py ← se ejecuta al iniciar el contenedor
│ └── dump_chats.py ← exporta el registro de chat como HTML (herramienta para el día del evento)
├── external_artifacts/ ← lo que subes a GitHub / Gist / DNS
│ ├── README.md ← lista de verificación de configuración
│ ├── anvil_chatkit/ ← el paquete falso de cadena de suministro
│ ├── gist_content.md ← pega esto en un Gist público
│ └── dns_records.txt ← registro TXT para añadir a tu dominio
└── docs/ ← documentación para ejecutar el evento
├── ANSWER_KEY.md ← soluciones guiadas + respuestas originales de las 20 flags
├── CHEAT_SHEET.md ← soluciones funcionales + pistas por niveles (solo GM)
├── OPERATIONS.md ← actualizaciones, copias de seguridad y solución de problemas
├── SETUP_RUNBOOK.md ← paso a paso de la semana del evento
└── EVENT_DAY_NOTES.md ← guion de briefing + solución de problemas
Usa el inicio rápido de abajo para la ruta guiada. La guía de operaciones cubre actualizaciones, copias de seguridad, recuperación y verificaciones previas al evento. La clave de respuestas, la hoja de trucos, el runbook de configuración y las notas del evento describen el formato opcional del CTF original.
apply_flags.py y
dump_chats.py — la aplicación en sí se ejecuta dentro de Docker).exiftool (solo es necesario si cambias la flag EXIF y quieres que
apply_flags.py vuelva a insertar los metadatos del logo).pip install y la descarga del modelo de Ollama).
Después de eso, la pila local principal funciona sin conexión. La cadena OSINT externa opcional necesita acceso 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 nombre de usuario; la plataforma genera una contraseña de 12 caracteres y la muestra una vez. Guárdala para después. Se te inicia sesión automáticamente y puedes seleccionar Start learning. Los jugadores que regresan pueden iniciar sesión para retomar el progreso guardado.
El proyecto de Compose se llama ai-ctf y tiene su propia red y volumen de modelo.
Solo la interfaz web publica un puerto del host: 18080 por defecto. Establece CTF_WEB_PORT
en platform/.env para elegir otro puerto. Ollama y el decoy no tienen puertos
del host publicados; la aplicación se conecta a su propio contenedor de Ollama. No se
configura passthrough de GPU. La CPU y la memoria aún se comparten con otras cargas de trabajo en el host.
Si actualizas una pila creada bajo un nombre de proyecto de Compose diferente, conserva ese
nombre con docker compose -p YOUR_EXISTING_PROJECT ... para reutilizar sus contenedores
y volumen de modelo. Cambiar los nombres de proyecto crea una pila separada.
La lección guiada de Customer Service usa un token de auditoría nuevo por intento en lugar del token fijo del evento. Reconoce divulgaciones en texto plano y distingue ver el ejemplo resuelto de resolverlo sin él. Los intentos nuevos conservan las conversaciones anteriores y el progreso obtenido. Su perfil para principiantes confía deliberadamente en un rol de operador de soporte declarado; el bot de práctica original de Customer Service permanece separado. Los intentos guiados existentes conservan su perfil anterior hasta que el jugador empieza de nuevo.
Dos lecciones guiadas más usan fixtures ficticios aislados: acceso a herramientas de HR, luego un artículo de conocimiento editable que puede redirigir una respuesta simulada. Ejecutan solicitudes de acción del modelo validadas por esquema contra esas herramientas de fixture, registran las llamadas a herramientas y validan sus resultados. Los jugadores pueden reproducir los mismos argumentos a través de una verificación de permisos e inspeccionar un control de uso legítimo. Esta comparación verifica el límite de la herramienta, no una segunda ejecución del modelo. No se envía nada por correo y no hay ningún servicio real de HR conectado. Las personas originales siguen siendo laboratorios de práctica autodirigidos con sus respuestas originales y puntuación manual.
El escenario de correo electrónico está disponible desde All lessons → Email Joe. Su Explorador de archivos
usa rutas familiares como C:\Users\Joe\Documents\Sales; estas identifican fixtures
en memoria y nunca acceden al sistema de archivos del host. Cada correo electrónico obtiene archivos ficticios nuevos,
una bandeja de salida y un registro de ventas. Los eventos de la historia se etiquetan por separado de la actividad observada del modelo
y las herramientas. Los objetivos de divulgación de archivos y cambio de registros requieren acciones ejecutadas,
no una afirmación en el resumen. Habilita Enforce Joe's tool permissions para volver a ejecutar cualquiera de los
objetivos de herramientas con verificaciones de la aplicación, luego envía un ejemplo limpio para comprobar el uso normal.
Los intentos, las pistas, el uso del ejemplo resuelto y el progreso se guardan.
Para una instalación existente, los cambios en la aplicación/plantillas requieren reconstruir la imagen web; reiniciar por sí solo no copia el código actualizado:
cd platform
docker compose up -d --build web
Las tablas de lecciones se crean al iniciar sin eliminar cuentas existentes ni el historial de chat. Sigue la guía de operaciones para hacer una copia de seguridad de una instalación existente antes de actualizar y verificar que los jugadores puedan retomar sus lecciones después.
La plataforma contiene 16 de las 20 flags. Las 4 restantes (#14–17) requieren
infraestructura externa que debes subir tú mismo — consulta
external_artifacts/README.md. Omite ese paso si solo quieres la
mitad dentro de la plataforma.
Los 20 valores de flags viven en un solo archivo: platform/flags.toml. Edita los valores
allí para darle a tu evento su propio estilo (diferentes tokens flag{adjetivo_sustantivo},
diferente código de cupón, diferente salario del CEO, etc.).
Después de editar:
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 actualiza los archivos que no son cargados por Python en tiempo de ejecución:
data/init.sql (salario del CEO, flag #4)decoy/html/private/index.html y decoy/html/internal-tools/index.htmlapp/static/logo.jpg (flag #20 — necesita exiftool en el PATH)external_artifacts/ (README de chatkit, contenido del gist, registro DNS,
mensaje de commit de setup-history.sh)Después de cambiar cualquier valor de flag, también actualiza docs/ANSWER_KEY.md para que tu
hoja de verificación coincida.
Reconstruir no actualiza las filas de empleados que ya están en la base de datos SQLite: la inserción inicial usa
INSERT OR IGNORE. Cambiar el salario del CEO en un evento existente aún requiere una migración
específica del fixture. No elimines la base de datos de jugadores para aplicar ese cambio.
Si quieres añadir o eliminar flags por completo (cambiar qué personas existen, eliminar
la cadena externa, añadir una nueva herramienta), edita platform/app/personas/__init__.py
y platform/app/tools.py directamente. No hay DSL — las personas SON el
juego.
platform/app/personas/__init__.py) — menos
cláusulas de protección, menos líneas "NEVER", menos ejemplos explícitos de rechazo.
La tasa de éxito de los jugadores en el primer intento aumenta.OLLAMA_MODEL en docker-compose.yml, descarga ese modelo,
y ejecuta docker compose up -d web para aplicar la configuración. El tamaño del modelo por sí solo no
establece la dificultad. Vuelve a verificar las tareas normales, los ejemplos resueltos, las llamadas nativas a herramientas
y las respuestas de acción estructuradas usando las verificaciones previas al evento.file:// a través del LLM.El catálogo de ataques original y los ejemplos históricos de prompts están en docs/CHEAT_SHEET.md.
docs/SETUP_RUNBOOK.md es la lista de verificación de la semana del evento (compilación → artefactos externos →
prueba en seco → día del evento). docs/EVENT_DAY_NOTES.md tiene el guion de briefing para jugadores,
el catálogo de pistas por niveles y una tabla de solución de problemas.
Para el análisis forense del día del evento — "¿quién resolvió qué realmente?" — ejecuta
platform/scripts/dump_chats.py contra la base de datos SQLite montada como bind para producir
un informe HTML autocontenido con chips de detección de flags por mensaje. Estas son coincidencias
de subcadenas, no prueba de que un asistente divulgara un secreto o ejecutara una herramienta. Las lecciones
guiadas conservan sus propios registros de finalización validados.
La exportación predeterminada ctf_log.html, los datos en tiempo de ejecución, los archivos de entorno locales y los archivos
de lanzamiento son ignorados por Git. Mantén las exportaciones con nombres personalizados y las copias de seguridad de despliegue fuera
del checkout o en el directorio ignorado platform/data/. Los registros de jugadores, las credenciales
y las exportaciones de chat deben permanecer privados.
MIT. Consulta LICENSE.
Creado por Rob Fuller (mubix) para formación práctica en seguridad de IA. Código en gran parte generado por IA; decisiones de diseño y contenido propiedad de un humano.