Triaj automat al alertelor de securitate cu AI peste Wazuh – reducere zgomot SIEM și mapare MITRE ATT&CK

Configurare noua (How To)

Situatie

Un SIEM precum Wazuh generează zilnic sute sau mii de alerte, majoritatea fals-pozitive sau redundante. Analiștii de securitate pierd timp triind manual alerte în loc să investigheze incidentele reale. Această soluție interoghează API-ul Wazuh, trimite alertele către un model AI local (Ollama sau Foundry Local) care le clasifică după severitate reală, le grupează pe cauză comună și le mapează pe tactici MITRE ATT&CK — totul rămâne local, fără trimitere de date către servicii cloud.

Solutie

Pasi de urmat

Pasul 1 — Creare utilizator API Wazuh dedicat (read-only)

# Pe serverul Wazuh, creeaza un utilizator API cu rol readonly
curl -k -u wazuh:parola_admin -X POST “https://localhost:55000/security/users” \
-H “Content-Type: application/json” \
-d ‘{“username”: “ai-triage-readonly”, “password”: “ParolaComplexa!23”}’

# Asigneaza rolul readonly
curl -k -u wazuh:parola_admin -X POST \
“https://localhost:55000/security/users/ai-triage-readonly/roles?role_ids=readonly”

Pregătire mediu Python

pip install requests ollama colorama python-dotenv

Funcție de autentificare și extragere alerte din Wazuh.

Salvează ca wazuh_client.py:

import requests
import urllib3
from datetime import datetime, timedelta

urllib3.disable_warnings()

WAZUH_URL = “https://wazuh-server:55000”
API_USER = “ai-triage-readonly”
API_PASS = “ParolaComplexa!23″

def get_auth_token():
response = requests.post(
f”{WAZUH_URL}/security/user/authenticate”,
auth=(API_USER, API_PASS),
verify=False
)
return response.json()[“data”][“token”]

def get_recent_alerts(token, hours=24, limit=100):
headers = {“Authorization”: f”Bearer {token}”}
since = (datetime.utcnow() – timedelta(hours=hours)).isoformat()

response = requests.get(
f”{WAZUH_URL}/alerts”,
headers=headers,
params={“limit”: limit, “q”: f”timestamp>{since}”},
verify=False
)
return response.json()[“data”][“affected_items”]

Funcție de analiză AI cu mapare MITRE ATT&CK.

Salvează ca ai_triage.py:

import ollama
import json

MODEL = “llama3”

MITRE_CONTEXT = “””
Tactici MITRE ATT&CK relevante pentru referinta:
– Initial Access (TA0001): phishing, exploatare servicii publice
– Execution (TA0002): rulare cod malitios
– Persistence (TA0003): mentinere acces (scheduled tasks, registry)
– Privilege Escalation (TA0004): escaladare drepturi
– Defense Evasion (TA0005): stergere loguri, dezactivare AV
– Credential Access (TA0006): dumping parole, brute-force
– Lateral Movement (TA0008): miscare intre sisteme
– Exfiltration (TA0010): extragere date
“””

def group_and_triage_alerts(alerts):
alerts_summary = “\n”.join([
f”- [{a.get(‘rule’, {}).get(‘level’, ‘?’)}] ”
f”{a.get(‘rule’, {}).get(‘description’, ‘N/A’)} ”
f”(agent: {a.get(‘agent’, {}).get(‘name’, ‘?’)})”
for a in alerts
])

prompt = f”””Esti un analist SOC senior. Analizeaza aceste alerte Wazuh din ultimele 24 ore.

{MITRE_CONTEXT}

Pentru fiecare grup de alerte similare, raspunde in acest format:

GRUP: <descriere scurta a grupului de alerte>
SEVERITATE_REALA: <Critica/Ridicata/Medie/Fals-pozitiv probabil>
TACTICA_MITRE: <tactica ATT&CK relevanta sau “N/A”>
NUMAR_ALERTE: <cate alerte fac parte din acest grup>
RECOMANDARE: <ce ar trebui sa faca analistul>

Grupeaza alertele similare impreuna. Prioritizeaza in raspuns grupurile cu severitate ridicata.
Raspunde DOAR in limba romana.

ALERTE:
{alerts_summary}
“””

response = ollama.chat(
model=MODEL,
messages=[{“role”: “user”, “content”: prompt}]
)
return response[“message”][“content”]

Script principal de rulare
Salvează ca run_triage.py:

# ============================================================
# AI SIEM Triage – Wazuh + Ollama
# Autor: Claudiu Ceausescu
# ============================================================

from datetime import datetime
from wazuh_client import get_auth_token, get_recent_alerts
from ai_triage import group_and_triage_alerts
from colorama import Fore, init

init(autoreset=True)

def main():
print(Fore.CYAN + “Conectare la Wazuh API…”)
token = get_auth_token()

print(Fore.CYAN + “Extragere alerte din ultimele 24 ore…”)
alerts = get_recent_alerts(token, hours=24, limit=200)

if not alerts:
print(Fore.YELLOW + “Nu exista alerte noi.”)
return

print(Fore.CYAN + f”Gasit {len(alerts)} alerte. Trimit spre analiza AI…\n”)
report = group_and_triage_alerts(alerts)

timestamp = datetime.now().strftime(“%Y-%m-%d_%H-%M”)
report_file = f”C:\\SOC_Reports\\Triage_{timestamp}.txt”

with open(report_file, “w”, encoding=”utf-8″) as f:
f.write(f”RAPORT TRIAJ AI – {datetime.now().strftime(‘%d.%m.%Y %H:%M’)}\n”)
f.write(“=” * 60 + “\n\n”)
f.write(report)

print(Fore.GREEN + f”\n[DONE] Raport salvat: {report_file}”)
print(Fore.GREEN + f”Alerte procesate: {len(alerts)}”)

if __name__ == “__main__”:
main()

Rulare și programare automată:

# Creeaza folderul de rapoarte
New-Item -ItemType Directory -Force -Path “C:\SOC_Reports”

# Ruleaza manual
python run_triage.py

# Programeaza rulare la fiecare 6 ore
$Action = New-ScheduledTaskAction -Execute “python” -Argument “run_triage.py” `
-WorkingDirectory “C:\SOC_Triage”
$Trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) `
-RepetitionInterval (New-TimeSpan -Hours 6) `
-RepetitionDuration (New-TimeSpan -Days 3650)
Register-ScheduledTask -TaskName “AI_SIEM_Triage” `
-Action $Action -Trigger $Trigger -RunLevel Highest

Tip solutie

Permanent

Voteaza

(12 din 17 persoane apreciaza acest articol)

Despre Autor

Leave A Comment?