Created
December 29, 2015 15:11
-
-
Save lucab/47e2214b962234a924b0 to your computer and use it in GitHub Desktop.
Scan authoritative NS trying to AXFR zones
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
""" | |
Scan authoritative NS trying to AXFR zones. | |
Result dictionary is as follows: | |
{ | |
'domain': 'example.com', | |
'axfr_answers': {'ns1.example.com': [], | |
'ns2.example.com': [], | |
'ns3.example.com': [], | |
'ns4.example.com': [{'name': '@', | |
'pretty_name': 'example.com', | |
'pretty_rdclass': 'IN', | |
'pretty_rdtype': 'A', | |
'rdata': '', | |
'rdclass': 1, | |
'rdtype': 1, | |
'ttl': 86400}]}, | |
'nameservers': ['ns1.example.com', | |
'ns2.example.com', | |
'ns3.example.com', | |
'ns4.example.com']} | |
} | |
""" | |
__author__ = "Luca Bruno" | |
__email__ = "lucab@debian.org" | |
# this module requires dnspython | |
import bisect | |
import dns.name | |
import dns.query | |
import dns.rdataclass | |
import dns.rdatatype | |
import dns.resolver | |
import dns.zone | |
def scan_dns_axfr(domain): | |
""" | |
Scan authoritative NS trying to AXFR a zone | |
@param domain: the domain we try to AXFR | |
@type domain: string | |
@rtype: dict | |
@return: dictionary with zone info | |
""" | |
AXFR_TIMEOUT = float(10) # AXFR timeout, in seconds | |
zone_data = {'domain': domain} | |
zone_data['nameservers'] = [] | |
zone_data['axfr_answers'] = {} | |
try: | |
ns_query = dns.resolver.query(domain, 'NS').rrset | |
except Exception: | |
ns_query = [] | |
for n in ns_query: | |
zone_content = [] | |
ns = str(n).rstrip('.') | |
if not ns: | |
continue | |
bisect.insort(zone_data['nameservers'], ns) | |
zone_data['axfr_answers'][ns] = zone_content | |
try: | |
axfr_rr = dns.query.xfr(ns, domain, lifetime=AXFR_TIMEOUT) | |
axfr_zone = dns.zone.from_xfr(axfr_rr) | |
except Exception: | |
axfr_zone = None | |
if not axfr_zone: | |
continue | |
for name, ttl, rdata in axfr_zone.iterate_rdatas(): | |
entry = {'name': name.to_text(), | |
'ttl': ttl, | |
'rdclass': rdata.rdclass, | |
'rdtype': rdata.rdtype, | |
'rdata': rdata.to_text()} | |
try: | |
entry['pretty_rdclass'] = dns.rdataclass.to_text(rdata.rdclass) | |
entry['pretty_rdtype'] = dns.rdatatype.to_text(rdata.rdtype) | |
parent = dns.name.Name(domain.split('.')) | |
if name == dns.name.empty: | |
entry['pretty_name'] = parent.to_text() | |
else: | |
entry['pretty_name'] = name.concatenate(parent).to_text() | |
except Exception: | |
pass | |
zone_content.append(entry) | |
zone_data['axfr_answers'][ns] = zone_content | |
return zone_data |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment