Gestion des faux positifs
Identifier, qualifier et traiter les faux positifs — tuning des règles SIEM
Catégories de faux positifs courants
| Catégorie | Exemples typiques | Signal déclenché | |---|---|---| | Tâches planifiées légitimes | Backup agents, patch management (SCCM, Intune), antivirus updates | Process spawn suspect, cmd child | | Outils d'admin légitimes | PsExec par équipe ops, remote WMI, RSAT, Ansible WinRM | Lateral movement rules, LSASS access | | Agents de monitoring | Zabbix, Datadog, Nagios, Splunk UF | Réseau scan, connexions inhabituelles | | Scanners de vulnérabilités | Nessus, Qualys, Tenable — scans planifiés | Port scan, bruteforce detection | | Scripts d'inventaire | PowerShell remoting pour inventaire parc | AMSI trigger, encoded PS | | Produits de sécurité | EDR qui injecte dans les process, sandbox AV | Process injection, hook detection | | Comportement développeur | CI/CD pipelines, build agents, Docker en local | Commandes admin, port bindings |
Checklist de qualification FP
Techniques Splunk — Exclusions et tuning
Exclusion simple avec NOT
# Exclure les hôtes de monitoring connusindex=windows EventCode=4625NOT (src_ip IN ("{{MONITORING_IP_1}}", "{{MONITORING_IP_2}}"))NOT (SubjectUserName IN ("svc-monitoring", "svc-backup", "svc-nessus"))| stats count by host, SubjectUserName, src_ip
Exclusion conditionnelle avec eval + lookup
# Lookup whitelist d'assets autorisésindex=windows EventCode=4688NewProcessName="*PsExec*"| eval is_authorized=if(match(host, "(?i)(jump|bastion|admin-ws)"),"yes", "no")| where is_authorized="no"| table _time, host, SubjectUserName, CommandLine
# Exclure via lookup CSV (whitelist_processes.csv : process_name, reason, owner)index=windows EventCode=4688| lookup whitelist_processes.csv process_name AS NewProcessName OUTPUT reason, owner| where isnull(reason)| table _time, host, NewProcessName, CommandLine
Exclusion multi-conditions avec isnotnull
# Faux positif Kerberoasting — exclure comptes de service légitimesindex=windows EventCode=4769 TicketEncryptionType=0x17| eval is_fp = if(isnotnull(match(ServiceName, "svc_.*|krbtgt|.*\$")),"fp", "investigate")| where is_fp="investigate"
Throttling sur alertes récurrentes
# Supprimer les alertes déjà vues dans les 24h (déduplication)index=notable| inputlookup fp_suppression.csv| eval suppress_until=strptime(suppress_until, "%Y-%m-%d %H:%M:%S")| where now() < suppress_until
Tuning de règles Sigma
Avant tuning — règle bruyante
# Règle originale — trop de bruittitle: PsExec Executionstatus: experimentallogsource:category: process_creationproduct: windowsdetection:selection:Image|endswith: '\psexec.exe'condition: selectionlevel: high
Après tuning — contextualisée
title: PsExec Execution - Unauthorized Hostsstatus: testlogsource:category: process_creationproduct: windowsdetection:selection:Image|endswith:- '\psexec.exe'- '\psexec64.exe'ParentImage|endswith:- '\cmd.exe'- '\powershell.exe'filter_authorized:# Exclure les jump servers et postes admin autorisésComputer|startswith:- 'JUMP-'- 'ADMIN-WS-'- 'SCCM-'filter_service_accounts:User|startswith:- 'svc-'- 'NT AUTHORITY\'condition: selection and not 1 of filter_*falsepositives:- Legitimate remote administration from jump servers- SCCM/Intune agent deploymentslevel: hightags:- attack.lateral_movement- attack.t1569.002
Quand whitelister vs quand tuner ?
| Situation | Action recommandée | |---|---| | FP systématique sur un outil légitime bien connu | Tuner la règle — ajouter filtre dans Sigma/SPL | | FP sur un hôte ou user spécifique uniquement | Lookup whitelist avec justification datée | | FP temporaire (projet, migration) | Suppression temporaire avec date d'expiry | | FP sur comportement rare mais légitime | Threshold — déclencher seulement au-delà de N occurrences | | Comportement ambigu, pas de confirmation IT | Ne pas whitelister — investiguer davantage | | Règle déclenche > 95% de FP | Désactiver et réécrire la règle depuis zéro |
Gestion du registre de whitelists
# Structure recommandée pour whitelist_processes.csv# process_name, host_pattern, user_pattern, reason, owner, added_date, expiry_datePsExecexeJUMPsvc-ops,Remote admin from jump serverops-team,2025-05-13,2026-05-13nessusexeSCANsvc-nessus,Vuln scanner authorizedsecurity-team,2025-05-13,
# Audit des whitelists expirées| inputlookup whitelist_registry.csv| eval expiry_epoch=strptime(expiry_date, "%Y-%m-%d")| where isnotnull(expiry_date) AND expiry_epoch < now()| table process_name, host_pattern, owner, expiry_date, reason
Métriques de qualité SIEM
# Ratio VP/FP par règle sur 30 joursindex=notable earliest=-30d| statscount(eval(status="true_positive")) as vp,count(eval(status="false_positive")) as fp,count as totalby rule_name| eval ratio_fp=round(fp/total*100, 1)| where ratio_fp > 50| sort -ratio_fp| table rule_name, total, vp, fp, ratio_fp