nsecx

- NSEC[3] Walking for DNSSEC
git clone git://git.acid.vegas/nsecx.git
Log | Files | Refs | Archive | README | LICENSE

nwalk (4188B)

      1 #!/bin/sh
      2 # NSEC Walking for DNSSEC enabled zones - developed by acidvegas (https://git.acid.vegas/nsecx)
      3 
      4 # Usage:
      5 #     NSEC walk on a single domain:
      6 #         ./nwalk <domain>
      7 #     NSEC walk on a list of domains:
      8 #         cat domain_list.txt | ./nwalk
      9 #     NSEC walk on a list of domains using parallel:
     10 #         parallel -a domain_list.txt -j 10 ./nwalk
     11 #     NSEC walk on all TLDs:
     12 #         curl -s 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt' | tail -n +2 | tr '[:upper:]' '[:lower:]' | ./nwalk
     13 #     NSEC walk on all PSL TLDs:
     14 #         curl -s https://publicsuffix.org/list/public_suffix_list.dat | grep -vE '^(//|.*[*!])' | grep '\.' | awk '{print $1}' | ./nwalk
     15 
     16 # Colors
     17 BLUE="\033[1;34m"
     18 CYAN="\033[1;36m"
     19 GREEN="\033[1;32m"
     20 GREY="\033[1;90m"
     21 PINK="\033[1;95m"
     22 PURPLE="\033[0;35m"
     23 RED="\033[1;31m"
     24 YELLOW="\033[1;33m"
     25 RESET="\033[0m"
     26 
     27 nsec_crawl() {
     28     domain=$1
     29 
     30     domain=$(echo "$domain" | sed -e 's|^\(https\?://\)\?||' -e 's|^www\.||' -e 's|/.*||')
     31 
     32     echo "${PINK}Looking up nameservers for ${CYAN}${domain}${RESET}"
     33 
     34     nameservers=$(dig +short +retry=3 +time=10 $domain NS | sed 's/\.$//')
     35 
     36     [ -z "$nameservers" ] && echo "    ${GREY}No nameservers found for ${CYAN}${domain}${RESET}" && return
     37 
     38     total_nameservers=$(echo "$nameservers" | wc -l)
     39     echo "    ${BLUE}Found ${total_nameservers} nameservers for ${CYAN}${domain}${RESET}"
     40 
     41     ns_ip_list=""
     42 
     43     for ns in $nameservers; do
     44         echo "        ${PINK}Looking up IP addresses for ${PURPLE}${ns}${RESET}"
     45 
     46         ns_ip=$(dig +short +retry=3 +time=10 $ns A && dig +short +retry=3 +time=10 $ns AAAA)
     47 
     48         [ -z "$ns_ip" ] && echo "            ${GREY}No IP addresses found on ${PURPLE}${ns}${GREY} for ${CYAN}${domain}${RESET}" && continue
     49 
     50         total_ip=$(echo "$ns_ip" | wc -l)
     51         echo "            ${BLUE}Found ${total_ip} IP addresses on ${PURPLE}${ns}${BLUE} for ${CYAN}${domain}${RESET}"
     52 
     53         for ip in $ns_ip; do
     54             ns_ip_list="${ns_ip_list}${ns} ${ip}\n"
     55         done
     56     done
     57 
     58     [ -z "$ns_ip_list" ] && echo "    ${GREY}No IP addresses found for ${CYAN}${domain}${RESET} nameservers" && return
     59 
     60     total_ns_ip=$(echo -e "$ns_ip_list" | wc -l)
     61     echo "    ${BLUE}Found ${total_ns_ip} IP addresses for ${CYAN}${domain}${BLUE} nameservers${RESET}"
     62 
     63     current_domain=$domain
     64 
     65     count=0
     66     error=0
     67 
     68     ns=$(echo "$ns_ip_list" | shuf -n 1)
     69 
     70     while true; do
     71         [ -z "$nameservers" ] && echo "${GREY}No nameservers left for ${CYAN}${domain}${RESET}" && return
     72         [ -z "$ns"          ] && echo "${GREY}No nameservers left for ${CYAN}${domain}${RESET}" && return
     73 
     74         ns_domain=$(echo $ns | awk '{print $1}')
     75         ns_ip=$(echo $ns | awk '{print $2}') 
     76         
     77         nsec=$(dig +short +retry=3 +time=10 @${ns_ip} $current_domain NSEC | awk '{print $1}' | sed 's/\.$//')
     78 
     79         if [ -z "$nsec" ]; then
     80             error=`expr $error + 1`
     81             if [ $error -eq 3 ]; then
     82                 echo "        ${RED}Failed to communicate with ${PURPLE}${ns_domain} ${GREY}(${ns_ip})${RED} for ${CYAN}${domain}${RESET}"
     83                 nameservers=$(echo "$nameservers" | grep -v "$ns_ip")
     84                 ns=$(echo "$ns_ip_list" | shuf -n 1)
     85                 error=0
     86             fi
     87             continue
     88         fi
     89 
     90         error=0
     91 
     92         [ "$nsec" = "$domain" ] || [ "$nsec" = "$current_domain" ] && break
     93 
     94         case $nsec in "\000."*) break;; esac
     95 
     96         count=`expr $count + 1`
     97 
     98         echo "$nsec" >> "${output_dir}/nsec-${domain}.txt"
     99         echo "        ${GREEN}NSEC record for ${CYAN}${domain}${GREEN} from ${PURPLE}${ns_domain} ${GREY}(${ns_ip})${GREEN} found ${YELLOW}${nsec}${RESET}"
    100 
    101         current_domain=$nsec
    102     done
    103 
    104     if [ $count -eq 0 ]; then
    105         echo "${RED}No NSEC records found for ${CYAN}${domain}${RED} from ${PURPLE}${ns}${RESET}"
    106     else
    107         echo "${GREEN}Found ${count} NSEC records for ${CYAN}${domain}${RESET}"
    108     fi
    109 }
    110 
    111 # Set output directory
    112 output_dir="nwalk_out"
    113 mkdir -p $output_dir
    114 
    115 if [ -t 0 ]; then
    116     [ $# -ne 1 ] && echo "Usage: $0 <domain> or cat domain_list.txt | $0" && exit 1
    117     nsec_crawl $1
    118 else
    119     while IFS= read -r line; do
    120         nsec_crawl $line
    121     done
    122 fi