Please consider donating: https://www.corelan.be/index.php/donate/


7,501 views

A chain is only as strong as its weakest link – DNS Hijack Monitoring

It doesn’t really matter how much time your developers have spent writing secure code and how many layers of security you have implemented to protect your website from being hacked and defaced.  Recent incidents have demonstrated that the bad guys will simply look for and find an easier way to hurt your business. 

Instead of going after vulnerabilities in the website itself, they’ll focus on a potentially weaker link in the system: the DNS registrar.  All they have to do is "convince" the right person (via e-mail, fax, etc) or by guessing username/password in the management console for DNS, by hacking into a DNS hosting company, that an update to your public DNS records is legit.  A few moments later, the internet won’t be looking at your website anymore.

You could use tools to monitor the content of your websites & report back when significant changes are made, but as the content of websites often changes, you’ll find yourself updating your tools quite often.  Perhaps an easier approach would be to also monitor the DNS records and report when an IP address has changed.

Getting started

I decided to hack a little python script together that allows you to do that.  You can get a copy of the script at https://github.com/corelan/dnshjmon  or simply clone the repository:

root@krypto1:/dns# git clone https://github.com/corelan/dnshjmon.git
Cloning into 'dnshjmon'...
remote: Counting objects: 54, done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 54 (delta 28), reused 43 (delta 17)
Unpacking objects: 100% (54/54), done.
root@krypto1:/dns# 

Setting up the configuration

The script uses 2 configuration files:

  • a file that contains the hostnames you want to monitor, and the valid IP (one, multiple, or even CIDR notations)
  • a file that contains the configuration about how to send email reports

DNS Config file

This is a flat ascii file (dnshjmon_dns.conf) that contains the list with hostnames that need to be checked and the list with valid IPs for that hostname.

hostname=ip

You can specify multiple IP addresses and/or even use CIDR notation. Simply separate entries with a comma:

hostname=127.0.0.1,192.168.0.1/25

If you want to exclude a certain IP, prefix it with a dash

hostname=127.0.0.1,192.168.0.1/25,-192.168.0.5

You can, obviously, specify as many hostnames as you want.

You can specify an alternative path for the dns configuration file using the -d argument.

SMTP Config file

This file (dnshjmon_smtp.conf) will be created the first time you run dnshjmon.py, using an interactive wizard.

(master) root@krypto1:/dns/dnshjmon# python dnshjmon.py 

     __                __     __                         
 .--|  |.-----..-----.|  |--.|__|.--------..-----..-----.
 |  _  ||     ||__ --||     ||  ||        ||  _  ||     |
 |_____||__|__||_____||__|__||  ||__|__|__||_____||__|__|
                            |___|                        
                        [ corelanc0d3r - www.corelan.be ]
 
[+] Using dns config file /dns/dnshjmon/dnshjmon_dns.conf
[-] Oops, email config file /dns/dnshjmon/dnshjmon_smtp.conf doesn't exist yet
[+] Creating a new config file.
    > Enter smtp mail server IP or hostname: 127.0.0.1
    > Enter mail server port (default: 25): 
    > Enter 'From' email address: peter.ve@corelan.be
    > Enter 'To' email address: peter.ve@corelan.be
    > Enter mail server timeout (in seconds, default: 300): 
    > Does server require authentication? (yes/no, default: no): 
    > Does server require/support STARTTLS ? (yes/no, default: no): 
[+] Saved new config file

You can specify an alternate path to the configuration file using the -s parameter.

If you want to add additional mailserver configurations or change the existing one, simply edit the conf file.

You can test if the mail configuration works correctly by using the -mail argument. By default, emails will be sent with high-priority and requesting a return-receipt.

Can I use custom nameservers (other than the ones configured on the OS level) ?

Sure you can, but you’ll need to install the python-dnspython library from www.dnspython.org.  On Ubuntu / Kali, this is as easy as running apt-get install python-dnspython.  On Windows, you need to extract the archive and run setup.py or, alternatively, just copy the ‘dns’ subfolder to c:\python27\lib\site-packages.

When dnshjmon detects that the library is installed, it will expose a -n argument, which allows you to specify the full path to a flat file that contains the IP address or addresses (one IP per line) of the DNS server(s) you want to use for queries.

Using the script

After setting up the configuration files, all you have to do is schedule the script to run (every half an hour, for example).  When a mismatch is found, an email will be sent.

