scapy - DNSRR 迭代

标签 scapy

如果我使用 sr1 为 www.google.com 发送 DNSQR,我会收到几个 DNSRR(s) 作为回复,例如(使用 ans[DNSRR].show() 完成):

###[ DNS Resource Record ]###
   rrname= 'www.google.com.'
   type= A
   rclass= IN
   ttl= 294
   rdlen= 4
   rdata= '173.194.35.176'
###[ DNS Resource Record ]###
   rrname= 'www.google.com.'
   type= A
   rclass= IN
   ttl= 294
   rdlen= 4
   rdata= '173.194.35.178'
###[ DNS Resource Record ]###
   ....

有没有一种巧妙的方法来迭代这些 DNSRR(s)?我使用正则表达式和以下代码:
def get_ip_addr(s):
    pattern = r'[0-9]+(?:\.[0-9]+){3}'
    match = re.search(pattern, s)
    if match:
        return match.group()
    return None    

def resolve_host(host, nserver):
    print "resolving host: " + host + " (using nserver: " + nserver + ")"
    dns_pkt = IP(dst=nserver)/UDP()/DNS(rd=1, qd=DNSQR(qname=host))
    ans = sr1(dns_pkt)
    if ans:
        print "IP(s) for %s:" % (host)
        dnsrr_strings = repr(ans[DNSRR]).split("|")
        for dnsrr in dnsrr_strings :
            ip_addr = get_ip_addr(dnsrr)
            if ip_addr:
                print " %s"  % ip_addr
    else:
        sys.stderr.write("unable to lookup " + host)

最佳答案

如果我们使用 scapy 发送 dns 请求,我们可以得到如下的 dns 响应:

>>> dns.show()
###[ DNS ]###
id= 43223
qr= 1L
opcode= QUERY
aa= 0L
tc= 0L
rd= 1L
ra= 1L
z= 0L
rcode= ok
qdcount= 1
ancount= 3
nscount= 0
arcount= 0
\qd\
 |###[ DNS Question Record ]###
 |  qname= 'search.yahoo.com.'
 |  qtype= A
 |  qclass= IN
\an\
 |###[ DNS Resource Record ]###
 |  rrname= 'search.yahoo.com.'
 |  type= CNAME
 |  rclass= IN
 |  ttl= 5
 |  rdlen= 39
 |  rdata= 'ds-global.l7.search.ystg1.b.yahoo.com.'
 |###[ DNS Resource Record ]###
 |  rrname= 'ds-global.l7.search.ystg1.b.yahoo.com.'
 |  type= CNAME
 |  rclass= IN
 |  ttl= 96
 |  rdlen= 43
 |  rdata= 'ds-any-global.l7.search.ysta1.b.yahoo.com.'
 |###[ DNS Resource Record ]###
 |  rrname= 'ds-any-global.l7.search.ysta1.b.yahoo.com.'
 |  type= A
 |  rclass= IN
 |  ttl= 94
 |  rdlen= 4
 |  rdata= '188.125.66.104'
ns= None
ar= None

qdcount - 查询 dns 计数,
帐号 - dns 回答计数,

dns.an[0] 是第一个 DNSRR,
dns.an[1] 是第二个 DNSRR,
...

我们可以用 解析 DNSRR帐号 ,这是我的演示代码:
#!/usr/bin/env python
# -*- coding: utf8 -*-

from scapy.all import *


# disable verbose mode
conf.verb = 0


def parse_dnspkt(pkt):
    """ parse dns request / response packet """
    if pkt and pkt.haslayer('UDP') and pkt.haslayer('DNS'):
        ip = pkt['IP']
        udp = pkt['UDP']
        dns = pkt['DNS']

        # dns query packet
        if int(udp.dport) == 53:
            qname = dns.qd.qname

            print "\n[*] request: %s:%d -> %s:%d : %s" % (
                ip.src, udp.sport,
                ip.dst, udp.dport,
                qname)

        # dns reply packet
        elif int(udp.sport) == 53:
            # dns DNSRR count (answer count)
            for i in range(dns.ancount):
                dnsrr = dns.an[i]
                print "[*] response: %s:%s <- %s:%d : %s - %s" % (
                    ip.dst, udp.dport,
                    ip.src, udp.sport,
                    dnsrr.rrname, dnsrr.rdata)


def sniffer():
    sniff(filter="udp port 53", prn=parse_dnspkt)


if __name__ == "__main__":
    sniffer()

执行 nslookup search.yahoo.com nslookup stackoverflow.com 在你的 shell 里。
root:scapy/ #  python scapy-dns_sniff.py
WARNING: No route found for IPv6 destination :: (no default route?)

[*] request: 192.168.1.108:59199 -> 192.168.1.1:53 : search.yahoo.com.
[*] response: 192.168.1.108:59199 <- 192.168.1.1:53 : search.yahoo.com. - ds-global.l7.search.ystg1.b.yahoo.com.
[*] response: 192.168.1.108:59199 <- 192.168.1.1:53 : ds-global.l7.search.ystg1.b.yahoo.com. - ds-any-global.l7.search.ysta1.b.yahoo.com.
[*] response: 192.168.1.108:59199 <- 192.168.1.1:53 : ds-any-global.l7.search.ysta1.b.yahoo.com. - 188.125.66.104

[*] request: 192.168.1.108:55391 -> 192.168.1.1:53 : stackoverflow.com.
[*] response: 192.168.1.108:55391 <- 192.168.1.1:53 : stackoverflow.com. - 198.252.206.16

关于scapy - DNSRR 迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12501780/

相关文章:

python - 在scapy中通过物理环回发送数据包

python - 使用 Python 2.7 在 Windows 上运行 Scapy

HTTP响应;有效载荷的总大小

python - 使用 Scapy 模块 (python) 从 pcap 文件获取特定包

python - 了解 Python struct.pack 和二进制输入

python - 为什么 scapy 在 Mac 上安装失败?

python - Scapy 发送/接收的定义是什么?

python - Apache Spark 将哪些数据传送到执行节点

linux - Scapy 不发送具有全局范围目标地址的 IPv6 数据包

python - 使用 scapy 和 python 将 MAC 地址记录到 csv