---
title: "Gestion des faux positifs"
domain: security
subdomain: soc
phase: 01-triage
type: snippet
tags: [soc, false-positive, tuning, SIEM, whitelist]
difficulty: intermediate
status: stable
updated: "2025-05-13"
---
## 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

<Checklist items={[
  "L'hôte est-il listé dans un groupe d'exclusion connu (monitoring, admin, scan) ?",
  "L'utilisateur/service account est-il connu et justifié pour cette action ?",
  "L'heure correspond-elle à une fenêtre de maintenance planifiée ?",
  "Le comportement est-il répétable et régulier (même heure, même pattern) ?",
  "Y a-t-il un ticket de changement (ITSM) associé à cette activité ?",
  "Le volume d'alertes identiques dans les 30 derniers jours est-il élevé ?",
  "L'activité est-elle cohérente avec la fonction métier de l'asset ?",
  "Vérification auprès du propriétaire de l'asset / équipe IT confirmée ?",
  "Documenter la décision avec justification métier et date d'expiry"
]} storageKey="soc-fp-check" />

---

## Techniques Splunk — Exclusions et tuning

### Exclusion simple avec NOT

```splunk
# Exclure les hôtes de monitoring connus
index=windows EventCode=4625
  NOT (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

```splunk
# Lookup whitelist d'assets autorisés
index=windows EventCode=4688
  NewProcessName="*PsExec*"
| eval is_authorized=if(
    match(host, "(?i)(jump|bastion|admin-ws)"),
    "yes", "no"
  )
| where is_authorized="no"
| table _time, host, SubjectUserName, CommandLine
```

```splunk
# 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

```splunk
# Faux positif Kerberoasting — exclure comptes de service légitimes
index=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

```splunk
# 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

```yaml
# Règle originale — trop de bruit
title: PsExec Execution
status: experimental
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    Image|endswith: '\psexec.exe'
  condition: selection
level: high
```

### Après tuning — contextualisée

```yaml
title: PsExec Execution - Unauthorized Hosts
status: test
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    Image|endswith:
      - '\psexec.exe'
      - '\psexec64.exe'
    ParentImage|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
  filter_authorized:
    # Exclure les jump servers et postes admin autorisés
    Computer|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 deployments
level: high
tags:
  - 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

```bash
# Structure recommandée pour whitelist_processes.csv
# process_name, host_pattern, user_pattern, reason, owner, added_date, expiry_date
PsExec.exe,JUMP-*,svc-ops,Remote admin from jump server,ops-team,2025-05-13,2026-05-13
nessus.exe,SCAN-*,svc-nessus,Vuln scanner authorized,security-team,2025-05-13,
```

```splunk
# 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

```splunk
# Ratio VP/FP par règle sur 30 jours
index=notable earliest=-30d
| stats
    count(eval(status="true_positive")) as vp,
    count(eval(status="false_positive")) as fp,
    count as total
  by 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
```

<Tip>Documenter chaque décision de whitelist avec : la justification métier, le nom du validateur, et une date d'expiry maximale de 12 mois. Réviser automatiquement toutes les whitelists > 6 mois — les contextes changent, une exclusion permanente est une dette de sécurité.</Tip>
