Sigma Rules: Logica di Detection Universale e Conversione SIEM
Nel mondo della cybersecurity difensiva, uno dei problemi più persistenti e sempre stato la frammentazione dei linguaggi di detection: ogni SIEM ha la sua sintassi proprietaria, ogni piattaforma richiede query diverse, e le regole scritte per Splunk non funzionano su Elastic, che a sua volta non e compatibile con Microsoft Sentinel. Il risultato e che i team SOC spendono enormi quantità di tempo a riscrivere le stesse logiche di rilevamento per ogni tool, anziche concentrarsi su ciò che conta davvero: trovare le minacce prima che causino danni.
Le Sigma rules nascono esattamente per risolvere questo problema. Introdotte da Florian Roth e Thomas Patzke, Sigma e oggi il formato standard de facto per scrivere regole di detection in modo portabile e indipendente dalla piattaforma. Una regola Sigma scritta una volta può essere automaticamente convertita in query Splunk SPL, Elasticsearch KQL, Microsoft Sentinel KQL, IBM QRadar, Chronicle YARA-L, e oltre 40 altri target. In questo articolo esploriamo la sintassi Sigma in profondi, i pattern di logsource mapping, le tecniche di modifica e conversione, e come integrare Sigma in una pipeline Detection-as-Code moderna.
Cosa Imparerai in Questo Articolo
- Struttura completa di una Sigma rule: titolo, logsource, detection, condition
- Logsource mapping: category, product, service e come si traducono nei SIEM
- Modifiers avanzati: contains, startswith, endswith, re, base64offset
- Aggregation conditions: count, sum, min, max per detection statistiche
- Conversione automatica con sigma-cli verso Splunk, Elastic e Sentinel
- Pattern per detection di lateral movement, persistence, exfiltration
- Testing e validazione delle regole Sigma con dati sintetici
- Gestione del repository Sigma aziendale con best practices
Cos'è Sigma e perchè e Diventato lo Standard
Sigma e un formato open, basato su YAML, per descrivere pattern di rilevamento su log di sicurezza in modo indipendente dalla piattaforma. Pensalo come YARA per i log: cosi come YARA permette di scrivere regole per file malevoli che funzionano su qualsiasi scanner, Sigma permette di scrivere regole di detection che funzionano su qualsiasi SIEM.
Il progetto SigmaHQ ospita oggi oltre 3.000 regole community coperte da continua manutenzione, mappate al framework MITRE ATT&CK, e pronte per essere convertite. La crescita e stata esplosiva: da strumento di nicchia per threat hunters, Sigma e diventato il linguaggio comune dei detection engineers professionisti. I vantaggi principali sono tre:
- Portabilita: scrivi una regola, deployala su N SIEM diversi
- Collaborazione: le regole sono leggibili da chiunque, indipendentemente dal SIEM in uso
- Automazione: la conversione e completamente automatizzabile in CI/CD
Anatomia di una Sigma Rule
Una regola Sigma e un file YAML con campi ben definiti. Vediamo la struttura completa con un esempio reale che rileva l'uso di mimikatz attraverso Windows Event Logs:
title: Mimikatz Detection via Windows Security Events
id: 0d82df6e-0e4e-4fbb-a12b-6e7a00a9c7c3
status: stable
description: Detects mimikatz usage patterns via LSASS access events
and command-line indicators
references:
- https://github.com/gentilkiwi/mimikatz
- https://attack.mitre.org/techniques/T1003/001/
author: Federico Calo
date: 2026/03/01
modified: 2026/03/09
tags:
- attack.credential_access
- attack.t1003.001
- attack.defense_evasion
logsource:
category: process_access
product: windows
detection:
selection_lsass:
TargetImage|endswith: '\lsass.exe'
GrantedAccess|contains:
- '0x1010'
- '0x1038'
- '0x1400'
- '0x143a'
selection_mimikatz_cli:
CommandLine|contains|all:
- 'sekurlsa'
- 'logonpasswords'
filter_legitimate:
SourceImage|startswith:
- 'C:\Windows\System32\'
- 'C:\Program Files\Windows Defender\'
condition: (selection_lsass and not filter_legitimate) or selection_mimikatz_cli
falsepositives:
- Legitimate security tools performing LSASS inspection
- Antivirus and EDR solutions
level: high
Analizziamo ogni sezione nel dettaglio:
Campi Obbligatori e Metadati
Il blocco di metadati all'inizio della regola serve sia per documentazione che per automazione della gestione:
- title: nome leggibile della regola. Deve essere univoco e descrittivo. Convenzione: "Verbo + Soggetto + Contesto"
- id: UUID v4 univoco. Non cambia mai nel tempo, permette il tracking delle versioni e dei false positive reports
-
status: lifecycle della regola. I valori validi sono:
stable,test,experimental,deprecated,unsupported -
level: severita. Valori:
informational,low,medium,high,critical -
tags: lista di tag MITRE ATT&CK in formato
attack.t<ID>per tecniche oattack.<tactic>per tattiche
Logsource: il Cuore della Portabilita
Il blocco logsource e la magia che rende Sigma portabile. Invece di specificare un index o data stream specifico del SIEM, definisce il tipo di log in modo astratto attraverso tre campi:
# Esempio 1: Windows Security Events
logsource:
category: process_creation
product: windows
# Esempio 2: Linux Authentication
logsource:
category: process_creation
product: linux
# Esempio 3: Web Server Logs
logsource:
category: webserver
# nessun product specifico: generico
# Esempio 4: Log specifico di un servizio
logsource:
product: windows
service: security
# Esempio 5: Log di rete
logsource:
category: network_connection
product: windows
# Esempio 6: Cloud Trail
logsource:
product: aws
service: cloudtrail
Il sistema di pipeline di sigma-cli traduce questi logsource astratti nei
path concreti di ciascun SIEM. Per esempio, category: process_creation
su product: windows diventa:
| SIEM Target | Traduzione del Logsource |
|---|---|
| Splunk | source="WinEventLog:Security" EventCode=4688 |
| Elasticsearch (ECS) | event.category:process AND event.type:start |
| Microsoft Sentinel (KQL) | SecurityEvent | where EventID == 4688 |
| Chronicle (YARA-L) | $event.metadata.event_type = "PROCESS_LAUNCH" |
Detection: Selections e Conditions
Il blocco detection e dove si definisce la logica di rilevamento. Si compone di due parti: le selections (filtri sui campi dei log) e la condition (logica booleana che combina le selections).
detection:
# Selection con match esatto su campo singolo
selection_exact:
EventID: 4625
# Selection con lista di valori (OR implicito)
selection_multi_value:
CommandLine|contains:
- 'net user'
- 'net localgroup'
- 'whoami'
# Selection con match su tutti i valori (AND implicito con |all)
selection_and_all:
CommandLine|contains|all:
- '-enc'
- 'powershell'
# Selection con regex
selection_regex:
CommandLine|re: '(?i)(invoke-mimikatz|sekurlsa::)'
# Selection con wildcard
selection_wildcard:
TargetFilename|startswith: 'C:\Users\'
TargetFilename|endswith: '.exe'
# Filter per ridurre i falsi positivi
filter_system_processes:
ParentImage|startswith: 'C:\Windows\System32\'
# Condition: logica booleana
condition: selection_exact and (
selection_multi_value or selection_and_all
) and not filter_system_processes
Modifiers Avanzati
I modifiers sono suffissi che si aggiungono ai nomi dei campi
con il carattere pipe | per modificare il tipo di match.
Conoscerli tutti e fondamentale per scrivere regole efficaci:
| Modifier | Descrizione | Esempio |
|---|---|---|
contains |
Substring match (wildcard ai due lati) | CommandLine|contains: 'mimikatz' |
startswith |
Match all'inizio del valore | Image|startswith: 'C:\Users\' |
endswith |
Match alla fine del valore | Image|endswith: '\cmd.exe' |
re |
Regex PCRE | CommandLine|re: '(?i)sekurlsa' |
base64offset |
Decodifica base64 con offset 0,1,2 | CommandLine|base64offset|contains: 'IEX' |
wide |
Match su Unicode wide strings | CommandLine|wide|contains: 'sekurlsa' |
all |
Tutti i valori della lista devono matchare | CommandLine|contains|all: ['-enc', 'bypass'] |
windash |
Match sia con trattino che con slash | CommandLine|contains|windash: '-Enc' |
cidr |
Match su range CIDR per IP | DestinationIp|cidr: '10.0.0.0/8' |
lt, lte, gt, gte |
Comparazioni numeriche | EventID|gte: 4624 |
Aggregation Conditions: Detection Statistica
Alcune detection richiedono di contare eventi in un certo intervallo di tempo, non di matchare un singolo evento. Sigma supporta le aggregation conditions per questi casi d'uso:
# Rilevare brute force: più di 10 login falliti in 60 secondi
title: Windows Brute Force Login Attempt
logsource:
product: windows
service: security
detection:
selection:
EventID: 4625
LogonType: 3
condition: selection | count() > 10
timeframe: 60s
falsepositives:
- Users with expired passwords
level: medium
---
# Rilevare data exfiltration: upload anomalo per destinazione
title: Potential Data Exfiltration by Volume
logsource:
category: network_connection
product: windows
detection:
selection:
Initiated: 'true'
DestinationPort:
- 443
- 80
condition: selection | count(DestinationHostname) by SourceIp > 50
timeframe: 1h
level: high
---
# Port scan detection: molte porte diverse dallo stesso sorgente
title: Network Port Scan Detection
logsource:
category: network_connection
detection:
selection:
EventID: 5156
condition: selection | count(DestinationPort) by SourceAddress > 30
timeframe: 10m
level: medium
Conversione con sigma-cli: Guida Pratica
sigma-cli e lo strumento ufficiale per convertire le regole Sigma nei linguaggi di query dei SIEM. Installazione e uso di base:
# Installazione
pip install sigma-cli
pip install pySigma-backend-splunk
pip install pySigma-backend-elasticsearch
pip install pySigma-backend-microsoft365defender
# Verifica backend disponibili
sigma list backends
# Conversione base: Sigma -> Splunk SPL
sigma convert -t splunk -p splunk_windows rules/mimikatz.yml
# Output atteso:
# (source="WinEventLog:Microsoft-Windows-Sysmon/Operational"
# EventCode=10 TargetImage="*\\lsass.exe"
# GrantedAccess IN ("0x1010", "0x1038", "0x1400", "0x143a"))
# NOT (SourceImage="C:\\Windows\\System32\\*"
# OR SourceImage="C:\\Program Files\\Windows Defender\\*")
# Conversione con pipeline personalizzata
sigma convert \
-t splunk \
-p splunk_windows \
-p my_custom_field_mapping.yml \
rules/
# Conversione per Elasticsearch con ECS
sigma convert \
-t elasticsearch \
-p ecs_windows \
-f lucene \
rules/credential_access/
# Conversione per Microsoft Sentinel (KQL)
sigma convert \
-t microsoft365defender \
-p microsoft365defender \
rules/lateral_movement/
# Output in formato JSON per automazione
sigma convert \
-t splunk \
-p splunk_windows \
--format-output json \
rules/ > converted_rules.json
Attenzione: Pipeline e Field Mapping
Ogni organizzazione ha una propria normalizzazione dei log. Se i tuoi log non seguono lo schema standard (es. Sysmon per Windows), devi creare una pipeline personalizzata che mappa i campi Sigma ai campi reali del tuo SIEM. Senza questa mappatura, le regole convertite non funzioneranno.
Creare Pipeline Personalizzate
Le pipeline Sigma definiscono come mappare i campi astratti di Sigma ai campi concreti del tuo SIEM. Ecco come crearne una per un'infrastruttura che usa un formato di log custom:
# custom_pipeline.yml
name: Custom Windows Pipeline
priority: 20
transformations:
# Rinominare campo Sigma -> campo reale nel SIEM
- id: field_mapping_process
type: field_name_mapping
mapping:
CommandLine: process.command_line
Image: process.executable
ParentImage: process.parent.executable
User: user.name
TargetImage: target.process.executable
GrantedAccess: target.process.granted_access
rule_conditions:
- type: logsource
category: process_creation
# Aggiungere condizioni all'index di destinazione
- id: index_condition
type: detection_item_keyword
keyword: 'index=windows_events'
rule_conditions:
- type: logsource
product: windows
# Sostituire valori nei campi
- id: winlog_channel_map
type: field_value_mapping
field_name: winlog.channel
mapping:
'Security': 'security'
'System': 'system'
'Application': 'application'
Pattern di Detection per Casi d'Uso Comuni
Vediamo una raccolta di Sigma rules pronte per casi d'uso ad alta priorità, mappate alle tecniche MITRE ATT&CK più sfruttate:
Lateral Movement: Pass-the-Hash
title: Pass-the-Hash Attack Pattern
id: 6571d552-4c16-4f50-b5f6-11ae9d1b0a38
status: stable
description: Detects Pass-the-Hash attacks via anomalous NTLM authentication
tags:
- attack.lateral_movement
- attack.t1550.002
logsource:
product: windows
service: security
detection:
selection:
EventID: 4624
LogonType: 3
AuthenticationPackageName: NTLM
KeyLength: 0
filter_local:
IpAddress:
- '127.0.0.1'
- '::1'
filter_machine:
SubjectUserName|endswith: '$'
condition: selection and not filter_local and not filter_machine
falsepositives:
- NTLMv1 authentication in legacy environments
level: high
Persistence: Scheduled Task Creation
title: Suspicious Scheduled Task Creation via CLI
id: 92a7b4f1-e6c9-4e1d-b7df-3c8e9a0b5d17
status: stable
description: Detects creation of scheduled tasks via command line
tags:
- attack.persistence
- attack.t1053.005
logsource:
category: process_creation
product: windows
detection:
selection_schtasks:
Image|endswith: '\schtasks.exe'
CommandLine|contains|all:
- '/create'
- '/tr'
selection_suspicious_location:
CommandLine|contains:
- 'C:\Users\Public\'
- 'C:\ProgramData\'
- '%TEMP%'
- 'AppData\Local\Temp'
filter_admin_tools:
ParentImage|startswith:
- 'C:\Windows\System32\'
- 'C:\Program Files\Microsoft Deployment Toolkit\'
condition: selection_schtasks and selection_suspicious_location
and not filter_admin_tools
falsepositives:
- Software installers creating scheduled maintenance tasks
level: high
Exfiltration: DNS Tunneling
title: Potential DNS Tunneling via High Subdomain Count
id: b7c3a9f1-d4e5-4a7b-9f2c-8d0e1b3c5a7f
status: experimental
description: Detects potential DNS tunneling via unusually long DNS queries
or high number of unique subdomains
tags:
- attack.exfiltration
- attack.t1048.001
- attack.command_and_control
- attack.t1071.004
logsource:
category: dns
detection:
selection_long_query:
QueryName|re: '^([a-zA-Z0-9]{32,}\.)+'
selection_high_entropy:
QueryName|re: '^[a-zA-Z0-9]{20,}\.[a-zA-Z0-9]{20,}\.'
condition: selection_long_query or selection_high_entropy
timeframe: 5m
falsepositives:
- CDN providers with hashed subdomains
- Legitimate DynamicDNS services
level: medium
Gestione del Repository Sigma Aziendale
Un repository Sigma aziendale ben organizzato e fondamentale per la scalabilità. Ecco la struttura raccomandata:
sigma-rules/
├── .github/
│ └── workflows/
│ ├── validate.yml # Lint e validazione YAML
│ └── convert-deploy.yml # Conversione e deploy
├── rules/
│ ├── windows/
│ │ ├── process_creation/
│ │ ├── security/
│ │ └── sysmon/
│ ├── linux/
│ │ ├── auth/
│ │ └── process/
│ ├── cloud/
│ │ ├── aws/
│ │ ├── azure/
│ │ └── gcp/
│ └── network/
│ ├── dns/
│ └── firewall/
├── pipelines/
│ ├── splunk_custom.yml
│ ├── elastic_ecs.yml
│ └── sentinel_kql.yml
├── tests/
│ ├── positive/ # Log che DEVONO triggherare
│ └── negative/ # Log che NON devono triggherare
└── scripts/
├── validate_rules.py
├── convert_all.py
└── deploy_to_siem.py
Automazione: Script di Validazione e Conversione
Ecco uno script Python completo per validare e convertire in bulk le regole Sigma in un repository aziendale:
#!/usr/bin/env python3
"""
Sigma Rule Validator and Converter
Valida la sintassi YAML e converte le regole per tutti i SIEM target.
"""
import os
import sys
import json
import yaml
import uuid
import subprocess
from pathlib import Path
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class ConversionResult:
rule_path: str
success: bool
target: str
output: str = ""
error: str = ""
@dataclass
class ValidationResult:
rule_path: str
valid: bool
errors: list[str] = field(default_factory=list)
warnings: list[str] = field(default_factory=list)
REQUIRED_FIELDS = ['title', 'id', 'status', 'description', 'logsource', 'detection', 'level']
VALID_STATUSES = ['stable', 'test', 'experimental', 'deprecated', 'unsupported']
VALID_LEVELS = ['informational', 'low', 'medium', 'high', 'critical']
SIEM_TARGETS = [
{"name": "splunk", "pipeline": "splunk_windows", "flag": "-t splunk"},
{"name": "elastic", "pipeline": "ecs_windows", "flag": "-t elasticsearch"},
{"name": "sentinel", "pipeline": "microsoft365defender",
"flag": "-t microsoft365defender"},
]
def validate_sigma_rule(rule_path: Path) -> ValidationResult:
"""Valida una singola regola Sigma."""
result = ValidationResult(rule_path=str(rule_path), valid=True)
try:
with open(rule_path, 'r', encoding='utf-8') as f:
rule = yaml.safe_load(f)
except yaml.YAMLError as e:
result.valid = False
result.errors.append(f"YAML parse error: {e}")
return result
# Check campi obbligatori
for field_name in REQUIRED_FIELDS:
if field_name not in rule:
result.valid = False
result.errors.append(f"Missing required field: {field_name}")
# Validate UUID
if 'id' in rule:
try:
uuid.UUID(str(rule['id']))
except ValueError:
result.errors.append(f"Invalid UUID format: {rule['id']}")
result.valid = False
# Validate status
if 'status' in rule and rule['status'] not in VALID_STATUSES:
result.warnings.append(
f"Unknown status: {rule['status']}. "
f"Valid: {VALID_STATUSES}"
)
# Validate level
if 'level' in rule and rule['level'] not in VALID_LEVELS:
result.valid = False
result.errors.append(
f"Invalid level: {rule['level']}. Valid: {VALID_LEVELS}"
)
# Check logsource ha almeno category o service
if 'logsource' in rule:
logsource = rule['logsource']
if not any(k in logsource for k in ['category', 'service', 'product']):
result.errors.append("logsource must have at least one of: category, service, product")
result.valid = False
# Check detection ha condition
if 'detection' in rule and 'condition' not in rule['detection']:
result.errors.append("detection block missing 'condition' field")
result.valid = False
# Warn su falsepositives mancanti per regole stable/high
if rule.get('status') == 'stable' and rule.get('level') in ['high', 'critical']:
if 'falsepositives' not in rule:
result.warnings.append("Stable high-severity rule missing falsepositives documentation")
return result
def convert_rule(rule_path: Path, target_config: dict) -> ConversionResult:
"""Converte una regola Sigma per un SIEM target."""
cmd = [
'sigma', 'convert',
'-t', target_config['name'],
'-p', target_config['pipeline'],
str(rule_path)
]
try:
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if proc.returncode == 0:
return ConversionResult(
rule_path=str(rule_path),
success=True,
target=target_config['name'],
output=proc.stdout.strip()
)
else:
return ConversionResult(
rule_path=str(rule_path),
success=False,
target=target_config['name'],
error=proc.stderr.strip()
)
except subprocess.TimeoutExpired:
return ConversionResult(
rule_path=str(rule_path),
success=False,
target=target_config['name'],
error="Conversion timeout"
)
def process_repository(rules_dir: str) -> dict:
"""Processa l'intero repository di regole Sigma."""
rules_path = Path(rules_dir)
results = {"validation": [], "conversion": {}, "summary": {}}
rule_files = list(rules_path.rglob("*.yml"))
print(f"Found {len(rule_files)} rules")
valid_count = 0
invalid_count = 0
for rule_file in rule_files:
val_result = validate_sigma_rule(rule_file)
results["validation"].append({
"path": str(rule_file.relative_to(rules_path)),
"valid": val_result.valid,
"errors": val_result.errors,
"warnings": val_result.warnings
})
if val_result.valid:
valid_count += 1
for target in SIEM_TARGETS:
if target['name'] not in results["conversion"]:
results["conversion"][target['name']] = []
conv = convert_rule(rule_file, target)
results["conversion"][target['name']].append({
"path": str(rule_file.relative_to(rules_path)),
"success": conv.success,
"output": conv.output if conv.success else None,
"error": conv.error if not conv.success else None
})
else:
invalid_count += 1
print(f"INVALID: {rule_file.name}")
for err in val_result.errors:
print(f" ERROR: {err}")
results["summary"] = {
"total": len(rule_files),
"valid": valid_count,
"invalid": invalid_count,
"conversion_rate": valid_count / len(rule_files) * 100 if rule_files else 0
}
return results
if __name__ == "__main__":
rules_dir = sys.argv[1] if len(sys.argv) > 1 else "./rules"
results = process_repository(rules_dir)
output_file = "sigma_report.json"
with open(output_file, 'w') as f:
json.dump(results, f, indent=2)
summary = results["summary"]
print(f"\n=== SIGMA VALIDATION REPORT ===")
print(f"Total rules: {summary['total']}")
print(f"Valid: {summary['valid']} ({summary['conversion_rate']:.1f}%)")
print(f"Invalid: {summary['invalid']}")
print(f"Full report: {output_file}")
sys.exit(0 if summary['invalid'] == 0 else 1)
GitHub Actions per CI/CD delle Sigma Rules
Integra la validazione e la conversione delle regole Sigma nella tua pipeline CI/CD:
# .github/workflows/sigma-pipeline.yml
name: Sigma Rules CI/CD
on:
push:
paths:
- 'rules/**/*.yml'
- 'pipelines/**/*.yml'
pull_request:
paths:
- 'rules/**/*.yml'
jobs:
validate:
name: Validate Sigma Rules
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install sigma-cli pySigma-backend-splunk \
pySigma-backend-elasticsearch \
pySigma-backend-microsoft365defender \
pyyaml
- name: Run validation
run: python scripts/validate_rules.py ./rules
- name: Upload validation report
if: always()
uses: actions/upload-artifact@v4
with:
name: sigma-validation-report
path: sigma_report.json
convert-and-deploy:
name: Convert and Deploy Rules
needs: validate
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Install sigma-cli
run: pip install sigma-cli pySigma-backend-splunk
- name: Convert rules for Splunk
run: |
sigma convert \
-t splunk \
-p splunk_windows \
-p pipelines/splunk_custom.yml \
--format-output savedsearches \
rules/ > converted/splunk_rules.conf
- name: Deploy to Splunk
env:
SPLUNK_HOST: ${{ secrets.SPLUNK_HOST }}
SPLUNK_TOKEN: ${{ secrets.SPLUNK_TOKEN }}
run: |
python scripts/deploy_to_splunk.py \
--rules converted/splunk_rules.conf \
--host "$SPLUNK_HOST" \
--token "$SPLUNK_TOKEN"
Best Practice: Sigma Rule Lifecycle
-
Inizia sempre con
status: experimentalelevel: lowper una nuova regola - Documenta i false positive noti nel campo
falsepositives -
Promuovi a
stablesolo dopo almeno 2 settimane di test in ambiente di staging con dati reali -
Usa
relatedper linkare regole correlate che coprono la stessa tecnica con approcci diversi - Mantieni un CHANGELOG per ogni regola: data, autore, motivo modifica
Sigma e MITRE ATT&CK: Coverage Mapping
Un uso avanzato di Sigma e la mappatura automatica della copertura ATT&CK. Con un semplice script e possibile analizzare il repository e generare un heatmap della copertura per tattiche e tecniche:
import yaml
import json
from pathlib import Path
from collections import defaultdict
def build_attck_coverage(rules_dir: str) -> dict:
"""
Analizza il repository Sigma e genera statistiche
di copertura per tecnica MITRE ATT&CK.
"""
coverage = defaultdict(list)
for rule_file in Path(rules_dir).rglob("*.yml"):
with open(rule_file) as f:
rule = yaml.safe_load(f)
tags = rule.get('tags', [])
rule_info = {
"title": rule.get('title', ''),
"status": rule.get('status', ''),
"level": rule.get('level', ''),
"file": str(rule_file)
}
for tag in tags:
# Estrae solo i tag di tecnica ATT&CK: attack.t1234.001
if tag.startswith('attack.t') and len(tag) > 9:
technique_id = tag.replace('attack.', '').upper()
coverage[technique_id].append(rule_info)
# Calcola statistiche per livello di severita
stats = {}
for technique, rules in coverage.items():
level_counts = defaultdict(int)
for r in rules:
level_counts[r['level']] += 1
stats[technique] = {
"rule_count": len(rules),
"stable_count": sum(1 for r in rules if r['status'] == 'stable'),
"levels": dict(level_counts),
"rules": [r['title'] for r in rules]
}
return {
"total_techniques_covered": len(coverage),
"total_rules": sum(len(r) for r in coverage.values()),
"techniques": stats
}
coverage = build_attck_coverage("./rules")
print(f"Tecniche coperte: {coverage['total_techniques_covered']}")
print(f"Regole totali: {coverage['total_rules']}")
with open("attck_coverage.json", "w") as f:
json.dump(coverage, f, indent=2)
Anti-Pattern da Evitare
Scrivere Sigma rules efficaci richiede di evitare alcuni errori comuni che portano a falsi positivi eccessivi o detection inefficaci:
Anti-Pattern Comuni
-
Regex troppo permissive:
CommandLine|re: '.*'matcha tutto. Usa regex specifiche e anchorate -
Mancanza di filtri: senza
filter_selections per processi legittimi, genererai migliaia di falsi positivi al giorno - Usare solo il nome del processo: gli attaccanti rinominano i binari. Usa hash, path completo E argomenti della command line
-
Non versionare le regole: senza
idUUID emodifieddate, non puoi tracciare l'evoluzione delle regole - Status always experimental: le regole non vengono promosse e rimangono in limbo senza un processo di review formale
- Campo level troppo alto: non tutto e "critical". Usa i livelli con parsimonia per preservare la priorità degli alert
Conclusioni e Prossimi Passi
Sigma rappresenta oggi lo stato dell'arte per la scrittura di detection logic portabile e collaborativa. Padroneggiare la sua sintassi, i modifier avanzati, e la conversione automatica e una competenza fondamentale per qualsiasi detection engineer moderno.
I punti chiave da ricordare:
- La struttura logsource e il cuore della portabilita: una regola, N piattaforme
- I modifier permettono match flessibili senza sacrificare la precisione
- Le aggregation conditions abilitano detection comportamentali e statistiche
- Un repository ben organizzato con CI/CD e prerequisito per la scalabilità
- La mappatura ATT&CK automatizzata permette di misurare la copertura oggettivamente
Continua la Serie Detection Engineering
Nel prossimo articolo vedremo come costruire una pipeline Detection-as-Code completa con Git e CI/CD, automatizzando test, conversione e deployment delle regole.
Domande frequenti
Cos'è Sigma e perchè è diventato lo standard per la scrittura di regole di detection?
Sigma è un formato open basato su YAML che descrive pattern di rilevamento su log di sicurezza in modo indipendente dalla piattaforma, pensalo come YARA per i log.
Quali sono i vantaggi principali di utilizzare Sigma?
I vantaggi principali sono tre: la portabilità delle regole tra diverse piattaforme SIEM, la possibilità di scrivere regole in modo indipendente dalla piattaforma e l'accesso a oltre 3.000 regole community coperte da continua manutenzione.
Come funziona la conversione automatica delle regole Sigma nei linguaggi di query dei SIEM?
La conversione è gestita dallo strumento ufficiale sigma-cli, che traduce i logsource astratti nei path concreti di ciascun SIEM.
Quali sono gli errori comuni da evitare quando si scrivono regole Sigma efficaci?
Gli errori comuni includono falsi positivi eccessivi o detection inefficaci, che possono essere evitati con la conoscenza della sintassi di Sigma e dei modifier avanzati.

Commenti
Caricamento commenti...
Accedi per commentare