Wazuh сторонние интеграции - Osquery, MISP, SOAR

Wazuh 4.14 расширяет возможности мониторинга и реагирования через интеграцию со сторонними платформами безопасности. Модуль Osquery обеспечивает расширенный сбор данных с конечных точек, платформы threat intelligence (MISP, OpenCTI) позволяют обогащать алерты индикаторами компрометации, а SOAR-решения автоматизируют полный цикл реагирования на инциденты.

Интеграция с Osquery

Osquery - инструмент для запросов к операционной системе через SQL-подобный интерфейс. Wazuh интегрируется с Osquery через модуль wodle, что позволяет выполнять запросы на агентах и анализировать результаты на сервере.

Настройка wodle osquery

Модуль настраивается в конфигурации агента /var/ossec/etc/ossec.conf:

<wodle name="osquery">
  <disabled>no</disabled>
  <run_daemon>yes</run_daemon>
  <log_path>/var/log/osquery/osqueryd.results.log</log_path>
  <config_path>/etc/osquery/osquery.conf</config_path>
  <add_labels>yes</add_labels>
</wodle>

Параметры модуля:

ПараметрОписаниеЗначение по умолчанию
<disabled>Включение/отключение модуляyes
<run_daemon>Управление демоном osquerydyes
<log_path>Путь к файлу результатов Osquery/var/log/osquery/osqueryd.results.log
<config_path>Путь к конфигурации Osquery/etc/osquery/osquery.conf
<add_labels>Добавление меток агента к результатамyes

Конфигурация Osquery Pack

Osquery использует файлы конфигурации в формате JSON для определения запросов:

{
  "schedule": {
    "system_info": {
      "query": "SELECT hostname, cpu_brand, physical_memory FROM system_info;",
      "interval": 3600,
      "description": "System information"
    },
    "open_ports": {
      "query": "SELECT DISTINCT pid, port, protocol, address FROM listening_ports WHERE port != 0;",
      "interval": 300,
      "description": "Open network ports"
    },
    "installed_packages": {
      "query": "SELECT name, version, source FROM deb_packages UNION SELECT name, version, source FROM rpm_packages;",
      "interval": 86400,
      "description": "Installed packages inventory"
    },
    "suspicious_processes": {
      "query": "SELECT p.name, p.path, p.cmdline, p.uid, u.username FROM processes p LEFT JOIN users u ON p.uid = u.uid WHERE p.on_disk = 0;",
      "interval": 60,
      "description": "Processes running from deleted binaries"
    }
  }
}

Правила обнаружения для Osquery

Wazuh анализирует результаты Osquery через движок правил. Встроенные правила покрывают базовые сценарии, но для расширенного мониторинга рекомендуется создавать собственные правила:

<rule id="100200" level="10">
  <decoded_as>osquery</decoded_as>
  <field name="osquery.name">suspicious_processes</field>
  <description>Osquery: process running from deleted binary detected on $(agent.name)</description>
  <mitre>
    <id>T1036</id>
  </mitre>
  <group>osquery,process_anomaly,</group>
</rule>

Подробнее о создании правил обнаружения читайте в разделе Возможности Wazuh .

Threat Intelligence - MISP

MISP (Malware Information Sharing Platform) - платформа обмена индикаторами компрометации (IoC). Интеграция с Wazuh позволяет автоматически проверять наблюдаемые объекты (IP-адреса, домены, хеши файлов) по базе IoC MISP.

Архитектура интеграции MISP

Wazuh Alert --> Custom Integration Script --> MISP API --> IoC Lookup
                                                              |
                                                    Match Found? --> Enriched Alert

Настройка интеграции

  1. Создайте API-ключ в MISP: Administration - Auth Keys - Add authentication key
  2. Установите скрипт интеграции:
#!/usr/bin/env python3
"""MISP integration for Wazuh - IoC lookup."""
import sys
import json
import requests
from typing import Optional

MISP_URL = "https://misp.example.com"
MISP_API_KEY = "YOUR_MISP_API_KEY"
VERIFY_SSL = True

