Reputation: 143
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)
Upvotes: 3
Views: 21838
Reputation: 1
I wrote a tool recently, I think you mean something like this #!/usr/bin/env python
from scapy.all import *
from datetime import datetime
import time
interface = 'eth0'
filter_bpf = 'udp and port 53'
def process_dns(pkt):
if DNSQR in pkt and pkt.dport == 53:
print('[**] Detected DNS Query at: ' + str(datetime.datetime.now()))
print('Source IP: ' + pkt[IP].src)
print('Destination IP: ' + pkt[IP].dst)
print('Source Port: ' + str(pkt[UDP].sport))
print('Destination Port: ' + str(pkt[UDP].dport))
print('Query Name: ' + pkt[DNSQR].qname.decode('utf-8'))
print('Query Type: ' + str(pkt[DNSQR].qtype))
elif DNSRR in pkt and pkt.sport == 53:
print('[**] Detected DNS Response at: ' + str(datetime.datetime.now()))
print('Source IP: ' + pkt[IP].src)
print('Destination IP: ' + pkt[IP].dst)
print('Source Port: ' + str(pkt[UDP].sport))
print('Destination Port: ' + str(pkt[UDP].dport))
print('Response Name: ' + pkt[DNSRR].rrname.decode('utf-8'))
print('Response Type: ' + str(pkt[DNSRR].type))
sniff(iface=interface, filter=filter_bpf, store=0, prn=process_dns)
Upvotes: 0
Reputation: 34207
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
Upvotes: 3
Reputation: 3134
>>> 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.
Upvotes: 3