Our DNS server was being used as an attack vector against primarily Chinese servers. DNS by preference uses UDP packets instead of TCP packets. The UDP protocol is much faster than TCP, but unlike TCP it does not perform a handshake. It is essentially one way communication with no confirmation of receipt. Because of that, it is possible to fake the sender IP address, and this is what the attackers were doing. A 128 byte request was causing a 388 byte invalid response to be sent to the target server. By enlisting many hacked computers, the attackers could overwhelm the target. Because the hackers were sending false source information to legitimate DNS servers, it was difficult to track the actual source.

Our DNS server has the capability to block source addresses that send too many requests per second. However, the hackers soon discovered that and started sending from groups of IP addresses. That necessitated me manually adding to the Block file, and that was getting to be a pain, and the list itself was getting quite long. So I set about to design a filter. For this purpose I am using the Windows Packet Filter Kit from NT Kernel Resources. This high performance packet filtering framework hooks the NDIS (Network Driver Interface Specification) driver in your Windows Operating System. This allows me to filter out only the incoming Port 53 UDP packets for further processing. A 20 element cache is maintained with the Source IP Address, the Question Type, the Question, and a Timeout. When a DNS request is received, the program checks the cache and if does not exist or is timed out, it is added with the maximun timeout. If it already exists, the timeout is reset to the maximum and the record dropped. A timer decrements the timeout values every second.

I had considered building this progam some time ago because some abusive DNS servers were using brute force by sending multiple requests for the same thing. The worst offender was Yahoo, which not only sent multiple requests from the same server, but also used multiple servers for the same thing. These hackers only served to elevate the priority.

The Service version of DNS Filter not only requires the WinpkFilter from NT Kernel Resources (free for personal use) but also the NT Service Control from Microsoft (included). So far it has been tested on Server 2000 and Windows Vista.

It consists of 2 programs; one is the actual service (DNSFilSvc.exe), and the other (DNSFilter.exe) to load and manage the Service. Although the service can install itself, the management program is needed to store a couple of paramters. Saving the GUID of the Ethernet Interface is necessary because the order in which the Interfaces are loaded changes with every boot. Because the Service runs in Session 0, the Registry values must be placed in the Registry in a location that allows System access. The same applies to the Log Files. They are placed in the %SystemRoot%\System32\Logfiles\DNS\ directory. Because the management program runs in Session 1 or more, it has no actual interaction with the service. It deals entirely with the Service Manager. I used to use the System Tray for interaction between a service and the desktop, but that is now difficult to do with Session Isolation. I also used to use the Dart Service Control (which I prefer), but that requires the user to purchase a license.

There is not much to look at because this program runs as a service.

The management program shown above simplifies the installation and management of the service. However, once the service has been installed and setup, the Service Manager (services.msc) can be used to manage the service. Using the Service Manager, you can change the StartUp Type to Automatic from Manual, so that the service will start at bootup.

So how can you tell if the program is doing anything. To test the DNS Filter, I have included a small test program called TestDNS.exe. It doesn't do much but listen on port 53 for UDP packets. When it receives a DNS query, it places the name queried in the Text Box. Run the Filter and Test program on one machine, and go to another machine on your network and run "Nslookup" in the command mode. Change the server to the IP address where the Test program is running, and enter a domain to query. The Test program will not provide a response, but you should see a single query (not 2). Use the F3 key to query the same name again. You should only see one query in the Test program. Wait at least 30 seconds and try again. You should now see a second query.

> server
> yellowhead.com
Server: []
DNS request timed out.
timeout was 2 seconds.
DNS request timed out.
timeout was 2 seconds.
Name: yellowhead.com

Bug Fix 11/12/2013: A bug was discovered that randomly allowed some duplicated queries to get through the filter. A fixed length buffer (128 bytes) was maintained to receive incoming query names. This string information was of variable length, but always ended in a null character. When the name was added to the string array, VB only recognized up to the null character. If the previous query was longer than the current one, extra characters got left behind in the fixed length buffer. For example, if "12345678.com" was followed by "123456.com", what was shown in the buffer was "123456.com m", which of course did not compare to what was already in cache. This was corrected by clearing the fixed length buffer after every query. At the same time, table updates were sped up by maintaining an end of cache pointer.

Back to Top

| Home Page