def search_ioc(value: str, ioc_type: str) -> Optional[dict]:
    """Search for an IoC in MISP."""
    headers = {
        "Authorization": MISP_API_KEY,
        "Accept": "application/json",
        "Content-Type": "application/json",
    }
    payload = {
        "returnFormat": "json",
        "value": value,
        "type": ioc_type,
    }
    response = requests.post(
        f"{MISP_URL}/attributes/restSearch",
        json=payload,
        headers=headers,
        verify=VERIFY_SSL,
    )
    if response.status_code == 200:
        results = response.json()
        if results.get("response", {}).get("Attribute"):
            return results["response"]["Attribute"][0]
    return None

def main():
    alert_file = sys.argv[1]
    with open(alert_file) as f:
        alert = json.load(f)

    # Extract source IP from alert
    src_ip = alert.get("data", {}).get("srcip")
    if src_ip:
        result = search_ioc(src_ip, "ip-src")
        if result:
            print(json.dumps({
                "misp_match": True,
                "event_id": result.get("event_id"),
                "category": result.get("category"),
                "comment": result.get("comment"),
            }))

if __name__ == "__main__":
    main()
  1. Настройте в ossec.conf:
<integration>
  <name>custom-misp</name>
  <hook_url>https://misp.example.com</hook_url>
  <api_key>YOUR_MISP_API_KEY</api_key>
  <level>7</level>
  <group>web,sshd,firewall,</group>
  <alert_format>json</alert_format>
</integration>

Типы IoC для проверки

Тип IoCИсточник в алерте WazuhТип MISP
IP-адрес источникаdata.srcipip-src
IP-адрес назначенияdata.dstipip-dst
Доменdata.hostnamedomain
Хеш файла (MD5)syscheck.md5_aftermd5
Хеш файла (SHA256)syscheck.sha256_aftersha256
URLdata.urlurl

Threat Intelligence - OpenCTI

OpenCTI - платформа управления данными о киберугрозах, поддерживающая стандарты STIX/TAXII.

Интеграция через TAXII Feed

Wazuh может потреблять IoC из OpenCTI через TAXII-сервер:

  1. Настройте экспорт коллекции в OpenCTI с TAXII endpoint
  2. Создайте скрипт периодической синхронизации IoC в формат CDB-списков Wazuh:
#!/bin/bash
# Sync OpenCTI IoC to Wazuh CDB lists
TAXII_URL="https://opencti.example.com/taxii2/feeds"
OUTPUT_DIR="/var/ossec/etc/lists"

# Download IP indicators
curl -sk -H "Authorization: Bearer ${OPENCTI_TOKEN}" \
  "${TAXII_URL}/ip-indicators" \
  | jq -r '.objects[] | select(.type=="indicator") | .pattern' \
  | sed "s/\[ipv4-addr:value = '//;s/'\]//" \
  | while read ip; do echo "${ip}:malicious"; done \
  > "${OUTPUT_DIR}/opencti-malicious-ips"

# Reload Wazuh rules
/var/ossec/bin/wazuh-control reload
  1. Используйте CDB-список в правилах:
<rule id="100210" level="12">
  <if_sid>5710</if_sid>
  <list field="srcip" lookup="address_match_key">etc/lists/opencti-malicious-ips</list>
  <description>Connection from IP flagged in OpenCTI threat intelligence: $(srcip)</description>
  <mitre>
    <id>T1071</id>
  </mitre>
  <group>threat_intelligence,opencti,</group>
</rule>

Тикет-системы - Jira

Интеграция с Jira позволяет автоматически создавать задачи при срабатывании критических алертов.

Настройка Jira Integration

  1. Создайте API Token в Jira: Account Settings - Security - API Tokens
  2. Установите скрипт интеграции:
#!/usr/bin/env python3
"""Jira integration for Wazuh - automatic ticket creation."""
import sys
import json
import requests
from base64 import b64encode

JIRA_URL = "https://company.atlassian.net"
JIRA_USER = "security-bot@company.com"
JIRA_TOKEN = "YOUR_JIRA_API_TOKEN"
JIRA_PROJECT = "SEC"

