POSIX version drastically improved, allows parsing AXFR output files now, improved verbosity, daxfr merged into mdaxfr script.

This commit is contained in:
Dionysus 2024-03-10 18:04:01 -04:00
parent 4c8ac71c62
commit ecbd8139f4
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
5 changed files with 171 additions and 131 deletions

BIN
.screens/preview_ripe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
.screens/preview_root.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -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...
___ ___

View File

@ -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

188
mdaxfr
View File

@ -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
fi
for nameserver_ip in $nameserver_ips; do axfr_output=$(dig +retry=3 +time=10 @$ip AXFR $domain)
dig AXFR "$tld" "@$nameserver_ip" > "$temp_file" axfr_status=$?
if ! grep -q 'IN.*NS' "$temp_file"; then
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" if [ $axfr_status -eq 0 ] && echo "$axfr_output" | grep -q "XFR size: "; then
rm -f "$temp_file" 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 else
mv "$temp_file" "$filename" echo " ${RED} Failed AXFR for ${CYAN}${domain}${RED} from ${PURPLE}${ns} ${GREY}(${ip})${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
fi fi
}
process_domain() {
domain=$1
domain=$(echo "$domain" | sed -e 's|^\(https\?://\)\?||' -e 's|^www\.||' -e 's|/.*||')
echo "${PINK}Looking up nameservers for ${CYAN}${domain}${RESET}"
nameservers=$(dig +short +retry=3 +time=10 $domain NS | sed 's/\.$//')
[ -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"
for domain in $domains; do
process_domain $domain
done
}
psl_crawl() {
psl=$(curl -s https://publicsuffix.org/list/public_suffix_list.dat | grep -vE '^(//|.*[*!])' | grep '\.' | awk '{print $1}')
[ -z "$psl" ] && echo "${RED}No PSL TLDs found${RESET}" && exit 1
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:]') 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 else
tlds=$(cat $rndroot | grep -E 'IN\s+NS' | awk '{print $1}' | sed 's/\.$//' | sort -u) while IFS= read -r line; do
process_domain $line
done
fi fi
# For TLD nameservers
for tld in $tlds; do
for ns in $(dig +short "$tld" NS | sed 's/\.$//'); do
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
for ns in $(dig +short "$tld" NS | sed 's/\.$//'); do
attempt_axfr "$tld" "$ns" "$output/psl/$tld.txt"
done
done