Threat Level: green Handler on Duty: Brad Duncan

SANS ISC: InfoSec Handlers Diary Blog InfoSec Handlers Diary Blog

Sign Up for Free!   Forgot Password?
Log In or Sign Up for Free!

Tracking Unexpected DNS Changes

Published: 2019-01-31
Last Updated: 2019-01-31 07:33:32 UTC
by Xavier Mertens (Version: 1)
5 comment(s)

DNS is a key element of the Internet and, regularly, we read new bad stories. One of the last one was the Department of Homeland Security warning[1]  about recent DNS hijacking attacks[2]. Indeed, when you want to visit the website '', you must be sure that the visited server will be and not a malicious one controlled by a malicious server. From an end-user point of view, we have to rely on the DNS. it’s not easy to detect unexpected changes but you can implement your own checks to tracks changes for your most visited websites. But from a website owner or network admin perspective, it is indeed a good practice to ensure that DNS servers authoritative for our domain zones are providing the correct information. At the Internet Storm Center, we must be sure that any request to resolve '' will always return the right IP address! 

To monitor DNS records for unexpected changes, you can use some plugins available in Nagios[3] (or any compatible tool like Icinga). You don't need to install a complete Nagios instance, just the plugins. The one that is interesting is 'check_dns'. It can check if the returned IP address for a FQDN is the expected one. We can also check if the DNS we used is authoritative for a zone:

$ ./check_dns -H -s --expected-address=
DNS CRITICAL - expected '' but got ''
$ ./check_dns -H -s --expected-address=
DNS OK: 0.141 seconds response time. returns|time=0.141161s;;;0.000000
$ ./check_dns -H -s --expect-authority
DNS CRITICAL - server is not authoritative for

But monitoring single DNS entries is complex because you may have thousands of records in a single zone. If you DNS is changed, the SOA[4] record (or 'State of Authority') will be changed (at least the serial number). 

Here is the current SOA record of the zone

$ host -t soa has SOA record 2019012901 7200 900 1814400 3600

A best practice is to keep the serial number format like this: YYYYMMDDNN (where ’NN’ is the number of change performed this day). If somebody has access to the zone and modifies it, the serial MUST be upgraded to let know to other DNS servers that the zone changed. How to monitor this?

First, we can use simple Bash commands. We get the SOA record, hash it, store the new hash and compare it with the previous one.

$ [ `host -t soa | sha256sum | awk '{ print $1 }' | tee` == `cat hash.txt 2>/dev/null || echo __undefined__` ] || \
    echo "SOA record changed"; \
    mv hash.txt
SOA record changed

This command can be executed at regular interval via a cron job.

Easy but not very convenient. The next idea is to use OSSEEC[5] (yes, I love this tool!). OSSEC can monitor regular log files but it can also monitor the output of commands and make a 'diff' of the output between two runs. Let’s check the SOA record of

Let’s define a new “log file” of type “command”:

  <command>host -t soa</command>

And create the corresponding alert:

<rule id=“10001" level="7">
  <match>ossec: output: ‘host -t soa'</match>
  <check_diff />
  <description>SOA record changed in zone</description>

Based on this alert, any change in the SOA record will be logged and injected into your regular alerting process (email notification, forward to a SIEM, etc).

Those techniques can be used to detected suspicious change into a DNS zone via a compromized admin account or a badly protected name server but they do NOT protect against other attacks like cache poisoning of a specific DNS server! And you? Do you have other techniques to keep an eye on your DNS zones? 


Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant

5 comment(s)
Diary Archives