Blog: Cybersecurity & Cyber Defense

Blog: Cybersecurity & Cyber Defense

Windows DNS Server Sinkhole Domains Tool

This article shows you how to use a free PowerShell script to manage sinkhole DNS domains using Microsoft's Windows Server DNS. The script is easy to use and can handle tens of thousands sinkhole DNS domains on local or remote Windows DNS servers. This is a script we use in the Securing Windows and Resisting Malware course (SEC505) at SANS conferences. To get the script, download the SEC505 scripts zip file and look in the Day4-IPSecDNS-NetBIOS-LLMNR folder of that zip file.

Note: And here is a different PowerShell script to manage sinkhole names in the HOSTS file instead.

Background


DNS servers resolve names, like "www.sans.org", to IP addresses. But there are fully-qualified domain names (FQDNs) which we do not want our users to successfully resolve, e.g., the names used for malware, spyware, phishing, scams, pornography, hate groups, bandwidth-wasting video sites, social networking sites unrelated to work, etc.

Most organizations have a "split DNS" architecture where the organization's internal DNS servers forward all their Internet name resolution requests to one or a few of their external DNS servers. The external DNS servers are usually located in the DMZ of the firewall. Only the external DNS servers can communicate with the outside world. The internal DNS servers must forward the requests they can't resolve themselves to the external DNS servers.

On the external DNS servers you can create primary zones for the domain names and FQDNs you do not want your users to resolve correctly. These DNS zones will all return an incorrect IP address, such as "0.0.0.0" or the address of an internal server, not the real address. Because the organization's internal DNS servers are configured to forward their requests to these external DNS servers in the DMZ, the internal DNS servers will cache these incorrect addresses too when the external DNS servers respond. So, when an internal client tries to resolve an unwanted DNS name, it will receive a response, but the IP address returned will be incorrect. Because an IP address of "0.0.0.0" is unreachable, these unwanted zones created on the external DNS servers are said to be "blackholed", "sinklisted" or "blocklisted".

What to block? You can obtain lists of FQDNs and domain names to sinkhole for free. Some lists are only for malware, others might be just for pornography, but be aware that they are never 100% complete or accurate (you get what you pay for, so don't be surprised to find gaps a small number of false positives).

Some of the more popular sinkhole lists include (in no particular order):

From sites like the above you can download lists of FQDNs and simple domain names which can be fed into the PowerShell script for this article in order to create sinkhole zones on Windows DNS servers. If you have DNS servers running BIND, perhaps on Linux or BSD, then the sites above will also help you import sinkhole domains on those DNS servers too (scripts for sinkholing on BIND are common).

Requirements


To use the PowerShell DNS sinkhole script (download it here), you must:
  • Have PowerShell 2.0 or later on the computer where the script will be run, which may be the DNS server itself or another management workstation.
  • Use Windows Server 2003 with SP2 or later for the DNS server.
  • Allow network access to the RPC ports of the Windows Management Instrumentation (WMI) service from the workstation where the script will be run.
  • Be a member of the local Administrators group on the DNS server.

Example Uses


To see the script's command-line options (don't forget the ".&#92" before the script name):
Sinkhole-DNS.ps1 /?

get-help -full Sinkhole-DNS.ps1


To sinkhole "www.sans.org" by making it resolve to "0.0.0.0":
Sinkhole-DNS.ps1 -Domain "www.sans.org"

To sinkhole all the FQDNs and domain names listed in file.txt, removing any "www." leading strings, plus add a wildcard (*) record for each domain, all resolving to "0.0.0.0":
Sinkhole-DNS.ps1 -InputFile file.txt -IncludeWildCard -RemoveLeadingWWW

To create sinkholed domains from file.txt on a remote DNS server named "server7.sans.org" with explicit credentials (you will be prompted for the passphrase):
Sinkhole-DNS.ps1 -InputFile file.txt -DnsServerName "server7.sans.org" -Credential "server7&#92administrator"

To delete all sinkhole domains (and only the sinkhole domains this script created, nothing else):
Sinkhole-DNS.ps1 -DeleteSinkHoleDomains

Frequently Asked Questions (FAQ)


Q: Are the DNS zones replicated through Active Directory?
A: No, these are standard primary zones using a text file.

Q: If I sinkhole 10,000 domains, will the script create 10,000 zone files?
A: No, one zone file named "000-sinkholed-domain.local.dns" is used by all of them.

Q: If I'm not sitting at the DNS server, because it's remote, does that DNS server need PowerShell installed?
A: No, the local PowerShell script only talks to the WMI service on the remote DNS server.

Q: Does the DNS server need to be a member of an Active Directory domain?
A: No, it can be a stand-alone or a domain member.

Q: What if I have other primary or AD-integrated zones on my DNS server?
A: That's fine, the script will add more primary zones to whatever zones you already have.

Q: Will the script delete or modify any of my other previously-existing zones?
A: No, the script only touches the zones or domains that it created itself, your other DNS domains won't be changed.

Intrusion Detection & Forensics


By default, the script will create sinkhole zones which resolve to "0.0.0.0", but there is a command-line parameter named "-SinkholeIP" with which you can set a different IP address for all your sinkholed zones. You might consider using the IP address of an internal server set up specifically for this purpose.

Your internal sinkhole IDS server, let's call it, should listen on all the likely ports which malware or attack tools might use, especially TCP 80 (HTTP) and 21 (FTP). Enable maximum logging on it. Run a packet capture tool (like WinDump, WireShark or Network Monitor) to capture full packet payloads 24x7 using circular logging, with a large maximum capture size before wrapping, of all traffic to/from the sinkhole server itself. You can install full servers for the listening ports, such as IIS for HTTP and FTP, but be careful of unintended infections. You might instead install honeypot services, or maybe something as simple as HoneyBOT, but we need to interact enough with the client so that the details of any requests can be logged. Your perimeter firewall should block and log all traffic for your sinkhole server to/from the Internet too.

