Conectar OpenCTI+Shuffle+Wazuh+TheHive Parte III (Los conjuros)
Foto de Deng Xiang en Unsplash

Tenemos el lienzo completo.
Hemos configurado Webhook 1
Ahora veremos como configurar el resto de los nodos.
Gemini Web me ira guiando como siempre en todas las cuestiones técnicas.
Shuffle Tools 1
Este nodo es, literalmente, el cerebro procesador de nuestro flujo.
En la entrega anterior diseñamos el lienzo completo y configuramos la entrada de datos a través de Webhook_1. Ahora que el tráfico de Wazuh llega en tiempo real a Shuffle, es el momento de adentrarnos en la configuración interna de cada nodo.
Empezamos por la pieza central de nuestro orquestador: el nodo Shuffle Tools 1.
Nodo Shuffle Tools 1: ¿Qué es, para qué sirve y qué hace aquí?
1.- El Limpiador / Parser de JSON:
La alerta que dispara Wazuh llega en formato JSON dentro de la variable $Webhook_1.exec.body. Sin embargo, los objetos JSON de logs pueden incluir caracteres especiales, saltos de línea o estructuras anidadas que rompen las llamadas API posteriores si no se procesan correctamente. Shuffle Tools se encarga de recibir, interpretar y normalizar ese JSON.
2.- Extracción del ID de MITRE ATT&CK:
Su función técnica más importante en nuestro flujo es rastrear e aislar la técnica de MITRE que Wazuh asignó al evento (por ejemplo, T1078 o T1059).
3.- Preparación para la bifurcación condicional:
Al extraer y limpiar ese valor (o detectar si viene vacío), Shuffle Tools 1 prepara el terreno para que las dos líneas condicionales que nacen de él sepan hacia dónde enviar la ejecución:
Camino Izquierdo (Http 1): Alerta estándar (sin MITRE).
Camino Derecho (Http 3 ➔ Http 2): Alerta enriquecible con Ciberinteligencia (con MITRE).

Si pinchamos en Shuffle Tools 1 se nos abre un cuadro de dialogo al costado derecho.
Aquí es donde realizamos la extracción precisa del dato clave que necesitamos para la inteligencia de amenazas.
Acción seleccionada:
Repeat back to me
Esta función nativa de Shuffle sirve como un "espejo" o extractor de variables. Toma un valor específico dentro del enorme objeto JSON enviado por Wazuh y lo devuelve como la salida limpia de este nodo.
El parámetro Call:
Dentro del campo Call, introducimos la siguiente expresión entre dobles llaves:
{{ $exec.all_fields.rule.mitre.id.0 }}
¿Por qué usamos exactamente esta sintaxis?
$exec / $Webhook_1: Es el objeto raíz que contiene la ejecución del evento recibido de Wazuh.
all_fields: Wazuh emite el evento estructurado dentro de este bloque con todas sus propiedades descifradas.
rule.mitre.id: Apunta directamente a las etiquetas MITRE ATT&CK asociadas a la regla que ha saltado.
.0 (El índice cero): Dado que una regla de Wazuh puede tener múltiples técnicas MITRE en forma de lista (array), con .0 le indicamos a Shuffle que extraiga la primera técnica identificada (por ejemplo, la T1078 de abuso de cuentas o T1059 de ejecución de comandos).
El resultado de este nodo
La salida (output) de Shuffle Tools 1 dejará de ser una maraña gigante de logs y se convertirá en un string único y limpio con el ID de la técnica (ejemplo: T1078).
Si la alerta de Wazuh no incluye ninguna técnica de MITRE, la salida de este nodo quedará vacía o devolverá null. Esta diferencia es la que permitirá a las condiciones de las ramas saber si desviar la alerta hacia OpenCTI o enviarla directamente a TheHive.
Con Shuffle Tools 1 destripado, el siguiente movimiento lógico es mostrar las condiciones de las dos líneas que nacen de él (Rama Izquierda hacia Http 1 y Rama Derecha hacia Http 3).

Configuración de la condición: Filtrando alertas con MITRE ATT&CK
Una vez que Shuffle Tools 1 ha extraído el campo MITRE de la alerta recibida, debemos decirle a Shuffle hacia dónde dirigir el flujo de ejecución.
Hacemos clic sobre el enlace condicional que va desde Shuffle Tools 1 hacia el nodo Http 1 (el encargado de comunicarse con OpenCTI) y se abrirá el panel de configuración de la rama.
Configuramos la regla con los siguientes tres parámetros:
Source (Origen): $shuffle_tools_1
Hacemos referencia directa al resultado obtenido en el nodo anterior.
Operador: contains (Contiene).
Destination (Destino): T
¿Por qué esta condición tan sencilla es tan potente?
Todas las técnicas oficiales del framework MITRE ATT&CK comienzan indefectiblemente por la letra T mayúscula seguida de cuatro dígitos (por ejemplo: T1078 para Valid Accounts, T1059 para Command and Scripting Interpreter, etc.).
Si la alerta SÍ trae una técnica MITRE: La salida de Shuffle Tools 1 será algo como T1078. La condición evalúa que la cadena contiene la letra 'T', la regla se cumple (TRUE) y el flujo avanza por esta rama hacia OpenCTI para consultar la inteligencia de amenazas.
Si la alerta NO trae técnica MITRE: La salida estará vacía o no contendrá la letra 'T'. La condición falla (FALSE) y Shuffle bloquea el paso por esta vía, enviando el evento por la otra rama para una gestión estándar.
¡Ya tenemos la puerta de entrada a OpenCTI completamente abierta!
El siguiente paso es ver cómo está configurado por dentro el nodo Http 1: la URL de la API GraphQL de OpenCTI, el método HTTP (POST), las cabeceras con el Bearer Token y la famosa consulta JSON/GraphQL que nos costó sus buenas horas ajustar.
Configuración del nodo Http 1.
En el lienzo de tu workflow funcional V5, el nodo que conecta con OpenCTI es el Http 1 (a la derecha abajo, resaltado en marrón) y desde él sale la flecha hacia Http 2. ¡Perfecto! Esto deja claro cómo viaja la información en producción.

