Clik here to view.

Simple and Powerful Testing with Scapy – Part II
Use Scapy for DNS fuzzing tests on CloudShield DNS Defender®
In a previous post, I shared about the advantages of using Scapy for DNS testing. In this post, I’ll provide some examples on how to use it for testing and demonstrations of CloudShield DNS Defender.
DNS Defender is a DNS firewall specifically designed to protect and enhance performance of DNS server farms. It takes advantage of the patented CloudShield Deep Packet Inspection (DPI) technology to analyze the whole content of every single packet, perform sanity checks, and enforce control.
While signature-based solutions, like Intrusion Prevention Systems (IPS), rely on specific patterns (signatures) to identify and block malformed or attack packets among the traffic (blacklisting), DNS Defender takes a different approach. By enforcing RFC compliance and techniques like stateful tracking of DNS transactions, DNS Defender ensures that any packet that deviates from the standards and not explicitly allowed by the custom rules is properly identified, logged, and blocked (whitelisting).
When demonstrating DNS Defender to customers, Scapy is handy to help generate multiple types of malformed DNS packets. We can then show how DNS Defender is capable of identifying, logging, and controlling these packets.
DNS fuzzing made easy
Fuzzing is a technique commonly used for security testing. It uses unexpected input or random data and puts it into a device, so we can examine how it behaves.
With Scapy, fuzzing testing can be accomplished by using a built-in function, capable of randomizing every single field on the DNS packet that is not explicitly defined.
For example, it’s possible to randomize all fields on the DNS packet with the following command:
packet=IP(src=RandIP(), dst='192.168.0.1')/UDP(dport=53)/fuzz(DNS(qd=fuzz(DNSQR()), an=fuzz(DNSRR())))
A packet created with the command above would look like this:
>>> packet.show() ###[ IP ]### version = 4 ihl = None tos = 0x0 len = None id = 1 flags = frag = 0 ttl = 64 proto = udp chksum = None src = 60.25.127.155 dst = 192.168.0.1 \options \ ###[ UDP ]### sport = domain dport = domain len = None chksum = None ###[ DNS ]### id = <RandShort> qr = <RandNum> opcode = <RandNum> aa = <RandNum> tc = <RandNum> rd = <RandNum> ra = <RandNum> z = <RandNum> rcode = <RandNum> qdcount = 1 ancount = 1 nscount = 0 arcount = 0 \qd \ |###[ DNS Question Record ]### | qname = <RandBin> | qtype = <RandShort> | qclass = <RandShort> \an \ |###[ DNS Resource Record ]### | rrname = <RandBin> | type = <RandShort> | rclass = <RandShort> | ttl = <RandInt> | rdlen = 210 | rdata = <RandBin> ns = None ar = None
Controlling the madness
Sometimes the goal is to test specific fields and combinations, instead of just randomizing all the fields with the fuzzing function. In this case, Scapy allows you to select how and which fields should be randomized.
Imagine, for example, that you want to play with different Opcodes, along with multiple combinations of the QR (query/response) and AA (authoritative answer) flags. You may also want to use random strings as domain names and issue queries using random IP addresses as the source. The command to create packets with such combinations could be:
packet=IP(src=RandIP(), dst='192.168.0.1')/UDP(sport=RandShort(), dport=[53])/ DNS(opcode=RandNum(0,15), aa=RandNum(0,1), qr=RandNum(0,1), qd=DNSQR(qname=RandString()))
Here is a how a packet from the command above would look:
>>> packet.show() ###[ IP ]### version = 4 ihl = None tos = 0x0 len = None id = 1 flags = frag = 0 ttl = 64 proto = udp chksum = None src = 161.184.24.220 dst = 192.168.0.1 \options \ ###[ UDP ]### sport = <RandShort> dport = ['domain'] len = None chksum = None ###[ DNS ]### id = 0 qr = <RandNum> opcode = <RandNum> aa = <RandNum> tc = 0 rd = 0 ra = 0 z = 0 rcode = ok qdcount = 1 ancount = 0 nscount = 0 arcount = 0 \qd \ |###[ DNS Question Record ]### | qname = <RandString> | qtype = A | qclass = IN an = None ns = None ar = None
Any other ideas?
Scapy enables you to generate all sorts of DNS packets and create different test scenarios by changing a single command line.
I hope the examples above give you a greater understanding of how convenient, simple, and powerful Scapy is for DNS testing. Considering that these examples only scratch the surface of Scapy capabilities, imagine how flexible and powerful Scapy can be when you really put it to the grindstone.
Do you have any interesting DNS tests you want to share? Or if you’d like me to create a specific test scenario, let me know in the comments. I’d love to hear about it.
Python is a registered trademark of Python Software Foundation
DNS Defender and CloudShield are registered trademarks of CloudShield Technologies
Clik here to view.