Q&A Klassiker: SSH Brute-Force

Kategorie: Q&A · Channel: #klassiker

Format: BĂŒhnenspiel – Admin · Angreifer · Kunde


Die Situation

Uhrzeit:  02:14 Uhr
Alarm:    Monitoring – auth.log GrĂ¶ĂŸe > 500MB
          fail2ban: 847 IPs in letzter Stunde gesperrt
Symptom:  SSH-Login dauert ungewöhnlich lange
Kunde:    kein direkter Kundenkontakt – internes Problem
          aber: wenn Server kompromittiert → Kundendaten in Gefahr

đŸ‘šâ€đŸ’» Admin-Perspektive: Was sehe ich, was tue ich?

Schritt 1: Lagebild – wie massiv ist der Angriff?

# Wie viele fehlgeschlagene Logins gerade?
grep "Failed password" /var/log/auth.log | wc -l

# Wie schnell kommen sie rein?
grep "Failed password" /var/log/auth.log | \
  awk '{print $1, $2}' | uniq -c | tail -20
# → zeigt Anzahl pro Minute

# Welche IPs greifen an?
grep "Failed password" /var/log/auth.log | \
  awk '{print $11}' | sort | uniq -c | sort -rn | head -20

# Welche Usernames werden probiert?
grep "Invalid user" /var/log/auth.log | \
  awk '{print $8}' | sort | uniq -c | sort -rn | head -20
# typisch: root, admin, ubuntu, pi, test, oracle, postgres...

# fail2ban Status
fail2ban-client status sshd
# → zeigt aktuelle Banned IPs und Gesamtzahl

Schritt 2: Wurde eine Verbindung erfolgreich hergestellt?

# Das ist die kritische Frage!

# Erfolgreiche Logins prĂŒfen:
grep "Accepted" /var/log/auth.log
grep "session opened" /var/log/auth.log

# Wer ist gerade eingeloggt?
who
w
last | head -20

# Aktive SSH-Verbindungen:
ss -tnp | grep :22

# Unbekannte Prozesse die der Angreifer gestartet haben könnte:
ps aux | grep -v "^root\|^www-data\|^mysql\|^nobody"
# → unbekannte User mit Prozessen = Warnsignal!

# Netzwerkverbindungen nach außen prĂŒfen:
ss -tnp | grep ESTABLISHED
netstat -tnp | grep -v "127.0.0.1\|10.0."
# → unbekannte externe Verbindungen = Warnsignal!

Schritt 3: Sofortmaßnahme – Angriff eindĂ€mmen

# Option A: IP-Bereich sofort sperren (wenn Angriff von einer Region)
iptables -I INPUT 1 -s 1.2.3.0/24 -j DROP

# Option B: SSH nur noch aus Management-Netz
iptables -I INPUT 1 -p tcp --dport 22 \
  ! -s 10.0.0.0/19 -j DROP

# Option C: SSH-Port temporĂ€r schließen
# ⚠ NUR wenn IPMI-Zugang verfĂŒgbar!
iptables -I INPUT 1 -p tcp --dport 22 -j DROP
# Dann: Reparatur via IPMI-Konsole

# fail2ban Ban-Zeit erhöhen (sofort wirksam):
fail2ban-client set sshd bantime 86400   # 24 Stunden
fail2ban-client set sshd maxretry 2      # nach 2 Fehlern sperren

Schritt 4: HĂ€rtung – wenn noch nicht geschehen

# PasswordAuthentication deaktivieren – SOFORT
# Schritt 1: Sicherstellen dass eigener Key hinterlegt ist
cat ~/.ssh/authorized_keys   # muss vorhanden sein!

# Schritt 2: Config Àndern
vi /etc/ssh/sshd_config
# PasswordAuthentication no
# PermitRootLogin no
# MaxAuthTries 3

# Schritt 3: Syntax prĂŒfen
sshd -t

# Schritt 4: In ZWEITER Session testen, dann reload
systemctl reload sshd

# Schritt 5: Sofort testen ob Key-Login noch funktioniert!
ssh -i ~/.ssh/id_ed25519 adminuser@10.0.1.50

Schritt 5: War der Angriff erfolgreich? – Forensik

# Rootkit-Check (schnell):
find / -name ".*" -type f 2>/dev/null | grep -v ".cache\|.config\|.local"
# → versteckte Dateien (Punkt am Anfang) außerhalb von Home

# SUID/SGID Dateien – wurden neue hinzugefĂŒgt?
find / -perm /4000 -o -perm /2000 2>/dev/null | sort
# Normalzustand kennen → mit frĂŒherer Liste vergleichen

# Cronjobs prĂŒfen – wurde etwas hinzugefĂŒgt?
crontab -l
crontab -l -u root
ls -la /etc/cron.*
cat /etc/crontab

# Neue User angelegt?
awk -F: '$3 >= 1000 {print $1, $3}' /etc/passwd
# → unbekannte UIDs = Warnsignal

# Letzte DateiÀnderungen:
find /etc /bin /sbin /usr/bin /usr/sbin \
  -newer /var/log/auth.log -type f 2>/dev/null

# Systemd-Services prĂŒfen:
systemctl list-units --state=active --type=service | \
  grep -v "^UNIT\|loaded\|exited"

Schritt 6: auth.log GrĂ¶ĂŸe reduzieren

# auth.log ist 500MB – zuerst verstehen warum
wc -l /var/log/auth.log

# Rotation erzwingen:
logrotate -f /etc/logrotate.d/rsyslog