Consulta GraphQL a OpenCTI
Cuando la condición se cumple (la alerta contiene un ID de MITRE), el flujo activa el nodo Http 1. Este nodo se encarga de realizar una petición HTTP POST a la API GraphQL de nuestra plataforma de Ciberinteligencia (OpenCTI).
Seleccionamos el nodo en el lienzo y configuramos sus parámetros en el panel derecho:
1.- Método HTTP: POST
2.- URL: http://192.168.1.101:8080/graphql
(Apuntamos al puerto 8080 de nuestra máquina donde corre el motor GraphQL de OpenCTI).
3.- Las Cabeceras (Headers)
En el recuadro Headers especificamos el formato de envío y el token de autenticación:
Content-Type: application/json
Authorization: Bearer ´El token API de OpenCTI ´
Content-Type: Indica a la API que le enviaremos un objeto JSON.
Authorization: Bearer <TOKEN>: Es el token API de OpenCTI (el UUID que obtenemos desde el perfil de usuario en la interfaz web de OpenCTI). Sin este token Bearer, OpenCTI rechazaría la petición devolviendo un error 401 Unauthorized.
4.- El Cuerpo de la Petición (Body): La consulta GraphQL
En el cuadro Body introducimos la Query que le formula la pregunta exacta al motor de inteligencia:
{
"query": "query { attackPatterns(filters: { mode: and, filters: [{ key: \"x_mitre_id\", values: [$shuffle_tools_1.0], operator: eq }], filterGroups: [] }) { edges { node { id name description x_mitre_id } } } }"
}Entendiendo la magia de la Query:
attackPatterns: Le pedimos a OpenCTI que busque en su base de conocimientos dentro del catálogo de patrones de ataque (Attack Patterns de MITRE).
key: "x_mitre_id" + values: [$shuffle_tools_1.0]: Aquí usamos la variable que extrajimos en el nodo anterior. En lugar de buscar "a ciegas", la Query se dinamiza y le dice a OpenCTI: "Busca el patrón cuyo ID de MITRE sea igual al valor que nos dio $shuffle_tools_1.0" (por ejemplo, T1078).
node { id name description x_mitre_id }: Especificamos los datos exactos que queremos que OpenCTI nos devuelva: el ID interno del objeto, el nombre oficial de la amenaza, su descripción técnica y su ID de MITRE.
5.- Parámetro Verify: False
En la parte inferior del panel marcamos Verify: False. Al estar trabajando en un entorno local de pruebas con direcciones IP privadas (192.168.1.x) sin certificados SSL/TLS firmados por una CA pública, esto evita que Shuffle aborte la conexión por errores de certificado HTTPS.
Con Http 1 (OpenCTI) perfectamente configurado, OpenCTI nos responderá con un JSON repleto de inteligencia (la descripción oficial de la amenaza).
Ahora le toca el turno al nodo Http 2 (el nodo central que recibe la flecha de Http 1), que usará toda esa inteligencia enriquecida para crear el caso definitivo en TheHive.

