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, but it was getting to be a pain to update the list, 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 inspect each packet and only target 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.

The hackers eventually figured out how to get around the filter. Instead of just 
repeating the same false request, they would just send a slightly different 
request each time. So this version has the added ability to block known abusers.
The first time the service is activated, it creates a file in the same directory 
as the service called "DropList.txt". You can add IPv4 addresses to this list, 
and then restart the server. Requests from any server on this list will simply 
be dropped.

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 recently has been Hetzner Online GmbH (hetzner.de), 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.

To run as a Service, the program must not make any attempt to display to the 
Desktop, as this can cause the operating system to get into an endless loop 
when the user is logged off and the desktop is not available. All potential 
errors must be trapped, and logged to the Event or other log.

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 (freely available). So far, Version 2.5 has been tested on Windows Vista.

It consists of 2 programs; one is the actual service, and the other 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.

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 still see only one query in the Test program. Wait at least 30 seconds 
and try again. You should now see a second query.

Note: DNSFilSvc was designed to be run in Development mode as well as a Service. 
To compile the service, change the IsService flag to True.
