← → 翻页 · B 静态 · ESC 索引
SOFISTIC × AGENTCON PANAMÁ · 2026
01 / 20
Attack Detected.
Claude Responds.
Autonomous Blue Team Agents · Wazuh + Claude
Julio Espinosa · Sofistic · 30 min
Attack Detected. Claude Responds.
01 / 20
02 / 20 · SOBRE MÍ
FRAMING
QUIÉN HABLA
Julio Espinosa
Julio Espinosa
SOC Team Leader · Sofistic Cybersecurity
6 años en ciberseguridad. Empecé como Cyber Security Analyst en 2020. Hoy lidero un SOC con 25 analistas entre Panamá y Colombia, cubriendo 50+ clientes y 30,000+ alertas/mes en cobertura 24/7.
Off-duty: videojuegos, deportes de alto riesgo, CTFs.
25
Analistas SOC
50+
Clientes enterprise
30K/mes
Alertas gestionadas
10+
DFIR enterprise
CERTS DESTACADAS · TOP 10 DE +50
CrowdStrikeCCSE
CrowdStrikeCCFH
CrowdStrikeCCFA
AWSAI Practitioner
GoogleCloud Digital Leader
CompTIAPenTest+ · CySA+
HTBCDSA · CJCA
EC-CouncilCEH Master · SOC
INEWAPT · eCPPT
MastermindISO 27001 LA
SPECIAL THANKS · Juan José Chavarría — sparring técnico, sin él no hay esta charla.
@ AGENTCON PANAMÁ · 2026
Sobre mí
02 / 20
03 / 20 · EL PROBLEMA
FRAMING
PULL-QUOTE
La mayoría de herramientas de seguridad detectan amenazas.
Esta las piensa.
El problema
03 / 20
04 / 20 · AGENDA
30 MIN
RUTA DE LA CHARLA
ACTO 1 FRAMING · 4' ACTO 2 ARQUITECTURA · 3' ACTO 3 PATRONES · 12' ACTO 4 DEMO · 5' ACTO 5 CIERRE · 6'
Agenda
04 / 20
05 / 20 · DEFINICIÓN
ARQUITECTURA
UN AGENTE NO ES UN CHATBOT
— ESTO NO —
Chatbot
  • ↳ Entrada: pregunta del usuario
  • ↳ Salida: texto
  • ↳ Sin estado entre interacciones
  • ↳ No ejecuta acciones
— ESTO SÍ —
Agente
  • ↳ Entrada: evento del entorno (alerta, webhook, sensor)
  • ↳ Salida: decisión + acción
  • ↳ Estado: percibe → razona → actúa → repite
  • ↳ Ejecuta tools / cambia el mundo
Qué es un agente
05 / 20
06 / 20 · SETUP
WAZUH + CLAUDE + DOCKER
Architecture animation
Arquitectura
06 / 20
07 / 20 · PATRÓN 01
3 PATRONES
00
Prompting para decisión,
no resumen.
— ANTI-PATRÓN —
Prompt típico
"Resume esta alerta de Wazuh
y dime si es importante."
→ Devuelve un párrafo de texto.
→ Tú decides. El agente solo describe.
— EL PATRÓN —
Prompt con decisión
"Eres analista Blue Team.
Alerta: <json>
Acciones a ejecutar:
 1. kill_sessions(src_ip)
 2. change_password(user)
 3. message_and_kill (honeypot)
Analiza 4-6 líneas: secuencia,
impacto, hardening."
→ Acciones ya decididas en el prompt.
→ El LLM analiza sobre un menú cerrado.
P01 · Decisión vs resumen
07 / 20
08 / 20 · PATRÓN 01 · CÓDIGO
agent.py
EN AGENT.PY
Rol fijo, acciones predefinidas, claude -p
# agent.py · prompt + ask_claude()
_PROMPT_BRUTE_SUCCESS = """
Eres el analista Blue Team del CTF AI Defender.
UN ATACANTE ACABA DE CONSEGUIR ACCESO SSH...

ACCIONES QUE SE VAN A EJECUTAR INMEDIATAMENTE:
  1. Enviar mensaje al terminal del atacante
  2. Terminar su sesión SSH activa  (kill_session)
  3. Rotar la contraseña del usuario comprometido
"""

def ask_claude(prompt: str) -> str | None:
    r = subprocess.run(
        ["claude", "-p", prompt],
        capture_output=True, text=True, timeout=60)
    return r.stdout.strip() if r.returncode == 0 else None
→ El menú de tools vive en el prompt. Claude analiza dentro del marco; no improvisa acciones.
P01 · Código
08 / 20
09 / 20 · PATRÓN 02
3 PATRONES
00
Action loop con rollback
o auditable.
— ANTI-PATRÓN —
Fire & forget
El agente actúa. No sabes qué hizo, ni cuándo, ni por qué. Si algo rompe en producción, no hay forma de rebobinar.
"Speed without rollback
is just faster damage."
— EL PATRÓN —
Cada acción reversible
o trazable
  • action_kill_sessions · log PIDs terminados
  • action_change_password · log nueva pwd
  • action_message_and_kill · honeypot trazado
  • log(EJECUTADO, ...) · huella obligatoria
