Finalized code more, README cleaned up

This commit is contained in:
Dionysus 2023-10-28 21:40:06 -04:00
parent 31b36e68b4
commit a4987c6447
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
2 changed files with 83 additions and 26 deletions

View File

@ -1,17 +1,25 @@
# Mass DNS AXFR (Zone Transfer)
# STILL FINISHING THIS - JUST UPLOADING PROGRESS
###### This script will attempt a [Zone Transfer](https://en.wikipedia.org/wiki/DNS_zone_transfer) on all of the [Root Nameservers](https://en.wikipedia.org/wiki/Root_name_server) and [Top-level Domains](https://en.wikipedia.org/wiki/Top-level_domain) *(TLDs)*.
## Expectations & Legalities
Please set realistic expectations when using this tool. In contemporary network configurations, AXFR requests are typically restricted, reflecting best practices in DNS security. While many nameservers now disallow AXFR requests, there may still be occasional instances where configurations permit them. Always exercise due diligence and ensure ethical use.
## Requirements
- [dnspython](https://pypi.org/project/dnspython/)
- [dnspython](https://pypi.org/project/dnspython/) *(`pip install dnspython`)*
## Usage
| Argument | Description |
| ---------------- | ---------------------------------------------------- |
| `-r`, `--root` | Perform zone transfer on root nameservers. |
| `-t`, `--tld` | Perform zone transfer on a specific TLD. |
| `-ts`, `--tlds` | Perform zone transfer on all TLDs. |
| `-o`, `--output` | Specify the output directory *(default is axfrout)*. |
## Information
This script will attempt a [Zone Transfer](https://en.wikipedia.org/wiki/DNS_zone_transfer) on all of the [Root Nameservers](https://en.wikipedia.org/wiki/Root_name_server) and [Top-level Domains](https://en.wikipedia.org/wiki/Top-level_domain) *(TLDs)*.
I only wrote this to shit on **[this bozo](https://github.com/flotwig/TLDR-2/tree/main)** who took a dead project & brought it back to life by making it even worse. Rather than making a pull request to give this bloke more credit in his "tenure" as a developer, I decided to just rewrite it all from scratch so people can fork off of *clean* code instead.
Really, I only wrote this to shit on **[this idiot](https://github.com/flotwig/TLDR-2/tree/main)** who took a dead project & brought it back to life by making it even worse. Rather than making a pull request to give this bloke more credit in his "tenure" as a developer, I decided to just rewrite it all from scratch so people can fork off of *clean* code instead.
## Notice
Do not expect insane results. For the most part, AXFR's are not very commonly allowed on nameservers anymore, by you will always catch a few that are not configured to block AXFR requests...
As a little added bonus, I have began working on a pure POSIX version of this script for protability, which is included in this repository.
___

87
axfr.py
View File

@ -1,7 +1,9 @@
#!/usr/bin/env python
# Mass DNS AXFR - developed by acidvegas in python (https://git.acid.vegas/mdaxfr)
import os
import urllib.request
import logging
try:
import dns.rdatatype
@ -11,32 +13,48 @@ try:
except ImportError:
raise SystemExit('missing required \'dnspython\' module (pip install dnspython)')
def tld_axfr(tld: str, nameserver: str):
def attempt_axfr(tld: str, nameserver: str, filename: str):
'''
Perform a DNS zone transfer on a target domain.
:param target: The target domain to perform the zone transfer on.
:param nameserver: The nameserver to perform the zone transfer on.
:param filename: The filename to store the zone transfer results in.
'''
xfr = dns.query.xfr(nameserver, tld+'.', timeout=15)
for msg in xfr:
for rrset in msg.answer:
for rdata in rrset:
print(f'{rrset.name}.{tld} {rrset.ttl} {rdata}')
temp_file = filename + '.temp'
try:
nameserver = resolve_nameserver(nameserver)
except Exception as ex:
logging.error(f'Failed to resolve nameserver {nameserver}: {ex}')
else:
try:
with open(temp_file, 'w') as file:
xfr = dns.query.xfr(nameserver, tld+'.', timeout=15)
for msg in xfr:
for rrset in msg.answer:
for rdata in rrset:
file.write(f'{rrset.name}.{tld} {rrset.ttl} {rdata}')
os.rename(temp_file, filename)
except Exception as ex:
if os.path.exists(temp_file):
os.remove(temp_file)
logging.error(f'Failed to perform zone transfer from {nameserver} for {tld}: {ex}')
def get_root_nameservers() -> list: # https://www.internic.net/domain/named.root
def get_root_nameservers() -> list:
'''Generate a list of the root nameservers.'''
return [f'{root}.rootservers.net' for root in ('abcdefghijklm')]
root_ns_records = dns.resolver.resolve('.', 'NS')
root_servers = [str(rr.target)[:-1] for rr in root_ns_records]
return root_servers
def get_root_tlds() -> list:
'''Get the root TLDs from IANA.'''
return urllib.request.urlopen('https://data.iana.org/TLD/tlds-alpha-by-domain.txt').read().decode('utf-8').lower().split('\n')[1:]
def get_tld_nameservers(tld: str) -> list: # https://www.internic.net/domain/root.zone
def get_tld_nameservers(tld: str) -> list:
'''Get the nameservers for a TLD.'''
return [nameserver for nameserver in dns.resolver.query(tld+'.', 'NS' )]
def resolve_nameserver(nameserver: str):
def resolve_nameserver(nameserver: str) -> str:
'''
Resolve a nameserver to its IP address.
@ -51,16 +69,47 @@ def resolve_nameserver(nameserver: str):
if __name__ == '__main__':
import argparse
for root in get_root_nameservers():
try:
xfr = tld_axfr('', root+'.root-servers.net') # Need to store to file in chunks
except Exception as e:
print(f"Failed to perform zone transfer from the {root} root server: {e}")
parser = argparse.ArgumentParser(description='Mass DNS AXFR')
parser.add_argument('-r', '--root', action='store_true', help='perform zone transfer on root nameservers')
parser.add_argument('-t', '--tld', help='perform zone transfer on a specific TLD')
parser.add_argument('-ts', '--tlds', help='perform zone transfer on all TLDs')
parser.add_argument('-o', '--output', default='axfrout', help='output directory')
args = parser.parse_args()
for tld in get_root_tlds():
os.makedirs(args.output, exist_ok=True) # Create output directory if it doesn't exist
if args.root:
try:
for ns in get_tld_nameservers(tld):
xfr = tld_axfr(tld, resolve_nameserver(str(ns))) # Need to store to file in chunks
for root in get_root_nameservers():
try:
attempt_axfr('', root+'.root-servers.net', os.path.join(args.output, root+'-root.txt'))
except Exception as e:
logging.error(f'Failed to perform zone transfer from the {root} root server: {e}')
except Exception as e:
print(f"Failed to resolve {tld}: {e}")
logging.error(f'Failed to get root nameservers: {e}')
if args.tlds:
try:
for tld in get_root_tlds():
try:
for ns in get_tld_nameservers(tld):
try:
attempt_axfr(tld, ns, os.path.join(args.output, tld+'.txt'))
except Exception as e:
logging.error(f'Failed to perform zone transfer from {ns} for {tld}: {e}')
except Exception as e:
logging.error(f'Failed to get nameservers for {tld}: {e}')
except Exception as e:
logging.error(f'Failed to get root TLDs: {e}')
elif args.tld:
try:
for ns in get_tld_nameservers(args.tld):
try:
attempt_axfr(args.tld, ns, os.path.join(args.output, args.tld+'.txt'))
except Exception as e:
logging.error(f'Failed to perform zone transfer from {ns} for {args.tld}: {e}')
except Exception as e:
logging.error(f'Failed to get nameservers for {args.tld}: {e}')