POSIX version drastically improved, allows parsing AXFR output files now, improved verbosity, daxfr merged into mdaxfr script.
This commit is contained in:
parent
4c8ac71c62
commit
ecbd8139f4
BIN
.screens/preview_ripe.png
Normal file
BIN
.screens/preview_ripe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
BIN
.screens/preview_root.png
Normal file
BIN
.screens/preview_root.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
41
README.md
41
README.md
@ -1,27 +1,50 @@
|
|||||||
# Mass DNS AXFR (Zone Transfer)
|
# Mass DNS AXFR (Zone Transfer)
|
||||||
|
|
||||||
###### [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)*.
|
## Information
|
||||||
|
MDAXFR allows you to perform a DNS [Zone Transfer](https://en.wikipedia.org/wiki/DNS_zone_transfer) against a target domain by resolving all of the domains nameservers to their respective A/AAAA records and making an AXFR attempt against each of the IP addresses.
|
||||||
|
|
||||||
|
You can also use this tool against the [Root Nameservers](https://en.wikipedia.org/wiki/Root_name_server) and [Top-level Domains](https://en.wikipedia.org/wiki/Top-level_domain) *(TLD)*, including those in the [Public Suffix List](https://en.wikipedia.org/wiki/Public_Suffix_List) *(PSL)* aswell.
|
||||||
|
|
||||||
|
![](.screens/preview_ripe.png)
|
||||||
|
![](.screens/preview_root.png)
|
||||||
|
|
||||||
## Expectations & Legalities
|
## Expectations & Legalities
|
||||||
It is expected to 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.
|
It is expected to 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
|
## Usage
|
||||||
|
### POSIX Version
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./mdaxfr <option>
|
||||||
|
```
|
||||||
|
|
||||||
|
###### Options
|
||||||
|
| Argument | Description |
|
||||||
|
| ------------- | ------------------------------------------------------------------------------------------- |
|
||||||
|
| `-tld`, | Perform AXFR on all TLDs |
|
||||||
|
| `-psl`, | Perform AXFR on all PSL TLDs |
|
||||||
|
| `<axfr_file>` | Perform AXFR on all domains found in `<axfr_file>` *(must be an AXFR output file from dig)* |
|
||||||
|
| `<domain>` | Perform AXFR on `<domain>` |
|
||||||
|
|
||||||
|
### Python Version
|
||||||
|
```shell
|
||||||
|
python mdaxfr.py <option>
|
||||||
|
```
|
||||||
|
|
||||||
|
###### Requirements
|
||||||
- [dnspython](https://pypi.org/project/dnspython/) *(`pip install dnspython`)*
|
- [dnspython](https://pypi.org/project/dnspython/) *(`pip install dnspython`)*
|
||||||
|
|
||||||
## Usage
|
###### Options
|
||||||
| Argument | Description |
|
| Argument | Description |
|
||||||
| --------------------- | ---------------------------------------------------- |
|
| --------------------- | ---------------------------------------------------- |
|
||||||
| `-c`, `--concurrency` | Maximum concurrent tasks. |
|
| `-c`, `--concurrency` | Maximum concurrent tasks. |
|
||||||
| `-o`, `--output` | Specify the output directory *(default is axfrout)*. |
|
| `-o`, `--output` | Specify the output directory *(default is axfrout)*. |
|
||||||
| `-t`, `--timeout` | DNS timeout *(default: 30)* |
|
| `-t`, `--timeout` | DNS timeout *(default: 30)* |
|
||||||
|
|
||||||
## Information
|
## Statistics, laughs, & further thinking...
|
||||||
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.
|
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](./extras/opennic) to do zone transfers on [OpenNIC TLDs](https://wiki.opennic.org/opennic/dot), a special [ozones](./extras/ozones) script for fetching a few obscure additional zones, and a [domain axfr script](./extras/daxfr) to target a specific website.
|
As of my last scan in 2023, I was only able to AXFR the zones for **8** out of **1,456** root TLDs, with a few of them being zones that were already retrieved by [acidvegas/czds](https://github.com/acidvegas/czds/), & **114** out of **7,977** TLDs in the [Public suffix list](https://publicsuffix.org/). The [addition scripts](./extras/) in this repository provide an additional **37** zone files.
|
||||||
|
|
||||||
## Statistics, laughs, & further thinking...
|
|
||||||
As of my last scan in 2023, I was only able to AXFR the zones for **8** out of **1,456** root TLDs, with a few of them being zones that were already retrieved by [acidvegas/czds](https://github.com/acidvegas/czds/), & **114** out of **7,977** TLDs in the [Public suffix list](https://publicsuffix.org/). The addition scripts in this repository provide an additional **37** zone files.
|
|
||||||
|
|
||||||
For laughs, here is a one-liner mass zone axfr:
|
For laughs, here is a one-liner mass zone axfr:
|
||||||
```bash
|
```bash
|
||||||
@ -29,7 +52,7 @@ curl -s https://www.internic.net/domain/root.zone | awk '$4=="A" || $4=="AAAA" {
|
|||||||
```
|
```
|
||||||
**Note:** Don't actually use this lol...
|
**Note:** Don't actually use this lol...
|
||||||
|
|
||||||
It is interesting to have seen this has worked on some "darknet" DNS servers...would maybe look into exploring collecting more zones for alterntive DNS routing. Some of that goes beyond an "AXFR" though...
|
It is interesting to have seen this has worked on some "darknet" DNS servers...would maybe look into exploring collecting more zones for alterntive DNS routing. I am also intruiged at how much you can explore [ARPANET](https://en.wikipedia.org/wiki/ARPANET) with AXFRs...more ARPAgheddon coming soon...
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|
||||||
|
69
extras/daxfr
69
extras/daxfr
@ -1,69 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Domain AXFR - developed by acidvegas (https://git.acid.vegas/mdaxfr)
|
|
||||||
# This one will take a domain as an argument and attempt to perform an AXFR against all of the nameservers for that domain.
|
|
||||||
# You can also pass an AXFR output file as an argument to attempt AXFR against all of the unique domains found in the file.
|
|
||||||
|
|
||||||
# Colors
|
|
||||||
BLUE="\033[1;34m"
|
|
||||||
CYAN="\033[1;36m"
|
|
||||||
GREEN="\033[1;32m"
|
|
||||||
GREY="\033[1;90m"
|
|
||||||
PURPLE='\033[0;35m'
|
|
||||||
RED="\033[1;31m"
|
|
||||||
YELLOW="\033[1;33m"
|
|
||||||
RESET="\033[0m"
|
|
||||||
|
|
||||||
# Globals
|
|
||||||
output_dir="daxfrout"
|
|
||||||
|
|
||||||
perform_axfr() {
|
|
||||||
domain=$1
|
|
||||||
ns=$2
|
|
||||||
ip=$3
|
|
||||||
|
|
||||||
echo "${YELLOW}Attempting AXFR for ${CYAN}${domain}${YELLOW} from ${PURPLE}${ns} ${GREY}(${ip})${RESET}"
|
|
||||||
|
|
||||||
axfr_output=$(dig +retry=3 +time=10 @$ip AXFR $domain)
|
|
||||||
axfr_status=$?
|
|
||||||
|
|
||||||
if [ $axfr_status -eq 0 ] && echo "$axfr_output" | grep -q "XFR size: "; then
|
|
||||||
echo "$axfr_output" > "${output+dir}/axfr-${domain}_${ns}_${ip}.txt"
|
|
||||||
size=$(echo "$axfr_output" | awk '/XFR size:/ {print $4}')
|
|
||||||
echo "${GREEN}Successful AXFR for ${CYAN}${domain}${GREEN} from ${PURPLE}${ns} ${GREY}(${ip}) ${BLUE}[${size} records]${RESET}"
|
|
||||||
else
|
|
||||||
echo "${RED} Failed AXFR for ${CYAN}${domain}${RED} from ${PURPLE}${ns} ${GREY}(${ip})${RESET}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
process_domain() {
|
|
||||||
domain=$1
|
|
||||||
nameservers=$(dig +short +retry=3 +time=10 $domain NS)
|
|
||||||
|
|
||||||
[ -z "$nameservers" ] && echo "${GREY}No nameservers found for ${CYAN}${domain}{$RESET}" && return
|
|
||||||
|
|
||||||
for ns in $nameservers; do
|
|
||||||
ns=$(echo "$ns" | sed 's/\.$//')
|
|
||||||
ns_ip=$(host $ns | awk '/has (IPv6 )?address/ { print $NF }')
|
|
||||||
|
|
||||||
[ -z "$ns_ip" ] && echo "${GREY}No IP addresses found for nameserver ${PURPLE}${ns}${GREY} under ${CYAN}${domain}{RESET}" && continue
|
|
||||||
|
|
||||||
for ip in $ns_ip; do
|
|
||||||
perform_axfr "$domain" "$ns" "$ip"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
[ $# -eq 0 ] && echo "Usage: $0 <domain> or <path_to_axfr_output>" && exit 1
|
|
||||||
|
|
||||||
mkdir -p $output_dir
|
|
||||||
|
|
||||||
if [ -f "$1" ]; then
|
|
||||||
root=$(grep -m1 '^; <<>> DiG' $1 | awk '{print $(NF-1)}') # Get the root domain from the dig output
|
|
||||||
domains=$(grep -a $'\t'IN$'\t'NS$'\t' "$1" | awk '{print $1}' | sort -u | sed 's/\.$//' | grep -v "^$root\.$") # Get the unique domains from the dig output (excluding the root domain)
|
|
||||||
|
|
||||||
for domain in $domains; do
|
|
||||||
process_domain $domain
|
|
||||||
done
|
|
||||||
else
|
|
||||||
process_domain $1
|
|
||||||
fi
|
|
192
mdaxfr
192
mdaxfr
@ -1,70 +1,156 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Mass DNS AXFR (POSIX version) - developed by acidvegas (https://git.acid.vegas/mdaxfr)
|
# Mass DNS AXFR (POSIX version) - developed by acidvegas (https://git.acid.vegas/mdaxfr)
|
||||||
|
|
||||||
# Define the current date for data organization
|
# Colors
|
||||||
now=$(date +"%Y-%m-%d")
|
BLUE="\033[1;34m"
|
||||||
|
CYAN="\033[1;36m"
|
||||||
|
GREEN="\033[1;32m"
|
||||||
|
GREY="\033[1;90m"
|
||||||
|
PINK="\033[1;95m"
|
||||||
|
PURPLE="\033[0;35m"
|
||||||
|
RED="\033[1;31m"
|
||||||
|
YELLOW="\033[1;33m"
|
||||||
|
RESET="\033[0m"
|
||||||
|
|
||||||
# Define the output directory
|
# Set output directory
|
||||||
output="axfrout/$now"
|
output_dir="axfrout"
|
||||||
|
mkdir -p $output_dir
|
||||||
|
|
||||||
# Function to attempt an AXFR request on all possible IP addresses for a nameserver
|
|
||||||
attempt_axfr() {
|
|
||||||
tld=$1
|
|
||||||
nameserver=$2
|
|
||||||
filename="$3"
|
|
||||||
|
|
||||||
temp_file="${filename}.temp"
|
axfr() {
|
||||||
nameserver_ips=$(dig +short A +retry=3 +time=10 $nameserver && dig +short AAAA +retry=3 +time=10 $nameserver)
|
domain=$1
|
||||||
|
ns=$2
|
||||||
|
ip=$3
|
||||||
|
|
||||||
if [ -z "$nameserver_ips" ]; then
|
echo " ${YELLOW}Attempting AXFR for ${CYAN}${domain}${YELLOW} from ${PURPLE}${ns} ${GREY}(${ip})${RESET}"
|
||||||
echo -e "\e[31m[FAIL]\e[0m AXFR for \e[36m$tld\e[0m on \e[33m$nameserver\e[0m \e[90m(failed to resolve nameserver)\e[0m"
|
|
||||||
return
|
axfr_output=$(dig +retry=3 +time=10 @$ip AXFR $domain)
|
||||||
|
axfr_status=$?
|
||||||
|
|
||||||
|
if [ $axfr_status -eq 0 ] && echo "$axfr_output" | grep -q "XFR size: "; then
|
||||||
|
echo "$axfr_output" > "${output_dir}/axfr-${domain}_${ns}_${ip}.txt"
|
||||||
|
size=$(echo "$axfr_output" | awk '/XFR size:/ {print $4}')
|
||||||
|
echo " ${GREEN}Successful AXFR for ${CYAN}${domain}${GREEN} from ${PURPLE}${ns} ${GREY}(${ip}) ${GREEN}found ${size} records${RESET}"
|
||||||
|
else
|
||||||
|
echo " ${RED} Failed AXFR for ${CYAN}${domain}${RED} from ${PURPLE}${ns} ${GREY}(${ip})${RESET}"
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
for nameserver_ip in $nameserver_ips; do
|
|
||||||
dig AXFR "$tld" "@$nameserver_ip" > "$temp_file"
|
process_domain() {
|
||||||
if ! grep -q 'IN.*NS' "$temp_file"; then
|
domain=$1
|
||||||
echo -e "[\e[31mFAIL\e[0m] AXFR for \e[36m$tld\e[0m on \e[33m$nameserver\e[0m \e[90m($nameserver_ip)\e[0m"
|
|
||||||
rm -f "$temp_file"
|
domain=$(echo "$domain" | sed -e 's|^\(https\?://\)\?||' -e 's|^www\.||' -e 's|/.*||')
|
||||||
else
|
|
||||||
mv "$temp_file" "$filename"
|
echo "${PINK}Looking up nameservers for ${CYAN}${domain}${RESET}"
|
||||||
echo -e "[\e[32mSUCCESS\e[0m] AXFR for \e[36m$tld\e[0m on \e[33m$nameserver\e[0m \e[90m($nameserver_ip)\e[0m"
|
|
||||||
return
|
nameservers=$(dig +short +retry=3 +time=10 $domain NS | sed 's/\.$//')
|
||||||
fi
|
|
||||||
|
[ -z "$nameservers" ] && echo " ${GREY}No nameservers found for ${CYAN}${domain}${RESET}" && return
|
||||||
|
|
||||||
|
total_nameservers=$(echo "$nameservers" | wc -l)
|
||||||
|
echo " ${BLUE}Found ${total_nameservers} nameservers for ${CYAN}${domain}${RESET}"
|
||||||
|
|
||||||
|
for ns in $nameservers; do
|
||||||
|
echo " ${PINK}Looking up IP addresses for ${PURPLE}${ns}${RESET}"
|
||||||
|
|
||||||
|
ns_ip=$(dig +short +retry=3 +time=10 $ns A && dig +short +retry=3 +time=10 $ns AAAA)
|
||||||
|
|
||||||
|
[ -z "$ns_ip" ] && echo " ${GREY}No IP addresses found on ${PURPLE}${ns}${GREY} for ${CYAN}${domain}${RESET}" && continue
|
||||||
|
|
||||||
|
total_ip=$(echo "$ns_ip" | wc -l)
|
||||||
|
echo " ${BLUE}Found ${total_ip} IP addresses on ${PURPLE}${ns}${BLUE} for ${CYAN}${domain}${RESET}"
|
||||||
|
|
||||||
|
for ip in $ns_ip; do
|
||||||
|
axfr "$domain" "$ns" "$ip"
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create the output directories (if they don't exist)
|
|
||||||
mkdir -p "$output/root"
|
|
||||||
mkdir -p "$output/psl"
|
|
||||||
|
|
||||||
# Give a warning about the current state of AXFR requests
|
read_axfr_out() {
|
||||||
echo "[\e[31mWARNING\e[0m] Most nameservers will block AXFR requests \e[90m(It is normal for most of these to fail)\e[0m" && sleep 3
|
axfr_output_file=$1
|
||||||
|
|
||||||
# For root nameservers
|
root=$(grep -m1 '^; <<>> DiG' $axfr_output_file | awk '{print $NF}')
|
||||||
for root in $(dig +short . NS | sed 's/\.$//'); do
|
domains=$(grep -aE "\s+IN\s+NS\s+" "$axfr_output_file" | grep -avE "^${root}\.\s+" | awk '{print $1}' | sort -u | sed 's/\.$//')
|
||||||
attempt_axfr "." "$root" "$output/root/$root.txt"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Parse the tld list from a root nameserver
|
[ -z "$domains" ] && echo "${GREY}No domains found for ${root}${RESET}" && return
|
||||||
rndroot=$(find $output/root/*.root-servers.net.txt -type f | shuf -n 1)
|
|
||||||
if [ -z $rndroot ]; then
|
total_domains=$(echo "$domains" | wc -l)
|
||||||
echo "Failed to AXFR a root nameserver (using IANA list instead)"
|
echo "${BLUE}Found ${total_domains} domains for ${CYAN}${root}${BLUE} zone"
|
||||||
tlds=$(curl -s 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt' | tail -n +2 | tr '[:upper:]' '[:lower:]')
|
|
||||||
else
|
|
||||||
tlds=$(cat $rndroot | grep -E 'IN\s+NS' | awk '{print $1}' | sed 's/\.$//' | sort -u)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For TLD nameservers
|
for domain in $domains; do
|
||||||
for tld in $tlds; do
|
process_domain $domain
|
||||||
for ns in $(dig +short "$tld" NS | sed 's/\.$//'); do
|
done
|
||||||
attempt_axfr "$tld" "$ns" "$output/$tld.txt"
|
}
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
# For Public Suffix List TLD nameservers
|
|
||||||
for tld in $(curl -s https://publicsuffix.org/list/public_suffix_list.dat | grep -vE '^(//|.*[*!])' | grep '\.' | awk '{print $1}'); do
|
psl_crawl() {
|
||||||
for ns in $(dig +short "$tld" NS | sed 's/\.$//'); do
|
psl=$(curl -s https://publicsuffix.org/list/public_suffix_list.dat | grep -vE '^(//|.*[*!])' | grep '\.' | awk '{print $1}')
|
||||||
attempt_axfr "$tld" "$ns" "$output/psl/$tld.txt"
|
|
||||||
done
|
[ -z "$psl" ] && echo "${RED}No PSL TLDs found${RESET}" && exit 1
|
||||||
done
|
|
||||||
|
total_psl=$(echo "$psl" | wc -l)
|
||||||
|
echo "${BLUE}Found ${total_psl} PSL TLDs${RESET}"
|
||||||
|
|
||||||
|
# Process the PSL TLDs
|
||||||
|
for tld in $psl; do
|
||||||
|
process_domain $tld
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tld_crawl() {
|
||||||
|
process_domain "."
|
||||||
|
|
||||||
|
rndroot=$(find $output_dir/*.root-servers.net.txt -type f | shuf -n 1)
|
||||||
|
|
||||||
|
if [ -z $rndroot ]; then
|
||||||
|
echo "${GREY}No root nameserver found, using IANA TLD list${RESET}"
|
||||||
|
tlds=$(curl -s 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt' | tail -n +2 | tr '[:upper:]' '[:lower:]')
|
||||||
|
else
|
||||||
|
tlds=$(cat $rndroot | grep -aE '\s+IN\s+NS\s+' | grep -avE "^\.\s+" | awk '{print $1}' | sed 's/\.$//' | sort -u)
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$tlds" ] && echo "${RED}No TLDs found${RESET}" && exit 1
|
||||||
|
|
||||||
|
total_tld=$(echo "$tlds" | wc -l)
|
||||||
|
echo "${BLUE}Found ${total_tld} TLDs${RESET}"
|
||||||
|
|
||||||
|
# Process the TLDs
|
||||||
|
for tld in $tlds; do
|
||||||
|
process_domain $tld
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ -t 0 ]; then
|
||||||
|
if [ $# -ne 1 0 ]; then
|
||||||
|
echo "Usage: $0 <option>"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " -tld : Perform AXFR on all TLDs"
|
||||||
|
echo " -psl : Perform AXFR on all PSL TLDs"
|
||||||
|
echo " <file> : Process AXFR output file (must be an AXFR output file from dig)"
|
||||||
|
echo " <domain> : Perform AXFR on a single domain"
|
||||||
|
echo ""
|
||||||
|
echo "Standard Input:"
|
||||||
|
echo " cat domain_list.txt | $0"
|
||||||
|
exit 1
|
||||||
|
elif [ $1 = '-tld' ]; then
|
||||||
|
tld_crawl
|
||||||
|
elif [ $1 = '-psl' ]; then
|
||||||
|
psl_crawl
|
||||||
|
elif [ -f $1 ]; then
|
||||||
|
read_axfr_out $1
|
||||||
|
else
|
||||||
|
process_domain $1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
while IFS= read -r line; do
|
||||||
|
process_domain $line
|
||||||
|
done
|
||||||
|
fi
|
Loading…
Reference in New Issue
Block a user