def create_ticket(alert: dict) -> dict:
    """Create a Jira issue from a Wazuh alert."""
    rule = alert.get("rule", {})
    agent = alert.get("agent", {})

    level = rule.get("level", 0)
    if level >= 12:
        priority = "Critical"
    elif level >= 10:
        priority = "High"
    elif level >= 7:
        priority = "Medium"
    else:
        priority = "Low"

    issue_data = {
        "fields": {
            "project": {"key": JIRA_PROJECT},
            "summary": f"[Wazuh] {rule.get('description', 'Security Alert')}",
            "description": (
                f"*Alert Details*\n"
                f"- Rule ID: {rule.get('id')}\n"
                f"- Level: {level}\n"
                f"- Agent: {agent.get('name')} ({agent.get('id')})\n"
                f"- Timestamp: {alert.get('timestamp')}\n"
                f"- Full log: {alert.get('full_log', 'N/A')}\n"
            ),
            "issuetype": {"name": "Bug"},
            "priority": {"name": priority},
            "labels": ["wazuh", "security-alert"],
        }
    }

    auth = b64encode(f"{JIRA_USER}:{JIRA_TOKEN}".encode()).decode()
    headers = {
        "Authorization": f"Basic {auth}",
        "Content-Type": "application/json",
    }

    response = requests.post(
        f"{JIRA_URL}/rest/api/3/issue",
        json=issue_data,
        headers=headers,
    )
    return response.json()

def main():
    alert_file = sys.argv[1]
    with open(alert_file) as f:
        alert = json.load(f)
    create_ticket(alert)

if __name__ == "__main__":
    main()
  1. Настройте в ossec.conf:
<integration>
  <name>custom-jira</name>
  <hook_url>https://company.atlassian.net</hook_url>
  <api_key>YOUR_JIRA_API_TOKEN</api_key>
  <level>10</level>
  <alert_format>json</alert_format>
</integration>

Тикет-системы - ServiceNow

ServiceNow интеграция реализуется через REST API или webhook.

Настройка через REST API

#!/usr/bin/env python3
"""ServiceNow integration for Wazuh - incident creation."""
import sys
import json
import requests

SNOW_INSTANCE = "company.service-now.com"
SNOW_USER = "wazuh-integration"
SNOW_PASSWORD = "YOUR_PASSWORD"

def create_incident(alert: dict) -> dict:
    """Create a ServiceNow incident from a Wazuh alert."""
    rule = alert.get("rule", {})
    agent = alert.get("agent", {})

    level = rule.get("level", 0)
    urgency_map = {range(12, 16): "1", range(10, 12): "2", range(7, 10): "3"}
    urgency = "3"
    for level_range, urg in urgency_map.items():
        if level in level_range:
            urgency = urg
            break

    incident = {
        "short_description": f"Wazuh Alert: {rule.get('description')}",
        "description": json.dumps(alert, indent=2),
        "urgency": urgency,
        "category": "Security",
        "subcategory": "Threat Detection",
        "assignment_group": "Security Operations",
        "caller_id": "wazuh-integration",
    }

    response = requests.post(
        f"https://{SNOW_INSTANCE}/api/now/table/incident",
        json=incident,
        auth=(SNOW_USER, SNOW_PASSWORD),
        headers={"Content-Type": "application/json", "Accept": "application/json"},
    )
    return response.json()

def main():
    alert_file = sys.argv[1]
    with open(alert_file) as f:
        alert = json.load(f)
    create_incident(alert)

if __name__ == "__main__":
    main()

Альтернатива: ServiceNow Webhook

ServiceNow поддерживает Inbound REST API, что позволяет использовать встроенный механизм webhook:

<integration>
  <name>custom-servicenow</name>
  <hook_url>https://company.service-now.com/api/now/table/incident</hook_url>
  <api_key>BASE64_ENCODED_CREDENTIALS</api_key>
  <level>10</level>
  <alert_format>json</alert_format>
</integration>

SOAR - Shuffle

Shuffle предоставляет визуальный конструктор workflows для автоматизации реагирования на инциденты.

Расширенная настройка Shuffle

Помимо базовой webhook-интеграции, описанной в разделе SIEM-интеграции , Shuffle поддерживает двустороннее взаимодействие с Wazuh через API.

Пример workflow: блокировка IP через Active Response

  1. Trigger: webhook получает алерт от Wazuh
  2. Condition: проверка уровня алерта >= 10 и наличие srcip
  3. Enrichment: запрос IP reputation через AbuseIPDB
  4. Decision: если IP в блоклисте - продолжить
  5. Action: вызов Wazuh API для запуска Active Response:
{
  "command": "firewall-drop0",
  "arguments": ["-", "srcip", "${srcip}"],
  "alert": {
    "data": {
      "srcip": "${srcip}"
    }
  }
}
  1. Notification: отправка результата в Slack-канал

Мониторинг работоспособности Shuffle

Для контроля доставки алертов в Shuffle рекомендуется настроить мониторинг:

