Detectare asistată de AI: LLM pentru generarea regulilor Sigma
Integrarea modelelor de limbaj mari în ingineria de detecție reprezintă una dintre cele mai radicale schimbări în peisajul SOC din ultimii ani. Nu este vorba doar de automatizarea unei sarcini repetitive: folosirea unui LLM pentru a genera reguli Sigma înseamnă comprimarea unui proces în secunde care un analist expert finalizează în câteva ore, de la citirea unui raport de amenințare până la scrierea unei reguli testate gata de implementare.
Cadre ca SigmaGen, prezentate la MITRE ATT&CK APAC 2025, demonstrează modul în care modelele ajustate pot ingera rapoarte de informații despre amenințări, extrage tehnici ATT&CK și produc reguli Sigma mapate de înaltă precizie. În același timp, instrumente open-source și Fluxurile de lucru bazate pe n8n permit echipelor mai mici să construiască conducte asistate de AI fără investiții ale întreprinderii.
Acest articol vă ghidează prin arhitectura unui sistem asistat de inteligență artificială pentru generarea de reguli de detectare: din promptul de inginerie, la validarea automată, testarea cu loguri sintetice, la integrarea într-o conductă CI/CD existentă.
Ce vei învăța
- Cum cred LLM-urile despre formatul Sigma și de ce produc rezultate mai bune decât SPL direct
- Tehnici specifice de inginerie promptă pentru generarea regulilor de detectare
- Arhitectura unei conducte end-to-end asistate de AI
- Validarea și testarea automată a regulilor generate
- Integrare cu fluxul de lucru SigmaGen, pySigma și CI/CD
- Anti-modele de evitat și limitele reale ale LLM-urilor în contexte de securitate
de ce LLM excelează la generarea regulilor Sigma
Una dintre cele mai interesante observații care a apărut din cercetarea aplicată (și confirmată de practică) este că LLM-urile produc rezultate de calitate. semnificativ mai mare atunci când generează Sigma comparativ cu interogările directe SPL sau KQL. Motivul este structural.
Formatul YAML al Sigma impune o separare clară între:
- titlu și descriere: Modelul trebuie să articuleze ce detectează și de ce
- sursă de jurnal: specifică sursa de date (categorie, produs, serviciu)
- detectare: logica de potrivire booleană
- stare: Cum să combinați selectoarele
- falspozitive: Raționament explicit asupra cazurilor marginale
Această structură obligă modelul să „gândească” secvenţial şi declarativ, reducând erorile logice care apar atunci când solicită direct rezultate într-un limbaj de interogare specific platformei. În practică, Sigma funcționează ca un lanțul-gândirii implicite pentru LLM aplicate detectării.
Date de referință
Cercetătorii din proiectul LLMCloudHunter (2024) au demonstrat că LLM-urile generaliste precum GPT-4 generează reguli Sigma care sunt valabile în 73% din cazuri. pe rapoartele CTI structurate, față de 41% atunci când se solicită rezultate directe SPL. Procentul crește la 89% cu reglaj fin pe seturile de date specificatii de siguranta.
Arhitectura unei conducte asistate de AI
O conductă asistată de IA pentru generarea regulilor de detectare constă din cinci etape distincte:
- Ingestie: asimilarea de rapoarte de amenințări, postări de blog CTI, aviz CVE
- Extracţie: extracție IOC, tehnici ATT&CK, comportamente descrise
- Generaţie: generarea regulii Sigma prin LLM
- Validare: validare automată sintactică și semantică
- Testare: Testare cu loguri sintetice și integrare CI/CD
# Architettura base della pipeline AI-assisted
# File: ai_sigma_pipeline.py
import openai
import yaml
import subprocess
from pathlib import Path
from dataclasses import dataclass
from typing import Optional
@dataclass
class ThreatReport:
content: str
source_url: str
report_type: str # 'cti_blog', 'advisory', 'malware_analysis'
@dataclass
class GeneratedRule:
sigma_yaml: str
mitre_techniques: list[str]
confidence: float
validation_passed: bool
test_results: Optional[dict] = None
class AISigmaPipeline:
def __init__(self, openai_api_key: str, rules_output_dir: str):
self.client = openai.OpenAI(api_key=openai_api_key)
self.output_dir = Path(rules_output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
def process_report(self, report: ThreatReport) -> list[GeneratedRule]:
"""Pipeline completa da report a regole validate."""
# Stage 1: Extraction
techniques = self._extract_attack_techniques(report)
behaviors = self._extract_behaviors(report)
# Stage 2: Generation
rules = []
for technique in techniques:
rule = self._generate_sigma_rule(
report=report,
technique=technique,
behaviors=behaviors
)
if rule:
rules.append(rule)
# Stage 3: Validation + Testing
return [self._validate_and_test(r) for r in rules]
def _extract_attack_techniques(self, report: ThreatReport) -> list[str]:
"""Estrae tecniche ATT&CK dal report tramite LLM."""
response = self.client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
"Sei un analista di threat intelligence esperto in MITRE ATT&CK. "
"Estrai SOLO le tecniche ATT&CK (formato T1234 o T1234.001) "
"esplicitamente descritte nel testo. Rispondi solo con una lista JSON."
)
},
{
"role": "user",
"content": f"Report:\n{report.content[:4000]}"
}
],
temperature=0.1 # Bassa temperatura per output deterministico
)
import json
try:
return json.loads(response.choices[0].message.content)
except json.JSONDecodeError:
return []
Inginerie promptă pentru Reguli Sigma de calitate
Calitatea rezultatelor depinde în mod critic de structura promptă. Există trei modele de bază care produc rezultate constând din generarea regulilor Sigma:
Model 1: Structured System Prompt
Promptul sistemului trebuie să conțină exact meta-informațiile de care modelul are nevoie pentru a genera Sigma valide:
structura YAML, valorile valide pentru category e product, cele mai bune practici pe
falsepositives și nivelurile de severitate permise.
# Prompt di sistema ottimizzato per generazione Sigma rules
SIGMA_SYSTEM_PROMPT = """
Sei un Detection Engineer esperto nella scrittura di Sigma rules.
Quando generi una Sigma rule, rispetta SEMPRE questa struttura YAML:
title: [titolo descrittivo, max 80 char]
id: [UUID v4]
status: experimental
description: [descrizione dettagliata del comportamento rilevato]
references:
- [URL del report originale se disponibile]
author: AI-Assisted Detection
date: [data odierna in formato YYYY-MM-DD]
tags:
- attack.[tattica]
- attack.[tecnica]
logsource:
category: [process_creation | network_connection | file_event | registry_event]
product: [windows | linux | macos]
detection:
[nome_selettore]:
[campo]: [valore o lista valori]
condition: [nome_selettore]
falsepositives:
- [casi legittimi plausibili]
level: [informational | low | medium | high | critical]
REGOLE CRITICHE:
- Usa SEMPRE wildcards (*) nei valori stringa per evitare match esatti fragili
- Preferisci campi con alta disponibilità (Image, CommandLine, ParentImage)
- Indica sempre almeno un falso positivo realistico
- Il campo 'condition' deve essere semplice e leggibile
- Non usare regex complesse se un approccio con keywords e sufficiente
"""
def build_generation_prompt(technique_id: str, behaviors: list[str],
logsource_hint: str, report_excerpt: str) -> str:
return f"""Genera una Sigma rule per rilevare la tecnica MITRE ATT&CK {technique_id}.
Comportamenti osservati nel report:
{chr(10).join(f'- {b}' for b in behaviors[:5])}
Tipo di log suggerito: {logsource_hint}
Estratto del report originale:
{report_excerpt[:1500]}
Genera UNA SOLA Sigma rule in formato YAML valido. Non aggiungere spiegazioni fuori dal YAML."""
Modelul 2: Câțiva fotografii cu exemple de calitate
Includerea a 2-3 exemple de reguli de înaltă calitate în prompt (few-shot) îmbunătățește dramatic consistența rezultatelor, mai ales pentru surse de jurnal neobișnuite sau condiții complexe.
# Few-shot: esempio di regola di qualità inclusa nel prompt
FEW_SHOT_EXAMPLE = """
Esempio di regola di alta qualità per ispirazione:
title: Suspicious PowerShell Encoded Command Execution
id: 5b4f6d89-1234-4321-ab12-fedcba987654
status: stable
description: >
Rileva l'esecuzione di PowerShell con parametri di encoding (-enc, -EncodedCommand)
frequentemente usati da malware per offuscare payload malevoli.
references:
- https://attack.mitre.org/techniques/T1059/001/
author: SigmaHQ Community
date: 2025-01-15
tags:
- attack.execution
- attack.t1059.001
logsource:
category: process_creation
product: windows
detection:
selection:
Image|endswith:
- '\\\\powershell.exe'
- '\\\\pwsh.exe'
CommandLine|contains:
- ' -enc '
- ' -EncodedCommand '
- ' -ec '
condition: selection
falsepositives:
- Software legittimo che usa PowerShell con encoding per configurazioni complesse
- Script di deployment enterprise
level: medium
"""
Modelul 3: Lanțul de gândire explicit
Pentru tehnici complexe, solicitarea modelului să raționeze înainte de a scrie regula produce rezultate mai precise. Această abordare adaugă latență, dar reduce semnificativ numărul de iterații necesare.
def generate_with_cot(self, technique_id: str, report: ThreatReport) -> GeneratedRule:
"""Generazione con Chain-of-Thought esplicito."""
# Step 1: Chiedi al modello di ragionare
reasoning_response = self.client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SIGMA_SYSTEM_PROMPT},
{
"role": "user",
"content": f"""Prima di scrivere la regola per {technique_id}, analizza:
1. Quali artefatti forensi questa tecnica lascia nei log?
2. Qual è il logsource più appropriato?
3. Quali campi hanno la maggiore discriminazione signal/noise?
4. Quali sono i falsi positivi più comuni?
Report: {report.content[:2000]}"""
}
],
temperature=0.3
)
reasoning = reasoning_response.choices[0].message.content
# Step 2: Usa il ragionamento per guidare la generazione
rule_response = self.client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SIGMA_SYSTEM_PROMPT},
{"role": "user", "content": f"Analisi tecnica:\n{reasoning}"},
{
"role": "assistant",
"content": "Basandomi su questa analisi, genero la Sigma rule ottimale:"
},
{"role": "user", "content": "Procedi con la generazione YAML."}
],
temperature=0.1
)
return GeneratedRule(
sigma_yaml=rule_response.choices[0].message.content,
mitre_techniques=[technique_id],
confidence=0.0, # Calcolata nella validazione
validation_passed=False
)
Validarea automată a regulilor generate
Un LLM poate produce YAML valid din punct de vedere sintactic, dar incorect din punct de vedere semantic: o sursă de jurnal inexistentă, câmp denumit greșit, o condiție care nu face referire corect la selectori. Validare automată și poarta critică înainte ca o regulă să intre în depozit.
import yaml
from sigma.rule import SigmaRule
from sigma.exceptions import SigmaError
import re
import uuid
class SigmaRuleValidator:
# Logsource validi più comuni
VALID_CATEGORIES = {
'process_creation', 'network_connection', 'file_event',
'registry_event', 'registry_add', 'registry_set',
'dns_query', 'image_load', 'pipe_created', 'raw_access_read'
}
VALID_LEVELS = {'informational', 'low', 'medium', 'high', 'critical'}
VALID_STATUSES = {'stable', 'test', 'experimental', 'deprecated', 'unsupported'}
def validate(self, sigma_yaml: str) -> tuple[bool, list[str]]:
"""Valida una Sigma rule. Restituisce (valida, lista errori)."""
errors = []
# 1. Validazione YAML sintattico
try:
rule_dict = yaml.safe_load(sigma_yaml)
except yaml.YAMLError as e:
return False, [f"YAML invalido: {str(e)}"]
# 2. Campi obbligatori
required_fields = ['title', 'description', 'logsource', 'detection']
for field in required_fields:
if field not in rule_dict:
errors.append(f"Campo obbligatorio mancante: {field}")
if errors:
return False, errors
# 3. Validazione logsource
logsource = rule_dict.get('logsource', {})
if 'category' in logsource:
if logsource['category'] not in self.VALID_CATEGORIES:
errors.append(
f"Categoria logsource non valida: {logsource['category']}. "
f"Valide: {', '.join(self.VALID_CATEGORIES)}"
)
# 4. Validazione detection
detection = rule_dict.get('detection', {})
if 'condition' not in detection:
errors.append("Campo 'condition' mancante in detection")
else:
condition = detection['condition']
# Verifica che i selettori nella condition esistano
selectors = [k for k in detection.keys() if k != 'condition']
# Parse base della condition per trovare riferimenti
referenced = re.findall(r'\b([a-zA-Z_][a-zA-Z0-9_]*)\b', condition)
for ref in referenced:
if ref not in ['and', 'or', 'not', '1', 'of', 'all', 'them', 'filter']:
if ref not in selectors:
errors.append(
f"Condition referenzia '{ref}' che non esiste nei selettori: {selectors}"
)
# 5. Validazione level
level = rule_dict.get('level', '')
if level and level not in self.VALID_LEVELS:
errors.append(f"Level non valido: {level}. Validi: {self.VALID_LEVELS}")
# 6. UUID check
rule_id = rule_dict.get('id', '')
if rule_id:
try:
uuid.UUID(str(rule_id))
except ValueError:
errors.append(f"ID non e un UUID valido: {rule_id}")
else:
errors.append("Campo 'id' mancante - genera un UUID v4")
# 7. Validazione pySigma (se disponibile)
try:
SigmaRule.from_yaml(sigma_yaml)
except SigmaError as e:
errors.append(f"Errore pySigma: {str(e)}")
return len(errors) == 0, errors
Anti-Pattern: Încredere oarbă în rezultatul LLM
O greșeală comună la echipele care implementează detectarea asistată de AI este implementarea regulilor generate fără validare. LLM-urile fac greșeli specifice și repetabile în generarea Sigma:
- Utilizați câmpuri
ProcessNameîn loc deImage(Sysmon) - Scrieți condiții care fac referire la selectori inexistenți
- Inventează categorii non-standard de surse de jurnal
- Utilizare
containspe câmpurile care nu acceptă metacaracterele în sursa de jurnal țintă
Validarea automată și testarea cu jurnalele reale NU SUNT OPȚIONALE.
Testare automată cu jurnalele sintetice
După validarea sintactică, fiecare regulă trebuie testată pe jurnalele care simulează ambele comportamente trafic rău așteptat (test adevărat pozitiv) decât traficul normal (test fals pozitiv). Această abordare, numit testarea unitară a regulilor, și practica care distinge o conductă matură de a experiment.
import json
from sigma.collection import SigmaCollection
from sigma.backends.test import TextQueryTestBackend
from typing import Any
class SigmaRuleTester:
def __init__(self):
self.backend = TextQueryTestBackend()
def generate_test_events(self, sigma_yaml: str,
llm_client) -> dict[str, list[dict]]:
"""Genera eventi di test tramite LLM basandosi sulla regola."""
rule_dict = yaml.safe_load(sigma_yaml)
prompt = f"""Data questa Sigma rule:
{sigma_yaml}
Genera in formato JSON due liste di eventi di log:
1. "true_positives": 3 eventi che DEVONO triggherare la regola
2. "false_positives": 3 eventi legittimi che NON devono triggherare la regola
Ogni evento deve avere i campi esatti che la regola usa per il matching.
Formato richiesto:
{
"true_positives": [
{"Image": "C:\\\\Windows\\\\System32\\\\cmd.exe", "CommandLine": "...", ...}
],
"false_positives": [
{"Image": "C:\\\\Program Files\\\\...", "CommandLine": "...", ...}
]
}"""
response = llm_client.chat.completions.create(
model="gpt-4o-mini", # Modello più economico per i test
messages=[{"role": "user", "content": prompt}],
temperature=0.2
)
try:
return json.loads(response.choices[0].message.content)
except json.JSONDecodeError:
return {"true_positives": [], "false_positives": []}
def run_tests(self, sigma_yaml: str, test_events: dict) -> dict[str, Any]:
"""Esegue i test e restituisce risultati dettagliati."""
results = {
"tp_tests": {"passed": 0, "failed": 0, "details": []},
"fp_tests": {"passed": 0, "failed": 0, "details": []},
"overall_pass": False
}
# Nota: questa e una simulazione del meccanismo di test.
# In produzione si usano tool come sigma-test o un SIEM sandbox.
rule_dict = yaml.safe_load(sigma_yaml)
detection = rule_dict.get('detection', {})
for event in test_events.get('true_positives', []):
matched = self._simulate_match(event, detection)
if matched:
results["tp_tests"]["passed"] += 1
results["tp_tests"]["details"].append({"event": event, "result": "PASS"})
else:
results["tp_tests"]["failed"] += 1
results["tp_tests"]["details"].append({"event": event, "result": "FAIL - non matchato"})
for event in test_events.get('false_positives', []):
matched = self._simulate_match(event, detection)
if not matched:
results["fp_tests"]["passed"] += 1
results["fp_tests"]["details"].append({"event": event, "result": "PASS"})
else:
results["fp_tests"]["failed"] += 1
results["fp_tests"]["details"].append({"event": event, "result": "FAIL - falso positivo"})
tp_ok = results["tp_tests"]["failed"] == 0
fp_ok = results["fp_tests"]["failed"] == 0
results["overall_pass"] = tp_ok and fp_ok
return results
def _simulate_match(self, event: dict, detection: dict) -> bool:
"""Simulazione semplificata del match. Per produzione: usa sigma-test."""
# Logica di matching semplificata per demo
for selector_name, selector_criteria in detection.items():
if selector_name == 'condition':
continue
if not isinstance(selector_criteria, dict):
continue
for field, value in selector_criteria.items():
actual_field = field.split('|')[0]
modifier = field.split('|')[1] if '|' in field else 'exact'
event_value = event.get(actual_field, '')
if isinstance(value, list):
for v in value:
if self._apply_modifier(str(event_value), str(v), modifier):
return True
else:
if self._apply_modifier(str(event_value), str(value), modifier):
return True
return False
def _apply_modifier(self, event_val: str, pattern: str, modifier: str) -> bool:
pattern_clean = pattern.replace('*', '')
if modifier == 'contains':
return pattern_clean.lower() in event_val.lower()
elif modifier == 'endswith':
return event_val.lower().endswith(pattern_clean.lower())
elif modifier == 'startswith':
return event_val.lower().startswith(pattern_clean.lower())
return event_val.lower() == pattern_clean.lower()
SigmaGen: Cadrul open-source pentru detectarea asistată de AI
SigmaGen, prezentat la MITRE ATT&CK APAC 2025, reprezintă stadiul tehnicii în cadre sursă deschisă pentru generarea AI de reguli de detectare. Proiectul combină reglarea fină a seturilor de date organizate cu o arhitectură pipeline care acoperă întregul ciclu de viață al regulii.
# Integrazione con SigmaGen (workflow concettuale)
# SigmaGen usa un approccio in tre fasi:
# 1. Ingestion di CTI (blog, advisory, STIX feeds)
# 2. Extraction di tecniche ATT&CK tramite NER specializzato
# 3. Generazione Sigma tramite modello fine-tuned
# Workflow alternativo con n8n e LLM generici:
# n8n Workflow JSON (estratto concettuale)
N8N_WORKFLOW_STRUCTURE = {
"nodes": [
{
"name": "RSS_CTI_Feed",
"type": "n8n-nodes-base.rssFeedRead",
"parameters": {
"url": "https://example-cti-blog.com/feed.xml"
}
},
{
"name": "Extract_Techniques",
"type": "n8n-nodes-base.openAi",
"parameters": {
"model": "gpt-4o",
"prompt": "Estrai tecniche ATT&CK da: {{$json.content}}",
"system_prompt": "Sei un analista CTI esperto..."
}
},
{
"name": "Generate_Sigma",
"type": "n8n-nodes-base.openAi",
"parameters": {
"model": "gpt-4o",
"prompt": "Genera Sigma rule per: {{$json.techniques}}",
"system_prompt": SIGMA_SYSTEM_PROMPT
}
},
{
"name": "Validate_Rule",
"type": "n8n-nodes-base.code",
"parameters": {
"code": "// Chiama API di validazione Python"
}
},
{
"name": "GitHub_PR",
"type": "n8n-nodes-base.github",
"parameters": {
"operation": "createPullRequest",
"repository": "org/detection-rules"
}
}
]
}
# Pipeline Python completa con gestione errori
class FullAISigmaPipeline:
def __init__(self, config: dict):
self.llm_client = openai.OpenAI(api_key=config['openai_key'])
self.validator = SigmaRuleValidator()
self.tester = SigmaRuleTester()
self.max_retries = config.get('max_retries', 3)
def generate_validated_rule(self, technique_id: str,
report: ThreatReport) -> Optional[GeneratedRule]:
"""Genera, valida e testa una regola con retry automatico."""
errors_history = []
for attempt in range(self.max_retries):
# Genera la regola (con errori precedenti nel prompt se disponibili)
sigma_yaml = self._generate_with_error_feedback(
technique_id, report, errors_history
)
# Valida
is_valid, errors = self.validator.validate(sigma_yaml)
if not is_valid:
errors_history.extend(errors)
continue
# Test con eventi sintetici
test_events = self.tester.generate_test_events(sigma_yaml, self.llm_client)
test_results = self.tester.run_tests(sigma_yaml, test_events)
if test_results['overall_pass']:
return GeneratedRule(
sigma_yaml=sigma_yaml,
mitre_techniques=[technique_id],
confidence=self._calculate_confidence(test_results),
validation_passed=True,
test_results=test_results
)
else:
errors_history.append(f"Test falliti: {test_results}")
return None # Non e riuscito a generare una regola valida
def _generate_with_error_feedback(self, technique_id: str,
report: ThreatReport,
errors: list[str]) -> str:
"""Genera con feedback sugli errori precedenti."""
error_context = ""
if errors:
error_context = f"\n\nTentativo precedente fallito con errori:\n" + \
"\n".join(f"- {e}" for e in errors[-3:]) # Ultimi 3 errori
prompt = build_generation_prompt(
technique_id=technique_id,
behaviors=[],
logsource_hint="process_creation",
report_excerpt=report.content[:2000] + error_context
)
response = self.llm_client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SIGMA_SYSTEM_PROMPT},
{"role": "user", "content": prompt}
],
temperature=0.1
)
return response.choices[0].message.content
def _calculate_confidence(self, test_results: dict) -> float:
"""Calcola un confidence score basato sui test."""
tp = test_results["tp_tests"]
fp = test_results["fp_tests"]
total_tp = tp["passed"] + tp["failed"]
total_fp = fp["passed"] + fp["failed"]
if total_tp == 0 or total_fp == 0:
return 0.5
tp_rate = tp["passed"] / total_tp
fp_ok_rate = fp["passed"] / total_fp
return (tp_rate + fp_ok_rate) / 2
Integrarea în conducta CI/CD
Regulile generate și validate nu intră automat în producție: ele trebuie să treacă prin proces de revizuire umană și porțile CI/CD ale conductei Detection-as-Code. Fluxul recomandat este acel AI generați o cerere de tragere, nu o îmbinare directă.
# GitHub Actions workflow per AI-generated rules
# File: .github/workflows/ai-sigma-generation.yml
"""
name: AI Sigma Rule Generation
on:
schedule:
- cron: '0 6 * * *' # Ogni giorno alle 6:00 UTC
workflow_dispatch:
inputs:
cti_url:
description: 'URL del CTI report da processare'
required: false
jobs:
generate-rules:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install openai pySigma pySigma-backend-splunk pyyaml
- name: Run AI pipeline
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: python scripts/ai_sigma_pipeline.py
- name: Validate generated rules
run: python scripts/validate_all_rules.py rules/ai-generated/
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
title: '[AI-Generated] Detection rules da CTI feed'
body: |
## Regole generate automaticamente da AI
Tecniche ATT&CK rilevate e tradotte in Sigma rules.
**REVIEW OBBLIGATORIA** - Verificare prima del merge:
- [ ] Logsource corretto per il SIEM target
- [ ] Condition logicamente corretta
- [ ] Falsi positivi accettabili
- [ ] Test su ambiente staging completato
labels: 'ai-generated,needs-review'
branch: 'ai-generated-rules'
"""
# Script di validazione bulk
# File: scripts/validate_all_rules.py
import sys
from pathlib import Path
def validate_directory(rules_dir: str) -> int:
"""Valida tutte le regole in una directory. Restituisce exit code."""
validator = SigmaRuleValidator()
rules_path = Path(rules_dir)
failed = []
for rule_file in rules_path.glob("**/*.yml"):
content = rule_file.read_text()
is_valid, errors = validator.validate(content)
if not is_valid:
failed.append((rule_file.name, errors))
print(f"FAIL: {rule_file.name}")
for e in errors:
print(f" - {e}")
else:
print(f"OK: {rule_file.name}")
print(f"\nRisultati: {len(failed)} fallite su {len(list(rules_path.glob('**/*.yml')))} totali")
return 1 if failed else 0
if __name__ == "__main__":
sys.exit(validate_directory(sys.argv[1] if len(sys.argv) > 1 else "rules/"))
Modele alternative și considerații de cost
Nu toate organizațiile pot sau doresc să trimită date sensibile CTI către API-urile cloud. Utilizarea șabloanelor sediul prin Ollama o vLLM și o alternativă concretă pentru medii cu cerințe de rezidență a datelor.
| Model | Calitate Sigma | Cost pe 100 de reguli | Latență medie | Data rezidenței |
|---|---|---|---|---|
| GPT-4o | Ridicat (87% valabil) | ~2,50 USD | 3-8s | Cloud (OpenAI) |
| GPT-4o-mini | Bun (71% valabil) | ~0,15 USD | 1-3s | Cloud (OpenAI) |
| Claude 3.5 Sonete | Ridicat (84% valabil) | ~3,00 USD | 3-6s | Nor (antropic) |
| Llama 3.1 70B (local) | Corect (58% valabil) | ~$0 (mai jos) | 15-45s | On-premise |
| Mistral 7B reglat fin | Bun (69% valabil) | ~$0 (mai jos) | 5-15s | On-premise |
Strategie rentabilă
Utilizați GPT-4o-mini pentru generarea inițială și reîncercați iterațiile (cost redus, calitate bună), și GPT-4o numai pentru cazurile în care mini eșuează după 2 încercări. Cu această abordare hibridă, costul mediu scade la 30% în comparație cu utilizarea exclusivă a GPT-4o, menținând în același timp o calitate comparabilă.
Limite reale și anti-modele
Sinceritatea este fundamentală în evaluarea acestei tehnologii. LLM-urile nu sunt infailibile în generarea de reguli de detectare, iar cunoașterea limitărilor acestora este la fel de importantă ca și exploatarea lor punctele forte.
Limitări documentate ale LLM-urilor pentru ingineria detectării
-
Halucinația câmpurilor: Modelul poate inventa nume de câmpuri care nu există
în jurnalele reale (de ex.
ProcessHashîn loc deHashesîn Sysmon). - Supraajustarea raportului: regulile generate pot fi prea specifice (pe baza IOC) în loc să surprindă comportamentul general.
- False pozitive nerealiste: „Falsepozitivele” generate de LLM sunt adesea generice și nu reprezintă cazuri reale în contextul specific al organizației.
- Tehnici întunecate: Pentru tehnici ATT&CK rare sau foarte recente (post-cutoff), calitatea se degradează semnificativ fără o recuperare crescută.
- Lipsa contextului SIEM: Modelul nu cunoaște normalizarea specifică ale SIEM-ului dvs. (de exemplu, modul în care Splunk normalizează câmpurile Windows în comparație cu Elastic ECS).
RAG pentru SIEM specific contextului
Retrieval Augmented Generation (RAG) vă permite să injectați context specific organizației în prompt: normalizarea câmpurilor SIEM, regulile existente, datele de calibrare fals pozitive. Această abordare reduce semnificativ erorile legate de lipsa contextului.
# RAG per generazione Sigma contestualizzata
from chromadb import Client
from chromadb.utils import embedding_functions
class RAGSigmaGenerator:
def __init__(self, chroma_persist_dir: str, openai_key: str):
self.chroma_client = Client()
self.embed_fn = embedding_functions.OpenAIEmbeddingFunction(
api_key=openai_key,
model_name="text-embedding-3-small"
)
# Collection di regole esistenti per few-shot contestuale
self.rules_collection = self.chroma_client.get_or_create_collection(
name="sigma_rules",
embedding_function=self.embed_fn
)
# Collection di field mappings SIEM-specifici
self.field_mappings_collection = self.chroma_client.get_or_create_collection(
name="siem_field_mappings",
embedding_function=self.embed_fn
)
def index_existing_rules(self, rules_dir: str) -> None:
"""Indicizza le regole esistenti per few-shot retrieval."""
for rule_file in Path(rules_dir).glob("**/*.yml"):
content = rule_file.read_text()
rule_dict = yaml.safe_load(content)
self.rules_collection.add(
documents=[content],
metadatas=[{
"title": rule_dict.get('title', ''),
"category": rule_dict.get('logsource', {}).get('category', ''),
"tags": str(rule_dict.get('tags', []))
}],
ids=[str(rule_file)]
)
def generate_with_rag(self, technique_id: str, report: ThreatReport) -> str:
"""Genera Sigma rule con contesto recuperato dal RAG."""
# Recupera regole simili come few-shot examples
similar_rules = self.rules_collection.query(
query_texts=[report.content[:500]],
n_results=3
)
# Recupera field mappings SIEM-specifici
field_mappings = self.field_mappings_collection.query(
query_texts=[f"process_creation windows {technique_id}"],
n_results=2
)
# Costruisce prompt arricchito con contesto RAG
context = "\n\n".join(similar_rules['documents'][0][:2])
mappings_context = "\n".join(field_mappings['documents'][0])
enhanced_prompt = f"""
Regole simili esistenti nel nostro repository (usa come ispirazione):
{context}
Field mappings specifici del nostro SIEM:
{mappings_context}
Ora genera una nuova regola per la tecnica {technique_id}
basandoti sul seguente report: {report.content[:2000]}
"""
# Continua con la generazione standard...
return enhanced_prompt
Concluzii și pașii următori
Ingineria de detecție asistată de AI nu este o tendință: este o necesitate operațională pentru echipele care trebuie să ține pasul cu viteza cu care apar noile tehnici de atac. Combinația de LLM pentru generare, validarea automată riguroasă și testarea cu jurnalele sintetice permite reduceți timpul de detectare de la zile la ore pe un raport de amenințare recent publicat.
Recomandări cheie
- LLM-urile produc reguli Sigma de calitate superioară decât interogările directe SPL datorită structurii YAML
- Inginerie promptă (prompt de sistem structurat, câteva lovituri, lanț de gândire) este crucială pentru calitate
- Validarea automată sintactică și semantică nu este opțională
- Testarea cu jurnalele sintetice generate de AI închide bucla de calitate
- Regulile generate trebuie să treacă prin revizuirea PR umană, nu prin fuziune automată
- RAG specific contextului SIEM reduce erorile de câmp și falsele pozitive
- Modelele locale (Llama, Mistral fine-tuned) sunt o alternativă validă pentru rezidența datelor
Articole înrudite
- Reguli Sigma: Logica de detectare universală și conversie SIEM
- Pipeline Detection-as-Code cu Git și CI/CD
- Reguli de detectare a testării: Testarea unitară pentru logica de securitate
- Ingestia de informații despre amenințări: STIX/TAXII Feed Processor







