首页 > 解决方案 > 使用 Scapy 解析多个 DNS 响应

问题描述

尝试使用 Scapy 解析 DNS 响应(参见下面的函数)。我的问题是 rdata[] 字段中的所有答案都没有显示。当我使用 Wireshark 进行数据包捕获时,我会在该rdata[]字段中看到多个答案,对于那些不熟悉 DNS 的人来说,单个响应数据包中通常会有两个或三个答案。

我只返回一个答案(第一个)。我尝试使用sr()而不是,sr1()也尝试multi=True在发送数据包时添加作为参数,但这些都不起作用。

有任何想法吗?

def send_query_recursion(resolver, target):
dns_req = IP(dst=f'{resolver}')/UDP(dport=53)/DNS(qr=0, rd=1, qd=DNSQR(qname=f'{target}'))
answer = sr1(dns_req, verbose=1)
for received in answer:
    if received.haslayer(DNS):
        for x in received:
            print(str(x[DNS].id))
            print("rrname: " + str(x[DNSRR].rrname))
            print("Type: " + str(x[DNSRR].type))
            if str(x[DNSRR].rclass) == "1":
                print("Class: " + str(x[DNSRR].rclass) + " IN")
            print("TTL: " + str(x[DNSRR].ttl))
            print("Resource Data Length: " + str(x[DNSRR].rdlen))
            print("Resource Data: " + str(x[DNSRR].rdata[:-1]))

标签: pythonpython-3.xscapy

解决方案


我和你有同样的问题。我无法使用 scapy 解决它,所以我使用 dpkt 包来解析DNS 响应的答案,如下所示(python 3):

with open('your_pcap.pcap', 'rb') as f:
        pcap = dpkt.pcap.Reader(f)
        for timestamp, buf in pcap:
            try:
                eth = dpkt.ethernet.Ethernet(buf)
            except:
                continue
            if eth.type != 2048:
                continue
            try:
                ip = eth.data
            except:
                continue
            if ip.p != 17:
                continue
            #filter on UDP assigned ports for DNS
            try:
                udp = ip.data
            except:
                continue
            if udp.sport != 53 and udp.dport != 53:
                continue
            #make the dns object out of the udp data and
            #check for it being a RR (answer) and for opcode QUERY
            try:
                dns = dpkt.dns.DNS(udp.data)
            except:
                continue
            if dns.qr != dpkt.dns.DNS_R:
                continue
            if dns.opcode != dpkt.dns.DNS_QUERY:
                continue
            if dns.rcode != dpkt.dns.DNS_RCODE_NOERR:
                continue
            if len(dns.an) < 1:
                continue
            for qname in dns.qd:
                print("The DNS response packet has ", len(dns.an), " answers")
                print("The answers (in a list) are: ", dns.an)

您可以在以下页面上找到有关使用 dpkt 解析 DNS 的更多信息:

https://dpkt.readthedocs.io/en/latest/_modules/dpkt/dns.html

https://mmishou.wordpress.com/2010/04/13/passive-dns-mining-from-pcap-with-dpkt-python/


推荐阅读