So the second piece of code in my series on the python & Scapy lovefest is another simple bit of code that looks through a pcap file and pulls out some DNS information. The initial thought behind this was making it easy to look for DNS domains that might be “dodgy”, i.e. has lots of DNS answer records and a low(ish) TTL.
Now the downside of using Scapy to look at DNS records is that it’s very very difficult to pull out all the DNS answer records (the IP’s) that might be contained in a DNS Response packet. They are essentially nested in the Scapy packet and I haven’t worked out a way to return them all (yet). However fear not my packet warriors there is a DNS ancount field which tells you have many answers exist in the DNS response, so I’ve used that as a measure of how “dodgy” the domain is.
Again the script can be found on my GitHub repo HERE:
To run the script you simply need to do this:
./pcap-dns.py pcapfile
I’m not going to post the code on the post this time (formatting is a bitch) but you should get something like this back (I used a fastflux pcap file for the demo).
The red coloured lines are DNS responses that have over 4 IP addresses in the response, you can change this in the code if you want but it does give you a good idea of what is going on. I also throw back the TTL because if it is something like Fast Flux it would probably have a high number of ancount records and a low TTL.
Simples..
This is a very well written script, that I have adapted for a fast-flux detection script, that also incorporates low TTLs as a fast-flux indicator. Well done!
I know this article is several years old, but it’s still one of the first Google results for searches referencing Scapy and DNS. I figured out how to extract data from DNS responses a little better, and want to share for the benefit of others.
A DNS response packet gets broken up by Scapy into a few segments, and using the DNS, DNSQR, DNSRR, etc keywords aren’t the best ways to search through them.
All the DNS header information can be obtained using packet[DNS].. These include qdcount, ancount, nscount, and arcount, representing the number of queries, answers, name servers, and additional records in the packet.
The best way to access each one of those segments is to reference the segment variable. For example, to return the name of the query, you can use packet[DNS].qd.qname.
Likewise, to return the names of all the answers…
for x in range(packet[DNS].ancount):
print(packet[DNS].an[x].rrname
Similar operations can be performed on packet[DNS].ns and packet[DNS].ar