python/scapy DNS sniffer and parser

17,523

Solution 1

>>> ls(DNS)
id         : ShortField           = (0)
qr         : BitField             = (0)
opcode     : BitEnumField         = (0)
aa         : BitField             = (0)
tc         : BitField             = (0)
rd         : BitField             = (0)
ra         : BitField             = (0)
z          : BitField             = (0)
rcode      : BitEnumField         = (0)
qdcount    : DNSRRCountField      = (None)
ancount    : DNSRRCountField      = (None)
nscount    : DNSRRCountField      = (None)
arcount    : DNSRRCountField      = (None)
qd         : DNSQRField           = (None)
an         : DNSRRField           = (None)
ns         : DNSRRField           = (None)
ar         : DNSRRField           = (None)
>>> ls(DNSQR)
qname      : DNSStrField          = ('.')
qtype      : ShortEnumField       = (1)
qclass     : ShortEnumField       = (1)
>>> ls(DNSRR)
rrname     : DNSStrField          = ('.')
type       : ShortEnumField       = (1)
rclass     : ShortEnumField       = (1)
ttl        : IntField             = (0)
rdlen      : RDLenField           = (None)
rdata      : RDataField           = ('')
>>> 

If the above layer definitions and fields are not enough, you can either define your own layer and decode the packet using your custom layer, or simply retrieve the data straight from the raw payload. As for the timestamp, you can do pkt.time.

Solution 2

I landed here while Googling scapy parse DNS queries (in my case i'm dealing with a captured pcap file)

this is my solution:

#!/usr/bin/env python

from scapy.all import *
from scapy.layers.dns import DNSRR, DNS, DNSQR

pcap = '/path/.../to/.../pcap/.../.pcap'
pkts = rdpcap(pcap)

for p in pkts:
    if p.haslayer(DNS):   
        if p.qdcount > 0 and isinstance(p.qd, DNSQR):
            name = p.qd.qname
        elif p.ancount > 0 and isinstance(p.an, DNSRR):
            name = p.an.rdata
        else:
            continue

        print name
Share:
17,523
user1627588
Author by

user1627588

Updated on June 26, 2022

Comments

  • user1627588
    user1627588 almost 2 years

    I have python/scapy sniffer for DNS. I am able to sniff DNS messages and get IP/UDP source and destination IP address and ports but I have problems parsing DNS part I would appreciate some help or solution to work this out.

    #!/usr/bin/env python
    
    from scapy.all import *
    from datetime import datetime
    import time
    import datetime
    import sys
    
    ############# MODIFY THIS PART IF NECESSARY ###############
    interface = 'eth0'
    filter_bpf = 'udp and port 53'
    
    # ------ SELECT/FILTER MSGS
    def select_DNS(pkt):
        pkt_time = pkt.sprintf('%sent.time%')
    # ------ SELECT/FILTER DNS MSGS
        try:
            if DNSQR in pkt and pkt.dport == 53:
            # queries
               print '[**] Detected DNS QR Message at: ' + pkt_time
               # 
            elif DNSRR in pkt and pkt.sport == 53:
            # responses
               print '[**] Detected DNS RR Message at: ' + pkt_time
     # 
        except:
            pass
    # ------ START SNIFFER 
    sniff(iface=interface, filter=filter_bpf, store=0,  prn=select_DNS)
    
  • user1627588
    user1627588 almost 10 years
    thx but i have problems with additional answers and additional records. I am not able to get them
  • wookie919
    wookie919 almost 10 years
    @user1627588 Ugh, by editing your original question, my answer now seems almost completely irrelevant. Please don't do this in the future. The question of not being able to retrieve fields, and not being able to retrieve fields under certain specific questions are two completely different questions.
  • user1627588
    user1627588 almost 10 years
    sorry man. You are completely right. Your answer does not seems relevant after editing. I did not think this way. I did not think at all. Should i somehow change it back?
  • wookie919
    wookie919 almost 10 years
    @user1627588 If you can, I think it would be best to change the question back to what it was actually asking before, and you can simply submit a new question with your more specific version. Hopefully your new question will get some answers. Cheers.
  • user1627588
    user1627588 almost 10 years
    i did it and changed the question back. sorry once again
  • wookie919
    wookie919 almost 10 years
    @user1627588 Hey, no problem, I am not even sure whether my answer really deserves to be accepted as an answer. In my answer I was just trying to point out the obvious stuff in case you have missed anything. Again, cheers.
  • user1627588
    user1627588 almost 10 years
    yeap. you did help me as well as some nice people out there. i just started learning python as pastime 4 months ago and any help is appreciated