DNSRR итерация
Если я отправляю DNSQR для www.google.com с помощью sr1, я получаю несколько ответов DNSRR, например (сделано с помощью 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? Как я использую регулярное выражение и следующий код:
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)
1 ответ
Если мы отправим запрос DNS с Scapy, мы можем получить ответ 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,
ancount - количество ответов DNS,
dns.an [0] является 1-м ДНРР,
dns.an [1] является 2-й ДНРСР,
...
мы можем проанализировать DNSRR с помощью ancount, вот мой демонстрационный код:
#!/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 stackru.com в вашей оболочке.
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 : stackru.com.
[*] response: 192.168.1.108:55391 <- 192.168.1.1:53 : stackru.com. - 198.252.206.16