mdaxfr

- Mass DNS AXFR
git clone git://git.acid.vegas/mdaxfr.git
Log | Files | Refs | Archive | README | LICENSE

commit b73cc90d525e4d470c7f170f2a359c1f49e3230b
parent 03c09942feef885b667589187300b2e2a219d191
Author: acidvegas <acid.vegas@acid.vegas>
Date: Thu, 23 Nov 2023 14:16:35 -0500

POSIX version now attempts IPv4 & IPv6, Python & POSIX version now correctly attempts every IP beloging to the nameserver

Diffstat:
MREADME.md | 2+-
Mmdaxfr | 23+++++++++++++----------
Mmdaxfr.py | 20+++++++++++---------

3 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/README.md b/README.md
@@ -16,7 +16,7 @@ It is expected to set *realistic* expectations when using this tool. In contempo
 | `-t`, `--timeout`     | DNS timeout *(default: 30)*                          |
 
 ## Information
-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.
+I only wrote this to shit on **[this bozo](https://github.com/flotwig/TLDR-2/)** 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.
 
 This repostiory also contains a [pure POSIX version](./mdaxfr) for portability, aswell as a [script](./opennic) to do zone transfers on [OpenNIC TLDs](https://wiki.opennic.org/opennic/dot).
 
diff --git a/mdaxfr b/mdaxfr
@@ -7,7 +7,7 @@ mkdir -p "$OUTPUT_DIR/root"
 mkdir -p "$OUTPUT_DIR/psl"
 
 resolve_nameserver() {
-	dig +short "$1" A || dig +short "$1" AAAA
+	dig +short AAAA $1 +short -t A $1 2>/dev/null
 }
 
 attempt_axfr() {
@@ -16,19 +16,22 @@ attempt_axfr() {
 	filename="$3"
 	temp_file="${filename}.temp"
 
-	nameserver_ip=$(resolve_nameserver "$nameserver")
-	if [ -z "$nameserver_ip" ]; then
+	nameserver_ips=$(resolve_nameserver "$nameserver")
+	if [ -z "$nameserver_ips" ]; then
 		echo "Failed to resolve nameserver $nameserver"
 		return
 	fi
 
-	dig AXFR "$tld" "@$nameserver_ip" > "$temp_file"
-	if [ $? -eq 0 ]; then
-		mv "$temp_file" "$filename"
-	else
-		echo "Failed to perform zone transfer from $nameserver for $tld"
-		rm -f "$temp_file"
-	fi
+	for nameserver_ip in $nameserver_ips; do
+		dig AXFR "$tld" "@$nameserver_ip" > "$temp_file"
+		if [ $? -eq 0 ]; then
+			mv "$temp_file" "$filename"
+			return 
+		else
+			echo "Failed to perform zone transfer from $nameserver for $tld"
+			rm -f "$temp_file"
+		fi
+	done
 }
 
 # For root nameservers
diff --git a/mdaxfr.py b/mdaxfr.py
@@ -29,17 +29,19 @@ def attempt_axfr(tld: str, nameserver: str, filename: str):
 	else:
 		for ns in nameserver: # Let's try all the IP addresses for the nameserver
 			try:
-				with open(temp_file, 'w') as file:
-					xfr = dns.query.xfr(nameserver.address, tld+'.', lifetime=300)
-					for msg in xfr:
-						for rrset in msg.answer:
-							for rdata in rrset:
-								file.write(f'{rrset.name}.{tld} {rrset.ttl} {rdata}\n')
-				os.rename(temp_file, filename)
+				xfr = dns.query.xfr(ns, tld+'.', lifetime=300)
+				if xfr:
+					with open(temp_file, 'w') as file:
+						for msg in xfr:
+							for rrset in msg.answer:
+								for rdata in rrset:
+									file.write(f'{rrset.name}.{tld} {rrset.ttl} {rdata}\n')
+					os.rename(temp_file, filename)
+					break
 			except Exception as ex:
 				if os.path.exists(temp_file):
 					os.remove(temp_file)
-				logging.error(f'Failed to perform zone transfer from {nameserver.address} for {tld}: {ex}')
+				logging.error(f'Failed to perform zone transfer from {nameserver} ({ns}) for {tld}: {ex}')
 
 
 def get_nameservers(target: str) -> list:
@@ -109,7 +111,7 @@ if __name__ == '__main__':
 	parser = argparse.ArgumentParser(description='Mass DNS AXFR')
 	parser.add_argument('-c', '--concurrency', type=int, default=30, help='maximum concurrent tasks')
 	parser.add_argument('-o', '--output', default='axfrout', help='output directory')
-	parser.add_argument('-t', '--timeout', type=int, default=30, help='DNS timeout (default: 30)')
+	parser.add_argument('-t', '--timeout', type=int, default=15, help='DNS timeout (default: 15)')
 	args = parser.parse_args()
 
 	os.makedirs(args.output, exist_ok=True)