The idea is that you can examine the various logs and packet captures on your sinkhole server to help identify infected machines or those users who are attempting to violate your acceptable use policies. For example, when a workstation becomes infected, that malware may attempt to resolve a known FQDN in order to download via HTTP another piece of malware; often, you can identify the type of malware simply by the URL of the file it tried to download. You might also set a default HTML page which reminds users of your acceptable use policies (and have it mention that all Internet access is logged for the sake of HR). Don't forget that you can enable debug logging on the DNS server too.

Caveats & Legal Disclaimers


The script is fast when creating new sinkhole domains, even tens of thousands of them, but the script is slow when deleting (-DeleteSinkHoleDomains) or reloading (-ReloadSinkHoleDomains) these domains. These two operations will also run up a core of the CPU to over 90% while executing. How slow is "slow"? For example, in my testing, deleting or reloading 20,000 sinkhole domains on a 2.7GHz Core i7 CPU box with Server 2008-R2 required just over nine minutes. The poor performance is due to the WMI queries required.

The script is free and in the public domain, you may use it for any purpose whatsoever without restriction. However, that being said...

THIS SCRIPT IS PROVIDED "AS IS" WITH NO WARRANTIES OR GUARANTEES OF ANY KIND, INCLUDING BUT NOT LIMITED TO MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. ALL RISKS OF DAMAGE REMAINS WITH THE USER, EVEN IF THE AUTHOR, SUPPLIER OR DISTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH DAMAGE. IF YOUR STATE DOES NOT PERMIT THE COMPLETE LIMITATION OF LIABILITY, THEN DO NOT DOWNLOAD OR USE THE SCRIPT. NO TECHNICAL SUPPORT WILL BE PROVIDED.

Please test the script on non-production servers first, then test on a production server only during off-peak hours and only after having made a full backup.

The SANS Institute hopes you will find the script useful, so best wishes and good luck!

[Version History]
31.Aug.2010 : Initial release.
17.Jun.2012 : Renamed the script.

10 Comments

Posted September 23, 2011 at 6:10 PM | Permalink | Reply

wayne

Seems to me we could actually download the files from one or more resources (if they have a newer time stamp than the previously downloaded ones), and "automatically" add them to our server. So, I'm wondering if there was some cautionary tale that resulted in your script avoiding doing that.

Posted September 24, 2011 at 5:43 AM | Permalink | Reply

Jason Fossen

Nope, no cautionary tale, but time stamp checking could be done in a wrapper script before running the DNS script.

Posted October 23, 2011 at 3:50 PM | Permalink | Reply

Mark

On windows servers, an auto-updating and parsing mechanism that retrieves bad domains from all these places is already built into software like DNS Redirector

Posted November 03, 2011 at 5:50 PM | Permalink | Reply

Mike

@Mark - many of us block http/https traffic to/from our DNS servers since they do not need such functionality to provide their core function, DNS service. Running Jason's script from an administrative system allows the DNS servers to be more limited in their access, which I think is a good thing.

Posted March 07, 2012 at 8:17 PM | Permalink | Reply

David Boucher

I looked through the script and tested it out. Very nice, thanks for sharing it! I like that way you put the script together taking care to build objects based on the blackhole zone file you specify.

I have two questions for anyone that may feel like commenting:

1) Is there any way that you know of to separate or split forward lookup zones into multiple folders in microsoft DNS (2008R2)? Importing tens of thousands of domains makes it a pain to scroll down in the GUI to your integrated domain zone. It just makes it look messy, and is confusing for someone when they first look at it.

2) Thoughts on using conditional forwarders for the same purpose? If DNS was configured to forward those domains to a bogus IP, it would effectively black hole it as well. You would obviously lose the ability to re-direct clients to a targeted wildcard forwarder entry for purposes of IDS, etc... Aside from that, would there be any other pros/cons to doing this?

Thanks!
Dave

Posted March 07, 2012 at 9:16 PM | Permalink | Reply

Jason Fossen

Hi David:

Unfortunately, as far as I know, it's not possible organize the zones into folders like that. I agree it looks messy with thousands of domains, but we might be stuck.

Using conditional forwarders is an interesting idea, but I bet the DNS service would complain if tens of thousands were configured. I'll think about it some more too.

Cheers,
J.

Posted February 05, 2013 at 5:57 PM | Permalink | Reply

Juba

Is there a way to enable these zones for active directory integration in the script?

Posted February 06, 2013 at 1:36 AM | Permalink | Reply

Jason Fossen

Hi Juba: The script could be rewritten to use AD integration, but I think 99% of admins would prefer to use the standard zone file, so that's how I wrote it. Feel free to change it though! Cheers, J.

Posted July 03, 2013 at 7:23 AM | Permalink | Reply

Frank

Hi Jason, is there any way to sinkhole everything except certain defined domain? Thanks

Posted July 03, 2013 at 12:39 PM | Permalink | Reply

Jason Fossen

Hi Frank:
Sorry, not possible with sinkholing <i>per se</i>, but you could create the domain(s) and records you need, then disable forwarding to other DNS servers and disable recursion. You can also do conditional forwarding for just the domain(s) you need, if your server won't be authoritative for those domains.
Cheers,
Jason

Post a Comment






* Indicates a required field.