# rsyslog Rate-Limiting fĂŒr Auth-Meldungen:
# /etc/rsyslog.d/50-default.conf:
# auth,authpriv.*  /var/log/auth.log

# FĂŒr fail2ban reichen die letzten Stunden:
# fail2ban liest die Datei live → alte EintrĂ€ge können rotiert werden

đŸŠč Angreifer-Perspektive: Wie gehe ich vor?

Phase 1: Reconnaissance

Ziel: herausfinden ob SSH offen ist und welche Version lÀuft

nmap -sV -p 22 10.0.1.50
# → SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2

# Was verrÀt der Banner?
nc 10.0.1.50 22
# SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2
# → Debian-Version bekannt → bekannte CVEs prĂŒfbar

Phase 2: Credential Stuffing / Dictionary Attack

Typische Tools:
hydra -l root -P /wordlists/rockyou.txt ssh://10.0.1.50
medusa -h 10.0.1.50 -u admin -P passwords.txt -M ssh
ncrack -p 22 --user root -P common_passwords.txt 10.0.1.50

Was ich probiere:
- root / root
- root / toor
- admin / admin
- ubuntu / ubuntu
- pi / raspberry
- test / test
- oracle / oracle
- postgres / postgres

Phase 3: Was ich suche nach Erfolg

1. Persistenz sichern:
   → eigenen Key in authorized_keys eintragen
   → neuen User anlegen: useradd -m -s /bin/bash sysbackup
   → Cronjob fĂŒr Reverse-Shell

2. Privilege Escalation:
   → sudo -l (was darf der User?)
   → SUID-Binaries (find / -perm /4000)
   → Kernel-Exploits (uname -a → bekannte CVEs)

3. Lateral Movement:
   → ~/.ssh/known_hosts lesen → welche anderen Server sind bekannt?
   → SSH-Keys kopieren → andere Server versuchen
   → Netzwerk scannen: nmap 10.0.1.0/24

Was mich am meisten aufhÀlt

✓ PasswordAuthentication no   → dictionary attacks nutzlos
✓ fail2ban mit kurzer Ban-Zeit → IP sofort gesperrt
✓ Port 22 nur aus MGMT-Netz   → ich komme gar nicht ran
✓ SSH-SchlĂŒssel + Passphrase  → selbst bei Key-Diebstahl nutzlos
✗ Nur Port-Change (2222)      → hilft wenig, nmap findet es trotzdem

👔 Kunden-Perspektive: Was erlebe ich?

Direkte Auswirkung auf Kunden:
→ Solange nur Brute-Force (kein Erfolg): keine direkte Auswirkung
→ Bei erfolgreichem Einbruch:
   - Kundendaten kompromittiert → DSGVO-Meldepflicht 72h!
   - Server als Spam-Relay genutzt → IP auf Blacklists
   - Crypto-Miner → Server zu langsam → Dienste trĂ€ge
   - Ransomware → Totalausfall

DSGVO-Kontext bei Erfolg:

Wenn personenbezogene Daten kompromittiert wurden:

72-Stunden-Frist:
→ Meldung an Datenschutzbehörde (BSI / Landesdatenschutzbeauftragter)
→ Information betroffener Kunden wenn hohes Risiko

Dokumentation die erstellt werden muss:
- Wann wurde der Angriff bemerkt?
- Welche Daten waren betroffen?
- Welche Maßnahmen wurden ergriffen?
- Wann wurde die LĂŒcke geschlossen?

🎯 Erkenntnis – Drei Perspektiven zusammen

Perspektive Kernaussage
đŸ‘šâ€đŸ’» Admin grep "Accepted" /var/log/auth.log ist die erste kritische Frage
đŸŠč Angreifer PasswordAuthentication no macht Dictionary Attacks sofort nutzlos
👔 Kunde Kein Kundenproblem solange kein Einbruch – danach: DSGVO 72h

🔧 PrĂ€vention – die vollstĂ€ndige Checkliste

# 1. PasswordAuthentication no  ← wichtigste Maßnahme
# 2. PermitRootLogin no
# 3. MaxAuthTries 3
# 4. Port 22 nur aus MGMT-Netz per iptables
# 5. fail2ban aktiv mit:
#    - maxretry 3
#    - bantime 24h
#    - ignoreip = eigenes Netz
# 6. SSH-Banner deaktivieren (kein OS-Fingerprint):
#    Banner none
#    DebianBanner no
# 7. Monitoring: Alert wenn auth.log > 100MB
# 8. Monitoring: Alert wenn fail2ban > 50 Bans/Stunde
# 9. known_hosts regelmĂ€ĂŸig prĂŒfen
# 10. Keine privaten Keys auf Servern (nur Public Keys!)

📋 Schnellreferenz: SSH Brute-Force – Einzeiler

# Angriff bewerten
grep "Failed password" /var/log/auth.log | wc -l
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head
grep "Accepted" /var/log/auth.log                      # Erfolgreiche Logins!

# Sofortmaßnahmen
fail2ban-client status sshd                            # Status
fail2ban-client set sshd bantime 86400                 # 24h sperren
iptables -I INPUT 1 -p tcp --dport 22 ! -s 10.0.0.0/19 -j DROP

# Forensik
who && w && last | head -20                            # wer ist drin?
ss -tnp | grep :22                                     # aktive Sessions
find /etc/cron* /var/spool/cron -type f -newer /var/log/auth.log  # neue Cronjobs?
awk -F: '$3 >= 1000 {print $1, $3}' /etc/passwd       # neue User?