Skip to content

Commit

Permalink
Fetch some records when zone provided (#143)
Browse files Browse the repository at this point in the history
* feat: fetch some records when provided

* resolve ns server hostnames to ip addresses before attempting to use them

* Actually resolve external records

Co-authored-by: Brandon Hall <[email protected]>
  • Loading branch information
SimonGurney and imnotbrandon authored Dec 22, 2022
1 parent 9ab859a commit a22cf29
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
41 changes: 40 additions & 1 deletion domain.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import ipaddress
import socket
from collections import namedtuple
import dns.resolver
from functools import lru_cache
Expand Down Expand Up @@ -37,6 +39,7 @@ def query(self, type):
return []

def fetch_std_records(self):
# TODO: is this recursive?
self.CNAME = self.query("CNAME")
self.A = self.query("A")
self.AAAA = self.query("AAAA")
Expand All @@ -47,19 +50,55 @@ def fetch_std_records(self):
return
self.NS = self.query("NS")

def fetch_external_records(self):
for cname in self.CNAME:
split_cname = cname.split(".", 1)
if len(split_cname) == 1:
continue # This cname has no zone to assess
if self.base_domain == split_cname[1]:
continue # Same zone, dont fetch
d = Domain(cname)
d.fetch_std_records()
self.A += d.A
self.AAAA += d.AAAA
self.CNAME += d.CNAME
for ns in self.NS:
d = Domain(self.domain, ns=ns)
self.A += d.A
self.AAAA += d.AAAA

def set_custom_NS(self, ns: str):
if type(ns) != str:
logging.error(f"Cannot set custom NS as {ns} not a string")
exit(-1)
self.resolver = dns.resolver.Resolver()
self.resolver.nameservers = [ns]

try:
ipaddress.ip_address(ns)
self.resolver.nameservers = [ns]
except ValueError:
try:
self.resolver.nameservers = [socket.gethostbyname(ns.rstrip("."))]
except:
logging.error(
f"Cannot set custom NS as {ns} does not resolve to a valid IP address"
)
exit(-1)

def set_base_domain(self):
split_domain = self.domain.split(".", 1)
if len(split_domain) > 1:
self.base_domain = split_domain[1]
else:
self.base_domain = "."

def __init__(self, domain, fetch_standard_records=True, ns=None):
self.domain = domain.rstrip(".")
self.NS = []
self.A = []
self.AAAA = []
self.CNAME = []
self.set_base_domain()
self.requests = requests
if ns == None:
self.resolver = dns.resolver
Expand Down
2 changes: 2 additions & 0 deletions scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ def scan_domain(domain, signatures, lock, findings, output_handler, name_servers
domain.set_custom_NS(random.choice(name_servers))
if domain.should_fetch_std_records:
domain.fetch_std_records()
else:
domain.fetch_external_records()
for signature in signatures:
logging.debug(
f"Testing domain '{domain.domain}' with signature '{signature.__name__}'"
Expand Down

0 comments on commit a22cf29

Please sign in to comment.