Drop all the bad domains
From now on I will also include IPtables rules to block request for these domains and when needed the used record type.
The rules can be found on my GitHub repository.
The rules will use the u32 module to match traffic, as this is really fast.
With these rules I try not to block legitimate traffic.
If you have tips on how to better distribute or manage these rules let me know.
A rule explained:
Here I will describe the following rule to drop nearly all isc.org IN ANY noise from my Open Resolver.
iptables --insert INPUT -p udp --dport 53 -m u32 --u32 "0x1c=0x1d420100 && 0x28=0x03697363 && 0x2c=0x036f7267 && 0x30=0x0000ff00" -j DROP -m comment --comment "DROP DNS Q ANY isc.org dns.id 0x1d42"
This iptables command will add (--insert) a new rule in to the 'INPUT' chain of the firewall. All traffic goes through this chain that is destined from that computer.
Match only UDP and only traffic with a destination port of 53.
From here on I start to use the module (-m) u32 and try to find traffic that matches those hex strings. More on that later. If this matches I drop it so it does not reach the DNS service.
All my rules will include a comment to describe what it does.. as the u32 makes that a bit cryptic.
The hex part:
To fully understand the signature it is important to have a look at a DNS query packet in HEX. Here is the hex representation of the packet I based my rule on:
11:53:05.434215 IP 126.96.36.199.23722 > 188.8.131.52.53: 7490+ [1au] ANY? isc.org. (36)
0x0000: 4500 0040 bf0d 0000 7411 FFFF b816 DF81 E..@....t..f....
0x0010: 0102 0304 5caa 0035 002c 0000 1d42 0100 ....\..5.,...B..
0x0020: 0001 0000 0000 0001 0369 7363 036F 7267 .........isc.org
0x0030: 0000 FF00 0100 0029 1000 0000 8000 0000 .......)........
Green is the source IP,
Orange is the destination IP(Fake).
Red is the checksum(Fake)
DarkBlue is the DNS Transaction ID
Purple is the DNS Flags
DarkPurple is the Query Name
LightBlue are a few NULL Bytes and the Query Type and the Class (IN).
The best way to see what, means what is by using wireshark, you can click on hex values and see the representing values.
In the case of ISC.ORG I noticed a lot of the Amplification attacks are made with static source ports, but they change a lot and at any given time I see about 2 or 3 active.
But all of them are currently sharing the same DNS ID. So the first part of our signature will be to match this:
The 0x1 in 0x1c means it is on the line indicated by 0x0010 and it will be the c-st value, it is hex.. so that would be 13th value. From there on I want to match in hex the following 4 bytes (the max you can do at the time with u32:
As you can see I don't just match the DNS ID but also the DNS Flags. This is party because it is easier to match 4 bytes at the time and not use 'Masks' (to ignore parts of the 4 bytes) and also to make sure it is actually a query.
With the && you can specify multiple matches, this does not keep track of it last match position, matching start again at 0x0.
Second match is for the first 4 bytes of the domain name. This is 0369 7363 This means what follows is a 3 byte domain label: I S C. This is followed by another match from position 0x2c:
0x03 that means the same thing.. O R G (036F 7267).
The last match starts at the first byte of the 3rd line. This matches the record type and the first half of the Query Class 'IN'.
"0x1c=0x1d420100 && 0x28=0x03697363 && 0x2c=0x036f7267 && 0x30=0x0000ff00"