Compare commits
No commits in common. "81d2ab767b78c1cc7de33dcd8f6c61982dd89cf8" and "4ee52126665b093c480978368741d249ff2b0713" have entirely different histories.
81d2ab767b
...
4ee5212666
Binary file not shown.
Before Width: | Height: | Size: 1.6 MiB |
13
README.md
13
README.md
@ -1,18 +1,13 @@
|
|||||||
# NSECX
|
# NSECX
|
||||||
> Research project on NSEC[3] walking for DNSSEC enabled Zones
|
|
||||||
|
|
||||||
![](./.screens/preview.gif)
|
###### Rsearch project on NSEC[3] walking for DNSSEC enabled Zones
|
||||||
|
|
||||||
## [Work in Progress]
|
## Work in progress: Come back later
|
||||||
|
|
||||||
The repository contains utilities for DNSSEC zone enumeration and subdomain discovery via NSEC/NSEC3 walking. It focuses on extracting and analyzing DNSSEC records for TLDs and specific target domains. Meant for educational purposes, security research, and sanctioned penetration testing, these tools aid in uncovering the underlying mechanisms of DNS security.
|
The repository contains utilities for DNSSEC zone enumeration and subdomain discovery via NSEC/NSEC3 walking. It focuses on extracting and analyzing DNSSEC records for TLDs and specific target domains. Meant for educational purposes, security research, and sanctioned penetration testing, these tools aid in uncovering the underlying mechanisms of DNS security.
|
||||||
|
|
||||||
## DNSSEC Statistics
|
## Statistics
|
||||||
| Status | Percentage | TLDs |
|
Based on my research at the time of writing this repository, after mapping 1,458 TLD zones, 89.78% use NSEC3, and 3.50% use NSEC, and 6.72% do not have DNSSEC features at all.
|
||||||
| ---------------------------------------- | ---------- | ----- |
|
|
||||||
| [NSEC3](./dnssec_stats/nsec3.txt) | 90% | 1,313 |
|
|
||||||
| [NSEC](./dnssec_stats/nsec.txt) | 3% | 51 |
|
|
||||||
| [NO DNSSEC](./dnssec_stats/nodnssec.txt) | 7% | 98 |
|
|
||||||
|
|
||||||
## NSEC Pitfalls
|
## NSEC Pitfalls
|
||||||
- Results inconsistent, must hop dns servers on ALL issues to continue the crawl.
|
- Results inconsistent, must hop dns servers on ALL issues to continue the crawl.
|
||||||
|
54
nsec
Executable file
54
nsec
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# NSEC walk script for DNSSEC - developed by acidvegas (https://git.acid.vegas/nsecx)
|
||||||
|
# nsec
|
||||||
|
|
||||||
|
# This script will walk through a DNS zone using NSEC records.
|
||||||
|
|
||||||
|
# You can wall all the zones outputted from tldsec using the following command:
|
||||||
|
# cat output/nsec.txt | while read line; do ./nsec "$line"; done
|
||||||
|
|
||||||
|
dns_servers=$(curl -s https://public-dns.info/nameservers.txt | grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b')
|
||||||
|
nameserver=$(echo "$dns_servers" | shuf -n 1)
|
||||||
|
|
||||||
|
# Loop to walk through the zone using NSEC records
|
||||||
|
while IFS= read -r line; do
|
||||||
|
tld="$line"
|
||||||
|
|
||||||
|
current_domain="$tld"
|
||||||
|
retry=0
|
||||||
|
breaker=0
|
||||||
|
while true; do
|
||||||
|
# Perform the dig command to get the NSEC record for the current domain
|
||||||
|
output="$(dig @${nameserver} +trace +time=10 +tries=3 $current_domain NSEC)"
|
||||||
|
|
||||||
|
# Use grep to find the line with the current domain and then use awk to extract the next domain
|
||||||
|
next_domain=$(echo "$output" | grep -F "$current_domain" | awk '$4 == "NSEC" { print $5 }')
|
||||||
|
|
||||||
|
if [ -z "$next_domain" ] || [ -n "$(printf '%s' "$next_domain" | tr -cd '\000')" ] || [ "$next_domain" = "$current_domain" ]; then
|
||||||
|
next_domain="$current_domain"
|
||||||
|
retry=$((retry + 1))
|
||||||
|
elif [ "$next_domain" = "nic.$tld" ]; then
|
||||||
|
echo "Found NIC!"
|
||||||
|
next_domain=
|
||||||
|
else
|
||||||
|
echo "Found NSEC record: $next_domain"
|
||||||
|
echo "$next_domain" >> output/nsec/$tld.txt
|
||||||
|
retry=0
|
||||||
|
breaker=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $retry -eq 3 ]; then
|
||||||
|
nameserver=$(echo "$dns_servers" | shuf -n 1)
|
||||||
|
retry=0
|
||||||
|
breaker=$((breaker + 1))
|
||||||
|
if [ $breaker -eq 3 ]; then
|
||||||
|
echo "Failed to get NSEC record for $current_domain"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update the current domain to the next one for the following iteration
|
||||||
|
current_domain=$next_domain
|
||||||
|
|
||||||
|
done
|
||||||
|
done < nsec.txt
|
122
nwalk
122
nwalk
@ -1,122 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# NSEC Walking for DNSSEC enabled zones - developed by acidvegas (https://git.acid.vegas/nsecx)
|
|
||||||
|
|
||||||
# Usage:
|
|
||||||
# NSEC walk on a single domain:
|
|
||||||
# ./nwalk <domain>
|
|
||||||
# NSEC walk on a list of domains:
|
|
||||||
# cat domain_list.txt | ./nwalk
|
|
||||||
# NSEC walk on a list of domains using parallel:
|
|
||||||
# parallel -a domain_list.txt -j 10 ./nwalk
|
|
||||||
# NSEC walk on all TLDs:
|
|
||||||
# curl -s 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt' | tail -n +2 | tr '[:upper:]' '[:lower:]' | ./nwalk
|
|
||||||
# NSEC walk on all PSL TLDs:
|
|
||||||
# curl -s https://publicsuffix.org/list/public_suffix_list.dat | grep -vE '^(//|.*[*!])' | grep '\.' | awk '{print $1}' | ./nwalk
|
|
||||||
|
|
||||||
# Colors
|
|
||||||
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"
|
|
||||||
|
|
||||||
nsec_crawl() {
|
|
||||||
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}"
|
|
||||||
|
|
||||||
ns_ip_list=""
|
|
||||||
|
|
||||||
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
|
|
||||||
ns_ip_list="${ns_ip_list}${ns} ${ip}\n"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -z "$ns_ip_list" ] && echo " ${GREY}No IP addresses found for ${CYAN}${domain}${RESET} nameservers" && return
|
|
||||||
|
|
||||||
total_ns_ip=$(echo -e "$ns_ip_list" | wc -l)
|
|
||||||
echo " ${BLUE}Found ${total_ns_ip} IP addresses for ${CYAN}${domain}${BLUE} nameservers${RESET}"
|
|
||||||
|
|
||||||
current_domain=$domain
|
|
||||||
|
|
||||||
count=0
|
|
||||||
error=0
|
|
||||||
|
|
||||||
ns=$(echo "$ns_ip_list" | shuf -n 1)
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
[ -z "$nameservers" ] && echo "${GREY}No nameservers left for ${CYAN}${domain}${RESET}" && return
|
|
||||||
[ -z "$ns" ] && echo "${GREY}No nameservers left for ${CYAN}${domain}${RESET}" && return
|
|
||||||
|
|
||||||
ns_domain=$(echo $ns | awk '{print $1}')
|
|
||||||
ns_ip=$(echo $ns | awk '{print $2}')
|
|
||||||
|
|
||||||
nsec=$(dig +short +retry=3 +time=10 @${ns_ip} $current_domain NSEC | awk '{print $1}' | sed 's/\.$//')
|
|
||||||
|
|
||||||
if [ -z "$nsec" ]; then
|
|
||||||
error=`expr $error + 1`
|
|
||||||
if [ $error -eq 3 ]; then
|
|
||||||
echo " ${RED}Failed to communicate with ${PURPLE}${ns_domain} ${GREY}(${ns_ip})${RED} for ${CYAN}${domain}${RESET}"
|
|
||||||
nameservers=$(echo "$nameservers" | grep -v "$ns_ip")
|
|
||||||
ns=$(echo "$ns_ip_list" | shuf -n 1)
|
|
||||||
error=0
|
|
||||||
fi
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
error=0
|
|
||||||
|
|
||||||
[ "$nsec" = "$domain" ] || [ "$nsec" = "$current_domain" ] && break
|
|
||||||
|
|
||||||
case $nsec in "\000."*) break;; esac
|
|
||||||
|
|
||||||
count=`expr $count + 1`
|
|
||||||
|
|
||||||
echo "$nsec" >> "${output_dir}/nsec-${domain}.txt"
|
|
||||||
echo " ${GREEN}NSEC record for ${CYAN}${domain}${GREEN} from ${PURPLE}${ns_domain} ${GREY}(${ns_ip})${GREEN} found ${YELLOW}${nsec}${RESET}"
|
|
||||||
|
|
||||||
current_domain=$nsec
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $count -eq 0 ]; then
|
|
||||||
echo "${RED}No NSEC records found for ${CYAN}${domain}${RED} from ${PURPLE}${ns}${RESET}"
|
|
||||||
else
|
|
||||||
echo "${GREEN}Found ${count} NSEC records for ${CYAN}${domain}${RESET}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set output directory
|
|
||||||
output_dir="nwalk_out"
|
|
||||||
mkdir -p $output_dir
|
|
||||||
|
|
||||||
if [ -t 0 ]; then
|
|
||||||
[ $# -ne 1 ] && echo "Usage: $0 <domain> or cat domain_list.txt | $0" && exit 1
|
|
||||||
nsec_crawl $1
|
|
||||||
else
|
|
||||||
while IFS= read -r line; do
|
|
||||||
nsec_crawl $line
|
|
||||||
done
|
|
||||||
fi
|
|
51
output/nsec.txt
Normal file
51
output/nsec.txt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
arpa
|
||||||
|
audio
|
||||||
|
auto
|
||||||
|
ax
|
||||||
|
bd
|
||||||
|
br
|
||||||
|
bt
|
||||||
|
car
|
||||||
|
cars
|
||||||
|
ch
|
||||||
|
christmas
|
||||||
|
ci
|
||||||
|
diet
|
||||||
|
dz
|
||||||
|
ee
|
||||||
|
er
|
||||||
|
flowers
|
||||||
|
game
|
||||||
|
gdn
|
||||||
|
gn
|
||||||
|
gov
|
||||||
|
guitars
|
||||||
|
hosting
|
||||||
|
id
|
||||||
|
ir
|
||||||
|
kg
|
||||||
|
kz
|
||||||
|
lb
|
||||||
|
li
|
||||||
|
lk
|
||||||
|
lol
|
||||||
|
lr
|
||||||
|
mc
|
||||||
|
mom
|
||||||
|
nu
|
||||||
|
pics
|
||||||
|
pr
|
||||||
|
ruhr
|
||||||
|
se
|
||||||
|
sl
|
||||||
|
tn
|
||||||
|
tz
|
||||||
|
ve
|
||||||
|
xn--54b7fta0cc
|
||||||
|
xn--80ao21a
|
||||||
|
xn--fzc2c9e2c
|
||||||
|
xn--l1acc
|
||||||
|
xn--mgbai9azgqp6j
|
||||||
|
xn--pgbs0dh
|
||||||
|
xn--xkc2al3hye2a
|
||||||
|
xn--ygbi2ammx
|
@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# NSEC Statistics for TLDs - developed by acidvegas (https://git.acid.vegas/nsecx)
|
# NSEC walk script for DNSSEC - developed by acidvegas (https://git.acid.vegas/nsecx)
|
||||||
# tldsec
|
# tldsec
|
||||||
|
|
||||||
# This script will check the DNSSEC status of all TLDs and output the results separated by NSEC, NSEC3, and NODNSSEC.
|
# This script will check the DNSSEC status of all TLDs and output the results separated by NSEC, NSEC3, and NODNSSEC.
|
||||||
@ -17,8 +17,17 @@ NC='\033[0m'
|
|||||||
# Create the output directory if it doesn't exist
|
# Create the output directory if it doesn't exist
|
||||||
mkdir -p output
|
mkdir -p output
|
||||||
|
|
||||||
# Parse the tld list from a root nameserver
|
# Parse the tld list from a root nameserver (todo: randomize the root nameserver)
|
||||||
tld_list=$(dig AXFR . @g.root-servers.net | grep -E 'IN\s+NS' | awk '{print $1}' | sed 's/\.$//' | sort -u)
|
tld_list=$(dig AXFR . @g.root-servers.net | grep -E 'IN\s+NS' | awk '{print $1}' | sed 's/\.$//' | sort -u)
|
||||||
|
if [ -z $tld_list ]; then
|
||||||
|
tld_list=$(curl -s 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt' | tail -n +2 | tr '[:upper:]' '[:lower:]')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the list was retrieved successfully
|
||||||
|
if [ -z "$tld_list" ]; then
|
||||||
|
printf "${RED}Failed to fetch the list of TLDs.${NC}\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Get the total number of TLDs, excluding comments and empty lines
|
# Get the total number of TLDs, excluding comments and empty lines
|
||||||
total_tlds=$(echo "$tld_list" | grep -v '^#' | grep -v '^$' | wc -l | tr -d ' ')
|
total_tlds=$(echo "$tld_list" | grep -v '^#' | grep -v '^$' | wc -l | tr -d ' ')
|
Loading…
Reference in New Issue
Block a user