Zion Boggan zionboggan.com ↗

shuffle enrichment workflow: vt/otx lookup -> thehive case

b366f1d   Zion Boggan committed on Mar 27, 2026 (2 months ago)
shuffle/docker-compose.yml +66 -0
@@ -0,0 +1,66 @@
+name: shuffle
+
+services:
+ shuffle-database:
+ image: opensearchproject/opensearch:2.14.0
+ hostname: shuffle-database
+ restart: unless-stopped
+ environment:
+ - OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g
+ - bootstrap.memory_lock=true
+ - DISABLE_INSTALL_DEMO_CONFIG=true
+ - DISABLE_SECURITY_PLUGIN=true
+ - discovery.type=single-node
+ ulimits:
+ memlock:
+ soft: -1
+ hard: -1
+ volumes:
+ - shuffle-database:/usr/share/opensearch/data
+
+ shuffle-backend:
+ image: ghcr.io/shuffle/shuffle-backend:1.4.0
+ hostname: shuffle-backend
+ restart: unless-stopped
+ depends_on:
+ - shuffle-database
+ ports:
+ - "5001:5001"
+ environment:
+ - SHUFFLE_APP_HOTLOAD_FOLDER=./shuffle-apps
+ - SHUFFLE_FILE_LOCATION=./shuffle-files
+ - ORG_ID=Shuffle
+ - BASE_URL=http://shuffle-backend:5001
+ - DOCKER_API_VERSION=1.40
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - shuffle-apps:/shuffle-apps
+ - shuffle-files:/shuffle-files
+
+ shuffle-frontend:
+ image: ghcr.io/shuffle/shuffle-frontend:1.4.0
+ hostname: shuffle-frontend
+ restart: unless-stopped
+ depends_on:
+ - shuffle-backend
+ ports:
+ - "3443:3443"
+ environment:
+ - BACKEND_HOSTNAME=shuffle-backend
+
+ shuffle-orborus:
+ image: ghcr.io/shuffle/shuffle-orborus:1.4.0
+ hostname: shuffle-orborus
+ restart: unless-stopped
+ environment:
+ - SHUFFLE_APP_SDK_TIMEOUT=300
+ - ENVIRONMENT_NAME=Shuffle
+ - BASE_URL=http://shuffle-backend:5001
+ - DOCKER_API_VERSION=1.40
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+
+volumes:
+ shuffle-database:
+ shuffle-apps:
+ shuffle-files:
shuffle/workflows/wazuh-thehive-enrichment.json +122 -0
@@ -0,0 +1,122 @@
+{
+ "name": "Wazuh -> TheHive Enrichment",
+ "description": "Enrich the offending indicator from a Wazuh alert, open a TheHive case with the verdict, and notify the analyst channel.",
+ "workflow_type": "standalone",
+ "triggers": [
+ {
+ "id": "trigger_webhook",
+ "app_name": "Webhook",
+ "name": "wazuh_alert",
+ "trigger_type": "WEBHOOK",
+ "status": "running",
+ "parameters": [
+ { "name": "tmp", "value": "" }
+ ]
+ }
+ ],
+ "actions": [
+ {
+ "id": "action_route",
+ "app_name": "Shuffle Tools",
+ "app_version": "1.2.0",
+ "name": "router",
+ "label": "Pick indicator",
+ "parameters": [
+ {
+ "name": "input_data",
+ "value": "$exec.src_ip || $exec.dst_ip"
+ }
+ ]
+ },
+ {
+ "id": "action_vt",
+ "app_name": "VirusTotal",
+ "app_version": "1.1.0",
+ "name": "get_ip_report",
+ "label": "VirusTotal lookup",
+ "parameters": [
+ { "name": "apikey", "value": "${vt_api_key}" },
+ { "name": "ip", "value": "$action_route.output" }
+ ]
+ },
+ {
+ "id": "action_otx",
+ "app_name": "AlienVault OTX",
+ "app_version": "1.0.0",
+ "name": "get_indicator",
+ "label": "OTX pulses",
+ "parameters": [
+ { "name": "apikey", "value": "${otx_api_key}" },
+ { "name": "indicator_type", "value": "IPv4" },
+ { "name": "indicator", "value": "$action_route.output" }
+ ]
+ },
+ {
+ "id": "action_score",
+ "app_name": "Shuffle Tools",
+ "app_version": "1.2.0",
+ "name": "execute_python",
+ "label": "Score verdict",
+ "parameters": [
+ {
+ "name": "code",
+ "value": "vt = int($action_vt.last_analysis_stats.malicious or 0)\notx = int($action_otx.pulse_info.count or 0)\nscore = vt * 2 + otx\nseverity = 3 if score >= 6 else (2 if score >= 2 else 1)\nreturn {\"score\": score, \"severity\": severity, \"vt_malicious\": vt, \"otx_pulses\": otx}"
+ }
+ ]
+ },
+ {
+ "id": "action_case",
+ "app_name": "TheHive",
+ "app_version": "1.4.0",
+ "name": "create_case",
+ "label": "Open TheHive case",
+ "parameters": [
+ { "name": "apikey", "value": "${thehive_api_key}" },
+ { "name": "url", "value": "${thehive_url}" },
+ { "name": "title", "value": "[Wazuh] $exec.rule_description" },
+ { "name": "description", "value": "Agent: $exec.agent_name ($exec.agent_ip)\nRule: $exec.rule_id level $exec.rule_level\nIndicator: $action_route.output\nVirusTotal malicious: $action_score.vt_malicious\nOTX pulses: $action_score.otx_pulses\n\n$exec.full_log" },
+ { "name": "severity", "value": "$action_score.severity" },
+ { "name": "tags", "value": "wazuh,automated,$exec.mitre.id" },
+ { "name": "tlp", "value": "2" }
+ ]
+ },
+ {
+ "id": "action_observable",
+ "app_name": "TheHive",
+ "app_version": "1.4.0",
+ "name": "create_observable",
+ "label": "Attach indicator",
+ "parameters": [
+ { "name": "apikey", "value": "${thehive_api_key}" },
+ { "name": "url", "value": "${thehive_url}" },
+ { "name": "case_id", "value": "$action_case.id" },
+ { "name": "data_type", "value": "ip" },
+ { "name": "data", "value": "$action_route.output" },
+ { "name": "ioc", "value": "true" },
+ { "name": "tags", "value": "cti,wazuh" }
+ ]
+ },
+ {
+ "id": "action_notify",
+ "app_name": "Slack",
+ "app_version": "1.1.0",
+ "name": "post_message",
+ "label": "Notify analysts",
+ "parameters": [
+ { "name": "apikey", "value": "${slack_token}" },
+ { "name": "channel", "value": "#soc-alerts" },
+ { "name": "text", "value": ":rotating_light: New case from Wazuh rule $exec.rule_id (sev $action_score.severity)\nIndicator $action_route.output - VT $action_score.vt_malicious / OTX $action_score.otx_pulses\nTheHive case: $action_case.id" }
+ ]
+ }
+ ],
+ "branches": [
+ { "source_id": "trigger_webhook", "destination_id": "action_route" },
+ { "source_id": "action_route", "destination_id": "action_vt" },
+ { "source_id": "action_route", "destination_id": "action_otx" },
+ { "source_id": "action_vt", "destination_id": "action_score" },
+ { "source_id": "action_otx", "destination_id": "action_score" },
+ { "source_id": "action_score", "destination_id": "action_case" },
+ { "source_id": "action_case", "destination_id": "action_observable" },
+ { "source_id": "action_case", "destination_id": "action_notify" }
+ ]
+}