<rule id="100220" level="3">
  <decoded_as>json</decoded_as>
  <field name="integration">shuffle</field>
  <description>Shuffle integration: alert forwarded successfully</description>
  <group>integration_health,</group>
</rule>

SOAR - Cortex XSOAR

Cortex XSOAR (ранее Demisto) - коммерческая SOAR-платформа от Palo Alto Networks.

Интеграция через Syslog

Cortex XSOAR поддерживает прием данных через syslog. Настройте syslog forwarding в Wazuh:

<syslog_output>
  <server>xsoar.example.com</server>
  <port>1514</port>
  <format>json</format>
  <level>7</level>
</syslog_output>

Интеграция через REST API

Cortex XSOAR предоставляет REST API для создания инцидентов:

#!/usr/bin/env python3
"""Cortex XSOAR integration for Wazuh."""
import sys
import json
import requests

XSOAR_URL = "https://xsoar.example.com"
XSOAR_API_KEY = "YOUR_XSOAR_API_KEY"

def create_incident(alert: dict) -> dict:
    """Create a Cortex XSOAR incident."""
    rule = alert.get("rule", {})
    severity_map = {
        range(0, 4): 0.5,   # Info
        range(4, 7): 1,     # Low
        range(7, 10): 2,    # Medium
        range(10, 12): 3,   # High
        range(12, 16): 4,   # Critical
    }

    level = rule.get("level", 0)
    severity = 1
    for level_range, sev in severity_map.items():
        if level in level_range:
            severity = sev
            break

    incident = {
        "name": f"Wazuh: {rule.get('description')}",
        "type": "Wazuh Alert",
        "severity": severity,
        "details": json.dumps(alert),
        "labels": [
            {"type": "rule_id", "value": str(rule.get("id"))},
            {"type": "agent", "value": alert.get("agent", {}).get("name", "")},
        ],
    }

    headers = {
        "Authorization": XSOAR_API_KEY,
        "Content-Type": "application/json",
        "Accept": "application/json",
    }

    response = requests.post(
        f"{XSOAR_URL}/incident",
        json=incident,
        headers=headers,
    )
    return response.json()

def main():
    alert_file = sys.argv[1]
    with open(alert_file) as f:
        alert = json.load(f)
    create_incident(alert)

if __name__ == "__main__":
    main()

Playbooks для Wazuh

Cortex XSOAR поддерживает создание playbooks - автоматизированных сценариев реагирования. Рекомендуемые playbooks для Wazuh:

PlaybookТриггерДействия
Brute Force ResponseRule group: authentication_failedБлокировка IP, уведомление SOC, создание тикета
Malware TriageRule group: syscheck + VirusTotal matchИзоляция хоста, сбор артефактов, анализ
Vulnerability ManagementRule group: vulnerability-detectorПриоритизация CVE, назначение ответственного

Устранение неполадок

Osquery не возвращает результаты

  1. Проверьте статус демона Osquery:
systemctl status osqueryd
  1. Убедитесь, что путь <log_path> в wodle совпадает с реальным расположением лога:
ls -la /var/log/osquery/osqueryd.results.log
  1. Проверьте конфигурацию Osquery на ошибки:
osqueryi --config_path /etc/osquery/osquery.conf --config_check

MISP-интеграция возвращает ошибки

  • SSL-ошибки: убедитесь, что сертификат MISP доверен на сервере Wazuh, или установите VERIFY_SSL = False для тестирования
  • 403 Forbidden: проверьте права API-ключа - необходим как минимум auth_key с доступом к атрибутам
  • Таймауты: увеличьте timeout в requests до 30 секунд для больших баз IoC

Jira/ServiceNow тикеты не создаются

  1. Проверьте сетевую доступность:
curl -sk https://company.atlassian.net/rest/api/3/serverInfo
  1. Убедитесь, что API-токен не истек
  2. Проверьте права проекта - пользователь интеграции должен иметь разрешение на создание задач

Shuffle workflow не запускается

  1. Проверьте логи integratord:
grep shuffle /var/ossec/logs/integrations.log
  1. Убедитесь, что webhook URL в Shuffle активен (зеленый индикатор)
  2. Проверьте, что workflow опубликован (не в режиме Draft)

Подробнее о создании собственных скриптов интеграции читайте в разделе Разработка пользовательских интеграций .

Last updated on