Configuración del nodo Http 2: Creación del caso enriquecido en TheHive
Una vez que Http 1 recibe la respuesta de OpenCTI con la inteligencia de amenazas, la ejecución avanza inmediatamente hacia Http 2.
La misión de este nodo es tomar la alerta original de Wazuh, vestirla con la descripción oficial que nos acaba de dar OpenCTI y enviarla mediante una llamada API a la plataforma de gestión de incidentes (TheHive).
Configuramos el nodo con los siguientes parámetros:
1.- Método HTTP: POST
2.- URL: http://192.168.1.101:9000/api/v1/case
(Apuntamos al endpoint nativo de TheHive en el puerto 9000 para la creación de casos).
3.- Las Cabeceras (Headers)
Content-Type: application/json
Authorization: Bearer ´API Key de TheHive´
4.- El Cuerpo de la Petición (Body): La estructura del caso
En el campo Body introducimos la plantilla JSON formateada que TheHive interpretará para construir la ficha del caso:
{
"title": "Alerta Wazuh [$shuffle_tools_1.0]: $exec.title",
"description": "Técnica MITRE: $shuffle_tools_1.0\nNombre: $http_1.body.data.attackPatterns.edges.0.node.name\nDescripción OpenCTI: $http_1.body.data.attackPatterns.edges.0.node.description\n\n--- Detalle Completo de Wazuh ---\n$exec.text",
"severity": 2,
"tlp": 1,
"pap": 1,
"tags": [
"Wazuh",
"MITRE",
"$shuffle_tools_1.0"
],
"flag": false
}Desglosando la anatomía de esta integración de datos:
title: Dinamizamos el título combinando la técnica procesada por Shuffle ($shuffle_tools_1.0) y el título original de la regla emitido por Wazuh ($exec.title).
description (El enriquecimiento en acción):
Fusionamos tres fuentes de datos en una sola vista para el analista:
La técnica extraída por Shuffle Tools ($shuffle_tools_1.0).
El nombre del patrón de ataque extraído de OpenCTI ($http_1.body.data.attackPatterns.edges.0.node.name).
La descripción detallada de OpenCTI (...node.description).
Los datos crudos y traza del evento de Wazuh ($exec.text).
severity, tlp y pap: Asignamos valores estándar para el filtrado de privacidad e impacto en el SOC (ejemplo: Severity 2 = Media, TLP 1 = AMBER).
tags: Etiquetamos el caso automáticamente en TheHive con la palabra Wazuh, MITRE y el ID de la técnica (ejemplo: T1078), lo que permitirá a los analistas filtrar o buscar incidentes por técnica con un solo clic.
¡La rama de inteligencia con OpenCTI está completamente documentada!
Para ponerle el broche final a esta Parte III, solo nos falta ver el último nodo: Http 3 (el nodo de la rama izquierda, la vía rápida cuando una alerta NO tiene técnica MITRE).
La rama estándar: Condición para alertas sin MITRE ATT&CK
Para cerrar la lógica de decisión, debemos configurar la rama izquierda que se activa cuando Wazuh emite una alerta genérica que no está vinculada a ninguna técnica MITRE.
Hacemos clic sobre el enlace condicional hacia Http 3
Source: $shuffle_tools_1
Condición: is empty (Está vacío)
Destination: (Se deja en blanco)

¿Cómo actúa este filtro?
Si Shuffle Tools 1 no encuentra ninguna etiqueta MITRE en el JSON de Wazuh, su salida estará vacía. La condición is empty se evaluará como verdadera (TRUE) y enviará la ejecución directamente hacia Http 3, evitando consultas innecesarias a OpenCTI.
Configuración del nodo Http 3: Creación del caso directo en TheHive

El nodo Http 3 realiza el envío de la alerta en bruto hacia TheHive sin pasar por el proceso de enriquecimiento.
1.- Método: POST
2.- URL: [http://192.168.1.101:9000/api/v1/case](http://192.168.1.101:9000/api/v1/case)
3.- Headers:
Content-Type: application/json
Authorization: Bearer ´API Key de TheHive´4.- Body (Cuerpo JSON):
{
"title": "Alerta Wazuh: $exec.title",
"description": "Detalles del evento de Wazuh:\n$exec.text",
"severity": 1,
"tlp": 1,
"pap": 1,
"tags": ["Wazuh", "Normal"],
"flag": false
}Diferencias clave con la rama enriquecida:
Simplicidad: La descripción solo incluye el texto crudo enviado por Wazuh ($exec.text).
Clasificación: Asigna una severidad menor (severity: 1) y una etiqueta genérica ("Normal"), permitiendo al SOC priorizar rápidamente los casos que sí cuentan con inteligencia de amenazas frente a los avisos estándar.
El siguiente paso para la Parte IV
Probar el flujo de extremo a extremo: lanzar una alerta simulada desde Wazuh y mostrar la captura de la traza verde en Shuffle (Debug/Executions) y el caso recién creado en TheHive.
"No quiero extender en exceso estas publicaciones.
Esta parte de la orquestación, que en teoría parece sencilla, siempre que demos con la tecla exacta, la IA esté de buen humor para dar la respuesta precisa o acertemos de lleno al formular la pregunta (prompt), me ha costado más de un mes de picar código, revisar documentación oficial, adaptarla a mi entorno y confiar en que la siguiente respuesta fuera, por fin, el paso definitivo.
Como veis, la arquitectura de este SOC es 100% personalizada. Es lo que a mí me dio Lovable y en lo que me he basado para construirlo.
Es muy probable, casi seguro, que quienes estéis siguiendo estas guías os encontréis con piedras en el camino distintas a las mías. Pero si algo he aprendido en este proceso es que, con tiempo y ganas, todo acaba saliendo.
Ya lo decía el refrán: 'Con tiempo y una caña, todo se pesca'. Y en la ingeniería de detección y respuesta, no hay verdad más grande."
Barakaldo 30 de julio de 2026.
Etiquetas:
También te podría interesar...
🔥 Lo más leído en el blog
Sobre Jose
Este autor prefiere mantener el misterio y aún no ha escrito su biografía.
Comentarios (0)
Inicia sesión para unirte a la conversación.
No hay comentarios aún. ¡Sé el primero en comentar!