It may not be a bad idea to configure your monitoring box to use Google or OpenDNS for DNS resolution. Furthermore, if you run this script on a windows box, maybe create a little batch file that will also call ipconfig /flushdns prior to running the python script.  It might be a good idea to run a git pull from time to time, as I may be adding new features some time in the future.

If all goes well, the output (on screen) will look like this:

(master) root@krypto1:/dns/dnshjmon# python dnshjmon.py

     _                __     __
 .--|  |.-----..-----.|  |--.|__|.--------..-----..-----.
 |  _  ||     ||__ --||     ||  ||        ||  _  ||     |
 |_____||__|__||_____||__|__||  ||__|__|__||_____||__|__|
                            |___|
                        [ corelanc0d3r - www.corelan.be ]
 
[+] Using dns config file /dns/dnshjmon/dnshjmon_dns.conf
[+] Using mail config file /dns/dnshjmon/dnshjmon_smtp.conf

[+] Running DNS check
[+] Using OS DNS configuration for queries

Results:
--------
1. www.corelan.be - check OK? : true (['178.79.152.9']) 

[+] Done checking, tested 1 sites, reported 0 IP mismatches

if an issue is found, you’ll see this:

(master) root@krypto1:/dns/dnshjmon# python dnshjmon.py

     _                __     __
 .--|  |.-----..-----.|  |--.|__|.--------..-----..-----.
 |  _  ||     ||__ --||     ||  ||        ||  _  ||     |
 |_____||__|__||_____||__|__||  ||__|__|__||_____||__|__|
                            |___|
                        [ corelanc0d3r - www.corelan.be ]
 
[+] Using dns config file /dns/dnshjmon/dnshjmon_dns.conf
[+] Using mail config file /dns/dnshjmon/dnshjmon_smtp.conf

[+] Running DNS check
[+] Using OS DNS configuration for queries

Results:
--------
1. www.corelan.be - check OK? : false (['178.79.152.9'] : Record manipulated?)

[+] Done checking, tested 1 sites, reported 1 IP mismatches

**************************************************
1 DNS record(s) may have been manipulated:
20131231-09:43:26: www.corelan.be resolves to 178.79.152.9, but it should be ['178.79.152.8']
**************************************************
[+] Config file appears to contain 1 mail server definitions
[+] Checking if 172.0.0.1:25 is reachable
    Yup, port is open
[+] Connecting to 127.0.0.1 on port 25
[+] Connected
[+] Sending email
[+] Mail sent, disconnecting

Suppose you want to use the google DNS server 8.8.8.8 instead of the OS DNS server configuration and you have installed python-dnspython, then simply create a file (nameservers.conf or something like that) and put 8.8.8.8 in that file. Tell dnshjmon to use that file and the output will look like this:

(master) root@krypto1:/dns/dnshjmon# python dnshjmon.py -n nameservers.conf

     _                __     __
 .--|  |.-----..-----.|  |--.|__|.--------..-----..-----.
 |  _  ||     ||__ --||     ||  ||        ||  _  ||     |
 |_____||__|__||_____||__|__||  ||__|__|__||_____||__|__|
                            |___|
                        [ corelanc0d3r - www.corelan.be ]
 
[+] Using dns config file /dns/dnshjmon/dnshjmon_dns.conf
[+] Using mail config file /dns/dnshjmon/dnshjmon_smtp.conf

[+] Running DNS check
[+] Using 1 DNS server(s) for queries:
    ['8.8.8.8']

Results:
--------
1. www.corelan.be - check OK? : true (['178.79.152.9']) 

[+] Done checking, tested 1 sites, reported 0 IP mismatches

The script was written and tested against python 2.7 and should run out of the box on Windows, Linux and Mac OS.

Enjoy !


© 2013, Peter Van Eeckhoutte (corelanc0d3r). All rights reserved.

3 Responses to A chain is only as strong as its weakest link – DNS Hijack Monitoring

Corelan Training

We have been teaching our win32 exploit dev classes at various security cons and private companies & organizations since 2011

Check out our schedules page here and sign up for one of our classes now!

Donate

Want to support the Corelan Team community ? Click here to go to our donations page.

Want to donate BTC to Corelan Team?



Your donation will help funding server hosting.

Corelan Team Merchandise

You can support Corelan Team by donating or purchasing items from the official Corelan Team merchandising store.

Protected by Copyscape Web Plagiarism Tool

Corelan on Slack

You can chat with us and our friends on our Slack workspace:

  • Go to our facebook page
  • Browse through the posts and find the invite to Slack
  • Use the invite to access our Slack workspace
  • Categories