P02 · Action loop
09 / 20
10 / 20 · PATRÓN 02 · CÓDIGO
agent.py
ACCIÓN CON HUELLA
Toda acción deja log estructurado
def action_change_password(container: str, user: str) -> bool:
    new_pass = _random_password()
    r = subprocess.run(
        ["docker", "exec", container, "bash", "-c",
         f"echo '{user}:{new_pass}' | chpasswd"],
        capture_output=True, text=True, timeout=10)

    # Audit trail — no opcional
    if r.returncode == 0:
        log("EJECUTADO",
            f"Contrasena de '{user}' rotada en {container}",
            GREEN)
        log("NUEVA PASS", new_pass, YELLOW + B)
        return True
    log("ERROR", f"chpasswd: {r.stderr.strip()}", RED)
    return False
→ El log no es opcional. Es parte de la acción. Sin huella, la acción no se considera ejecutada.
P02 · Código
10 / 20
11 / 20 · PATRÓN 03
3 PATRONES
00
Explicabilidad
cuando no hay humano.
— ANTI-PATRÓN —
Caja negra
El agente actuó. Punto. Mañana viene el cliente y pregunta por qué se reinició su sesión a las 3am. No tienes respuesta.
Sin explicabilidad, la confianza
se quema una vez.
— EL PATRÓN —
Razonamiento +
acción + log
  • ↳ Imprime la respuesta de Claude siempre
  • ↳ Cada acción con timestamp + tag MAGENTA
  • ↳ Stream coloreado en consola (audit-friendly)
  • ↳ Replay-able: puedes reconstruir el porqué
P03 · Explicabilidad
11 / 20
12 / 20 · PATRÓN 03 · CÓDIGO
agent.py
PRINT + AUDIT
El razonamiento es parte del output
def print_claude_response(response: str):
    print(f"\n{MAGENTA}{'·'*64}{R}", flush=True)
    for line in response.splitlines():
        print(f"  {WHITE}{line}{R}", flush=True)
    print(f"{MAGENTA}{'·'*64}{R}\n", flush=True)

# Pipeline · respond_brute_success()
log("CLAUDE", "Consultando analista Blue Team...",
    MAGENTA + B)
response = ask_claude(prompt)
if response:
    print_claude_response(response)   # REASON visible
log("ACCION", "Rotando contrasena...", MAGENTA)
action_change_password(agent_name, user)  # EJECUCION
→ Cada acción del agente queda replayable. CLAUDE → REASON → ACCION → EJECUTADO, todo en el mismo log stream.
P03 · Código
12 / 20
13 / 20 · RECAP
3 REGLAS
SÍNTESIS · 3 PATRONES
Patrón Anti-patrón Regla
01 · Decisión, no resumen Prompt "resume esto" Diseña el menú de acciones en el prompt. El LLM analiza, no improvisa.
02 · Action loop con audit Fire & forget Toda acción reversible o trazable. El log es parte de la acción.
03 · Explicabilidad Caja negra CLAUDE → REASON → ACCION → EJECUTADO en el mismo stream. Replayable.
Recap
13 / 20
14 / 20 · DEMO SETUP
● LIVE
QUÉ VAS A VER EN VIVO · 5 MIN
Un ataque real,
una respuesta real.
  1. PASO 01
    test_brute.py · brute-force SSH
  2. PASO 02
    Wazuh dispara → webhook al agent.py
  3. PASO 03
    Claude CLI analiza · decide
  4. PASO 04
    Acción ejecutada · < 30 segundos end-to-end
Demo setup
14 / 20
15 / 20 · DEMO RECAP
< 30 SEG END-TO-END
QUÉ ACABAS DE VER
0s · ATAQUE test_brute.py 8s · ALERTA Wazuh webhook 12s · PROMPT claude -p 22s · DECISIÓN {tool, reason} 25s · ACCIÓN rotate + kill 28s · DONE attacker locked out
Demo recap
15 / 20
16 / 20 · DÓNDE ROMPEN
01 / 03
00
FALLA 01
Over-trust del LLM
El agente confía en el output del modelo como si fuera una decisión humana. Si Claude alucina "deploy_honeypot en 10.0.0.5" contra un host de producción legítimo, el agente lo hace.
→ Mitigación: validar el target contra whitelist antes de actuar. El LLM propone, el código valida.
Rompen · 01
16 / 20
17 / 20 · DÓNDE ROMPEN
02 / 03
00
FALLA 02
Latencia · ventana de daño
Claude CLI tarda 8–15 segundos en pensar. En esos segundos, el atacante ya hizo lo suyo. Para SSH brute-force está bien. Para data exfiltration en burst, llegas tarde.
→ Mitigación: capas. Reglas determinísticas para ventanas < 1s (kill-switch). LLM para análisis post-incident y casos ambiguos.
Rompen · 02
17 / 20
18 / 20 · DÓNDE ROMPEN
03 / 03
00
FALLA 03
Falsos positivos en cascada
Webhook ruidoso → agente actúa sobre alerta falsa → nueva alerta por la acción → agente actúa otra vez. Pesadilla en 30 segundos.
→ Mitigación: cooldown por target (15 min). Rate-limit global. Y un kill-switch grande, rojo, accesible.
Rompen · 03
18 / 20
19 / 20 · QUÉ LLEVARTE
3 REGLAS
QUÉ LLEVARTE
01
Diseña el menú,
el LLM elige.
02
El log es parte
de la acción.
03
Sin replay,
no hay confianza.
Qué llevarte
19 / 20
20 / 20 · GRACIAS
Q&A
Gracias.
Preguntas → ahora
Special thanks · Juan José Chavarría
Julio Espinosa · jespinosa@sofistic.com · sofistic.com
Gracias
20 / 20