330 lines
No EOL
12 KiB
Markdown
330 lines
No EOL
12 KiB
Markdown
# Lab Wazuh — Détection brute force SSH (Debian 13) & exécution PowerShell (Win11)
|
||
|
||
Documentation pour un lab Proxmox avec :
|
||
|
||
- **Wazuh** (manager + indexer + dashboard) en LXC, installé via helper-script.
|
||
- **Debian 13** avec l'agent Wazuh → on veut détecter un **brute force SSH**.
|
||
- **Windows 11** avec l'agent Wazuh → on veut détecter l'**exécution d'un script PowerShell**.
|
||
|
||
> Convention de chemins utilisée dans tout le document :
|
||
> - **Manager (LXC)** : `/var/ossec/etc/...`, service `wazuh-manager`
|
||
> - **Agent Debian** : `/var/ossec/etc/ossec.conf`, service `wazuh-agent`
|
||
> - **Agent Windows** : `C:\Program Files (x86)\ossec-agent\ossec.conf`, service `Wazuh`
|
||
|
||
---
|
||
|
||
## 0. Pré-requis : vérifier que les agents remontent bien
|
||
|
||
Sur le manager (dans le LXC) :
|
||
|
||
```bash
|
||
/var/ossec/bin/agent_control -l
|
||
```
|
||
|
||
Tu dois voir tes deux agents en `Active`. S'ils sont `Disconnected`, règle la connectivité (firewall, ports `1514/tcp` et `1515/tcp` vers le LXC) avant de continuer.
|
||
|
||
---
|
||
|
||
## A. Détection du brute force SSH sur Debian 13
|
||
|
||
### A.1 — Point clé : Debian 13 n'a plus `rsyslog` par défaut
|
||
|
||
Depuis Debian 12, le paquet `rsyslog` n'est **plus installé par défaut** : les logs sont gérés par **`systemd-journald`**, et le fichier `/var/log/auth.log` peut donc **ne pas exister**. C'est le piège classique : l'agent est connecté mais ne remonte aucun événement SSH.
|
||
|
||
Tu as deux options. **L'option 1 (journald) est recommandée** sur Debian 13.
|
||
|
||
#### Option 1 (recommandée) — Collecte via journald
|
||
|
||
Les agents Wazuh ≥ 4.8 collectent journald **par défaut**. Vérifie la présence de ce bloc dans `/var/ossec/etc/ossec.conf` sur la Debian :
|
||
|
||
```xml
|
||
<localfile>
|
||
<location>journald</location>
|
||
<log_format>journald</log_format>
|
||
</localfile>
|
||
```
|
||
|
||
S'il est absent, ajoute-le, puis redémarre l'agent :
|
||
|
||
```bash
|
||
sudo systemctl restart wazuh-agent
|
||
```
|
||
|
||
#### Option 2 — Revenir à `/var/log/auth.log`
|
||
|
||
Si tu préfères le fichier classique :
|
||
|
||
```bash
|
||
sudo apt update && sudo apt install -y rsyslog
|
||
sudo systemctl enable --now rsyslog
|
||
```
|
||
|
||
Puis vérifie/ajoute dans `/var/ossec/etc/ossec.conf` :
|
||
|
||
```xml
|
||
<localfile>
|
||
<log_format>syslog</log_format>
|
||
<location>/var/log/auth.log</location>
|
||
</localfile>
|
||
```
|
||
|
||
Et redémarre l'agent :
|
||
|
||
```bash
|
||
sudo systemctl restart wazuh-agent
|
||
```
|
||
|
||
### A.2 — Les règles sont déjà intégrées (rien à écrire)
|
||
|
||
Wazuh embarque la détection SSH dans `0095-sshd_rules.xml`. Les règles utiles :
|
||
|
||
| Règle | Niveau | Signification |
|
||
|-------|--------|---------------|
|
||
| `5710` | 5 | Tentative de connexion avec un **utilisateur inexistant** |
|
||
| `5716` | 5 | Échec d'authentification SSH |
|
||
| `5720` | 10 | **8 échecs d'authentification** depuis la même IP |
|
||
| `5712` | 10 | **Brute force SSH** : la règle `5710` se déclenche **8 fois en 120 s** depuis la même IP (MITRE **T1110**) |
|
||
|
||
La règle `5712` ressemble à ceci (pour info, **à ne pas recopier**) :
|
||
|
||
```xml
|
||
<rule id="5712" level="10" frequency="8" timeframe="120" ignore="60">
|
||
<if_matched_sid>5710</if_matched_sid>
|
||
<description>sshd: brute force trying to get access to the system.</description>
|
||
<mitre><id>T1110</id></mitre>
|
||
<same_source_ip />
|
||
</rule>
|
||
```
|
||
|
||
> **À retenir pour le test** : pour déclencher `5712`, il faut **8+ tentatives en moins de 120 s, depuis la même IP, avec un utilisateur inexistant** (c'est ce qui alimente `5710`). On choisira donc un login bidon comme `baduser`.
|
||
|
||
### A.3 (optionnel) — Bloquer automatiquement l'IP (Active Response)
|
||
|
||
Pour aller plus loin, tu peux faire bannir l'IP attaquante via `firewall-drop`. Dans `/var/ossec/etc/ossec.conf` **du manager** :
|
||
|
||
```xml
|
||
<active-response>
|
||
<command>firewall-drop</command>
|
||
<location>local</location>
|
||
<rules_id>5712</rules_id>
|
||
<timeout>1800</timeout>
|
||
</active-response>
|
||
```
|
||
|
||
Puis `sudo systemctl restart wazuh-manager`. (Facultatif pour un simple test de détection.)
|
||
|
||
---
|
||
|
||
## B. Détection de l'exécution PowerShell sur Windows 11
|
||
|
||
Le principe : activer le **Script Block Logging** de PowerShell (génère l'**Event ID 4104** dans le canal `Microsoft-Windows-PowerShell/Operational`), faire collecter ce canal par l'agent, puis ajouter une règle d'alerte.
|
||
|
||
### B.1 — Activer le Script Block Logging
|
||
|
||
**Méthode registre** (fonctionne sur toutes les éditions, y compris Win11 Home). PowerShell **en administrateur** :
|
||
|
||
```powershell
|
||
$base = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" ; New-Item -Path $base -Force | Out-Null ; Set-ItemProperty -Path $base -Name "EnableScriptBlockLogging" -Value 1 -Type DWord
|
||
```
|
||
|
||
**Méthode GPO** (Win11 Pro) : `gpedit.msc` → *Configuration ordinateur* → *Modèles d'administration* → *Composants Windows* → *Windows PowerShell* → **Activer la journalisation des blocs de script PowerShell** → **Activé**.
|
||
|
||
### B.2 — Collecter le canal PowerShell avec l'agent Wazuh
|
||
|
||
Édite `C:\Program Files (x86)\ossec-agent\ossec.conf` et ajoute, **à l'intérieur du bloc `<ossec_config>`** :
|
||
|
||
```xml
|
||
<localfile>
|
||
<location>Microsoft-Windows-PowerShell/Operational</location>
|
||
<log_format>eventchannel</log_format>
|
||
</localfile>
|
||
```
|
||
|
||
Redémarre l'agent (PowerShell admin) :
|
||
|
||
```powershell
|
||
Restart-Service -Name Wazuh
|
||
```
|
||
|
||
> Wazuh fournit déjà des règles PowerShell intégrées dans
|
||
> `/var/ossec/ruleset/rules/0915-win-powershell_rules.xml` (règle parente **`91802`**).
|
||
> Le champ exploité est `win.eventdata.scriptBlockText`.
|
||
|
||
### B.3 — Ajouter une règle d'alerte (sur le manager)
|
||
|
||
Pour avoir une alerte nette à chaque exécution de script, ajoute des règles personnalisées dans
|
||
`/var/ossec/etc/rules/local_rules.xml` **(sur le manager / LXC)** :
|
||
|
||
```xml
|
||
<group name="windows,powershell,">
|
||
|
||
<!-- Alerte sur TOUTE exécution d'un bloc de script PowerShell (EID 4104) -->
|
||
<rule id="100100" level="6">
|
||
<if_sid>91802</if_sid>
|
||
<field name="win.eventdata.scriptBlockText" type="pcre2">.+</field>
|
||
<description>PowerShell: bloc de script exécuté sur $(win.system.computer)</description>
|
||
<mitre>
|
||
<id>T1059.001</id>
|
||
</mitre>
|
||
</rule>
|
||
|
||
<!-- Alerte renforcée si motifs typiquement suspects -->
|
||
<rule id="100101" level="12">
|
||
<if_sid>100100</if_sid>
|
||
<field name="win.eventdata.scriptBlockText" type="pcre2">(?i)(-enc |-encodedcommand|downloadstring|invoke-expression|\biex\b|frombase64string|-nop |-w hidden|bypass)</field>
|
||
<description>PowerShell: exécution potentiellement suspecte sur $(win.system.computer)</description>
|
||
<mitre>
|
||
<id>T1059.001</id>
|
||
<id>T1027</id>
|
||
</mitre>
|
||
</rule>
|
||
|
||
</group>
|
||
```
|
||
|
||
Redémarre le manager :
|
||
|
||
```bash
|
||
sudo systemctl restart wazuh-manager
|
||
```
|
||
|
||
> ⚠️ La règle `100100` (niveau 6) alerte sur **chaque** bloc de script — pratique pour le lab, mais bruyant en prod. En usage réel, garde plutôt seulement `100101` (motifs suspects) ou monte le seuil.
|
||
|
||
---
|
||
|
||
## C. Déclencher les détections (tests)
|
||
|
||
### C.1 — Brute force SSH depuis un client Linux
|
||
|
||
Depuis **n'importe quelle autre machine Linux** du réseau (Kali, une VM, ton poste...). Remplace `IP_DEBIAN` par l'IP de la Debian 13.
|
||
|
||
> Utilise volontairement un **utilisateur qui n'existe pas** (`baduser`) pour alimenter la règle `5710` → `5712`.
|
||
|
||
#### Méthode 1 — Hydra (la plus simple)
|
||
|
||
```bash
|
||
sudo apt install -y hydra
|
||
|
||
# petite liste de mots de passe bidon
|
||
printf 'azerty\n123456\npassword\nadmin\nroot\ntoor\nletmein\nqwerty\nmotdepasse\nwazuh\nchangeme\n111111\n' > pass.txt
|
||
|
||
# 12 tentatives en rafale → > 8 en < 120s
|
||
hydra -l baduser -P pass.txt ssh://IP_DEBIAN -t 4 -V
|
||
```
|
||
|
||
```bash
|
||
# Sur ton client Linux d'attaque
|
||
sudo apt install -y hydra
|
||
|
||
# Utilisateurs inexistants → garantit le déclenchement de la règle 5710
|
||
printf 'admin\nroot\ntest\noracle\npostgres\nubuntu\nguest\nbaduser\nftpuser\ndeploy\njenkins\ngit\n' > users.txt
|
||
|
||
# Liste de mots de passe : rockyou si dispo (Kali), sinon une liste de secours
|
||
head -n 300 /usr/share/wordlists/rockyou.txt > pass.txt 2>/dev/null || \
|
||
printf 'azerty\n123456\npassword\nadmin\nroot\ntoor\nletmein\nqwerty\nmotdepasse\nwazuh\nchangeme\n111111\n12345678\nadmin123\nP@ssw0rd\nwelcome\nmonkey\ndragon\n' > pass.txt
|
||
|
||
# Brute force bruyant : tous les users × tous les mots de passe
|
||
hydra -L users.txt -P pass.txt ssh://IP_DEBIAN -t 4 -V -I
|
||
```
|
||
|
||
#### Méthode 2 — Sans hydra (boucle + sshpass)
|
||
|
||
```bash
|
||
sudo apt install -y sshpass
|
||
for i in $(seq 1 12); do
|
||
sshpass -p "wrongpass$i" \
|
||
ssh -o StrictHostKeyChecking=no \
|
||
-o PreferredAuthentications=password \
|
||
-o PubkeyAuthentication=no \
|
||
-o ConnectTimeout=3 \
|
||
baduser@IP_DEBIAN "echo ok" 2>/dev/null
|
||
done
|
||
```
|
||
|
||
**Résultat attendu** : tu dois voir l'alerte **`5712`** (niveau 10) apparaître dans le dashboard.
|
||
|
||
### C.2 — Exécution PowerShell depuis Win11
|
||
|
||
Crée le script de test (totalement inoffensif) — par exemple `C:\Temp\test_wazuh.ps1` :
|
||
|
||
```powershell
|
||
# test_wazuh.ps1 — script de test Wazuh, sans danger
|
||
Write-Output "=== Test detection Wazuh ==="
|
||
Write-Output "Hostname : $env:COMPUTERNAME"
|
||
Write-Output "Utilisateur : $env:USERNAME"
|
||
Write-Output "Date : $(Get-Date)"
|
||
Get-Process | Select-Object -First 5 Name, Id
|
||
Write-Output "=== Fin du test ==="
|
||
```
|
||
|
||
Puis exécute-le :
|
||
|
||
```powershell
|
||
powershell.exe -ExecutionPolicy Bypass -File C:\Temp\test_wazuh.ps1
|
||
```
|
||
|
||
Cela déclenche la règle **`100100`**. Comme la commande contient `bypass`, elle déclenche **aussi** la règle suspecte **`100101`**.
|
||
|
||
#### Variante « commande encodée » (déclenche `100101`, toujours inoffensif)
|
||
|
||
Beaucoup d'attaques utilisent `-EncodedCommand`. On peut le simuler avec une charge utile bénigne (afficher du texte) :
|
||
|
||
```powershell
|
||
$cmd = 'Write-Output "Wazuh encoded test"'
|
||
$enc = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($cmd))
|
||
powershell.exe -NoProfile -EncodedCommand $enc
|
||
```
|
||
|
||
---
|
||
|
||
## D. Visualiser les alertes dans le dashboard
|
||
|
||
Dans le dashboard Wazuh → module **Threat Hunting** (ou **Security Events**) → barre de recherche :
|
||
|
||
- **Brute force SSH (Debian)** :
|
||
```
|
||
rule.id:(5710 OR 5712 OR 5720)
|
||
```
|
||
- **PowerShell (Windows)** :
|
||
```
|
||
rule.id:(91802 OR 100100 OR 100101)
|
||
```
|
||
|
||
Tu peux aussi filtrer par agent (`agent.name`) pour isoler la Debian ou le Win11.
|
||
|
||
---
|
||
|
||
## E. Dépannage
|
||
|
||
**Tester une règle/un log à la main (sur le manager)** — très utile :
|
||
|
||
```bash
|
||
/var/ossec/bin/wazuh-logtest
|
||
```
|
||
Colle ensuite une ligne de log (ex. une ligne `Invalid user baduser from ...`) ; l'outil affiche le décodeur et la règle qui matche.
|
||
|
||
**Vérifier que l'agent Debian lit bien la source de logs** :
|
||
|
||
```bash
|
||
sudo /var/ossec/bin/wazuh-control status # tous les process actifs ?
|
||
sudo grep -i 'localfile\|journald' /var/ossec/etc/ossec.conf
|
||
```
|
||
|
||
**Côté Windows, vérifier que l'EID 4104 est bien généré** : `eventvwr.msc` → *Journaux des applications et des services* → *Microsoft* → *Windows* → *PowerShell* → *Operational* → filtrer sur l'ID **4104**.
|
||
|
||
**Aucune alerte malgré tout ?**
|
||
- Rappelle-toi que seules les alertes de **niveau ≥ 3** sont remontées par défaut.
|
||
- Pour le brute force : il faut bien **8+ tentatives en < 120 s, même IP, utilisateur inexistant**. Si tu testes depuis la Debian elle-même (127.0.0.1), `same_source_ip` fonctionne quand même, mais lance depuis une autre machine pour un test réaliste.
|
||
- Vérifie l'horloge des machines (un décalage NTP fausse la fenêtre de 120 s).
|
||
|
||
---
|
||
|
||
### Récapitulatif des fichiers modifiés
|
||
|
||
| Machine | Fichier | Action |
|
||
|---------|---------|--------|
|
||
| Agent Debian | `/var/ossec/etc/ossec.conf` | S'assurer de la collecte journald (ou auth.log) |
|
||
| Agent Windows | `C:\Program Files (x86)\ossec-agent\ossec.conf` | Ajouter le `localfile` eventchannel PowerShell |
|
||
| Windows (système) | Registre `...\PowerShell\ScriptBlockLogging` | Activer le Script Block Logging |
|
||
| Manager (LXC) | `/var/ossec/etc/rules/local_rules.xml` | Règles PowerShell `100100` / `100101` |
|
||
| Manager (LXC) | `/var/ossec/etc/ossec.conf` | (optionnel) Active Response SSH | |