DNS Sinkholing with BIND9 (DNS Series:Part III)

4 minute read

Like talked earlier DNS is just like a phone book in your cell phone that maps the names to the phone number. The benefit of this is that you don’t have to memorize the lengthy numbers. When you have to call someone we just have to search in the number and call it won’t matter if you remember the number or not. But imagine someone changes the underlying phone number without your knowledge, you will definitely call someone else. If the destination receiver can mimic the voice then you are totally screwed before you know it.

Image the exact scenario in your DNS server, to add to the problem your DNS is more publicly accessible than your phone. So it is primally important to protect your DNS server. We gonna use our DNS server to route the traffic of the malicious sites to a sinkhole. Since almost all browsers work with the domain names instead of IP address DNS sinkhole is the best option in hand to prevent the organization from malignment sites.

DNS Sinkholing played an important role in de-weaponizing the WannaCry Ransomware. Basically, WannaCry infections entered organization network through emails and propagated in the network via SMB ports which were the SMB vulnerability for which Windows had released a patch 2 months earlier. So infection had a kill switch built into it which would check whether a certain gibberish URL led to a live web page. Someone found with and registered the website and entire thing was stopped. It was such a naive kill switch for such disastrous internet phenomena. Off course this was intentional kill switch to tame the monster they have created but was really not thought through. As it turns out, that $10.69 investment was enough to shut the whole thing down—for now, at least.

Lets create a DNS server for sinkholing unwanted sites.


1. Normal DNS architecture

DNS server

2. Sinkholed DNS Server architecture

DNS server

So actuall we are configuring the bind to route a particular domains to sink hole server.

Configure bind for sinkholing

After we have configured bind like here lets configure a new zone files. Create a zone file in /etc/bind/zones folder, lets name it sinkhole.zone.file and populate it as

  ;file /etc/bind/zones/sinkhole.zone.file
  ; BIND db file for ad servers - point all addresses to an invalid IP
  $TTL  864000  ; ten days

  @       IN      SOA     localhost.      root.localhost. (
                        2008032800       ; serial number YYMMDDNN
                        288000   ; refresh  80 hours
                        72000    ; retry    20 hours
                        8640000  ; expire  100 days
                        864000 ) ; min ttl  10 day
                NS      localhost.


  *   IN      A

What this zone file is doing is rediecting all domain pointed to this zone file to our sinkhole server which my case). You might notice we have set TTL value to 10 days so that they are be cached for longer time.

Now lets do the main part, lets gather the malicious sites and make them point to our sinhole zone file.

First create a confuration for blocking sites. for this create a file named.conf.blocked in ‘‘/etc/bind/’’ and populate it with sites which needs to be blocked. Add this configuration to named.conf as :

    // This is the primary configuration file for the BIND DNS server named.
   // Please read /usr/share/doc/bind9/README.Debian.gz for information on the 
   // structure of BIND configuration files in Debian, *BEFORE* you customize 
   // this configuration file.
   // If you are just adding zones, please do that in /etc/bind/named.conf.local

   include "/etc/bind/named.conf.blocked";
   include "/etc/bind/named.conf.options";
   include "/etc/bind/named.conf.local";
   include "/etc/bind/named.conf.default-zones";

We need to populate the block conf to point to our sinkhole zone file. I am using this project to get all malicious sites, I am sure you can find pretty more like these. This file looks like this:

   zone "2-dot-mod-ads-dot-house-ads-server.appspot.com" { type master; notify no; file "/etc/bind/zones/sinkhole.zone.file"; };
   zone "lb0-telemetry-prod-us-east-1.servers.getgo.com" { type master; notify no; file "/etc/bind/zones/sinkhole.zone.file"; };
   zone "xn--80aebbcbcdemfkhba4byaehoejh8dza3v.xn--p1ai" { type master; notify no; file "/etc/bind/zones/sinkhole.zone.file"; };
   zone "howupdateworks.amazingupdates4youtoday.website" { type master; notify no; file "/etc/bind/zones/sinkhole.zone.file"; };
   zone "getsoftnow.smallandprecise2upgradingnew.review" { type master; notify no; file "/etc/bind/zones/sinkhole.zone.file"; };
   zone "pornographo.blogspot.com.tr.br.blogspot.com.tr" { type master; notify no; file "/etc/bind/zones/sinkhole.zone.file"; };
   zone "buying.mobile.online.phone.samsung.uk.sms13.de" { type master; notify no; file "/etc/bind/zones/sinkhole.zone.file"; };
   zone "upgrade.themainplacesetnowforcontentingnew.bid" { type master; notify no; file "/etc/bind/zones/sinkhole.zone.file"; };

For testing purpose I have setup a webserver in sinkhole server. We can use Intrusion Detection System as fail2ban to tracking and alerting purpose.

I have setup a client machine pointing to our DNS server which is We can do this in ubuntu linux by editing /etc/resolv.conf file manually.

  # file: /etc/resov.conf


Now lets query a malicious domain in our blocked configuration.

Client$ dig usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com


   ; <<>> DiG 9.11.4-4-Debian <<>> usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54212
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 3

; EDNS: version: 0, flags:; udp: 4096
;usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com. IN  A

usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com. 864000 IN A

usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com. 864000 IN NS localhost.

localhost.    604800  IN  A
localhost.    604800  IN  AAAA  ::1

;; Query time: 0 msec
;; WHEN: Sun Sep 09 16:09:30 +0545 2018
;; MSG SIZE  rcvd: 171

You see it routes to our webserver

Now lets curl it

curl -v usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com


    * Rebuilt URL to: usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com/
    *   Trying
    * TCP_NODELAY set
    * Connected to usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com ( port 80 (#0)
    > GET / HTTP/1.1
    > Host: usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com
    > User-Agent: curl/7.61.0
    > Accept: */*
    < HTTP/1.1 200 OK
    < Date: Sun, 09 Sep 2018 10:27:07 GMT
    < Server: Apache/2.4.18 (Ubuntu)
    < Last-Modified: Sat, 08 Sep 2018 16:49:46 GMT
    < ETag: "1b-5755ee95ea784"
    < Accept-Ranges: bytes
    < Content-Length: 27
    < Content-Type: text/html
    <p> You are sinkholed </p>
    * Connection #0 to host usaa.com-inet-truememberent-iscaddetour-verify.kurusfit.com left intact

That it how its got sinkholed to our webserver