Python/Scapy DNS嗅探器和解析器

3

我有一个用于DNS的Python/Scapy嗅探器。我能够嗅探DNS消息并获取IP/UDP源和目标IP地址和端口,但是我在解析DNS部分时遇到了问题。我希望能得到一些帮助或解决方案来解决这个问题。

#!/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)
3个回答

3

我在谷歌搜索“scapy解析DNS查询”时,来到了这里(在我的情况下,我正在处理一个捕获的pcap文件)。

这是我的解决方案:

#!/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

3
>>> 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           = ('')
>>> 

如果上述层定义和字段不足够,您可以定义自己的层并使用自定义层解码数据包,或者直接从原始有效载荷中检索数据。至于时间戳,您可以使用pkt.time。

谢谢,但我有关于额外答案和额外记录的问题。我无法获取它们。 - user1627588
@user1627588 真糟糕,通过编辑您的原始问题,我的答案现在似乎完全不相关了。请不要在将来这样做。无法检索字段和无法在特定问题下检索字段是两个完全不同的问题。 - wookie919
抱歉,你是完全正确的。在编辑后,你的回答似乎不相关。我没有想到这一点。我根本没有考虑过。我应该把它改回来吗? - user1627588
@user1627588 如果可以的話,我認為最好將問題改回實際上所問的內容,然後你可以提交一個新的問題,其中包含更具體的版本。希望你的新問題能獲得一些答案。乾杯! - wookie919
@user1627588 嘿,没问题,我甚至不确定我的答案是否真的值得被接受为答案。在我的回答中,我只是试图指出显而易见的东西,以防你错过了什么。再次干杯。 - wookie919
显示剩余2条评论

0
我最近写了一个工具,我想你是指这样的东西 #!/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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接