Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to read in list of multiple domains. #6

Merged
merged 2 commits into from
Dec 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ If this fails, it will lookup TXT and MX records for the domain, and then perfor
Usage
-----

dnscan.py -d \<domain\> [OPTIONS]
dnscan.py (-d \<domain\> | -l \<list\>) [OPTIONS]

#### Mandatory Arguments
-d --domain Target domain
-d --domain Target domain; OR
-l --list Newline separated file of domains to scan

#### Optional Arguments
-w --wordlist <wordlist> Wordlist of subdomains to use
Expand Down
122 changes: 70 additions & 52 deletions dnscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ def get_args():
global args

parser = argparse.ArgumentParser('dnscan.py', formatter_class=lambda prog:argparse.HelpFormatter(prog,max_help_position=40))
parser.add_argument('-d', '--domain', help='Target domain', dest='domain', required=True)
target = parser.add_mutually_exclusive_group(required=True) # Allow a user to specify a list of target domains
target.add_argument('-d', '--domain', help='Target domain', dest='domain', required=False)
target.add_argument('-l', '--list', help='File containing list of target domains', dest='domain_list', required=False)
parser.add_argument('-w', '--wordlist', help='Wordlist', dest='wordlist', required=False)
parser.add_argument('-t', '--threads', help='Number of threads', dest='threads', required=False, type=int, default=8)
parser.add_argument('-6', '--ipv6', help='Scan for AAAA records', action="store_true", dest='ipv6', required=False, default=False)
Expand All @@ -241,8 +243,9 @@ def get_args():
args = parser.parse_args()

def setup():
global target, wordlist, queue, resolver, recordtype, outfile
target = args.domain
global targets, wordlist, queue, resolver, recordtype, outfile
if args.domain:
targets = [args.domain]
if args.tld and not args.wordlist:
args.wordlist = os.path.join(os.path.dirname(os.path.realpath(__file__)), "tlds.txt")
else:
Expand Down Expand Up @@ -286,55 +289,70 @@ def setup():
out = output()
get_args()
setup()
if args.tld:
if "." in target:
out.warn("Warning: TLD scanning works best with just the domain root")
out.good("TLD Scan")
add_tlds(target)
else:
queue.put(target) # Add actual domain as well as subdomains

nameservers = get_nameservers(target)
out.good("Getting nameservers")
targetns = [] # NS servers for target
try: # Subdomains often don't have NS recoards..
for ns in nameservers:
ns = str(ns)[:-1] # Removed trailing dot
res = lookup(ns, "A")
for rdata in res:
targetns.append(rdata.address)
print(rdata.address + " - " + col.brown + ns + col.end)
if outfile:
print(rdata.address + " - " + ns, file=outfile)
zone_transfer(target, ns)
except SystemExit:
sys.exit(0)
except:
out.warn("Getting nameservers failed")
# resolver.nameservers = targetns # Use target's NS servers for lokups
# Missing results using domain's NS - removed for now
out.warn("Zone transfer failed\n")
if args.zonetransfer:
sys.exit(0)

get_v6(target)
get_txt(target)
get_mx(target)
wildcard = get_wildcard(target)
out.status("Scanning " + target + " for " + recordtype + " records")
add_target(target)

for i in range(args.threads):
t = scanner(queue)
t.setDaemon(True)
t.start()
try:
if args.domain_list:
out.verbose("Domain list provided, will parse {} for domains.".format(args.domain_list))
if not os.path.isfile(args.domain_list):
out.fatal("Domain list {} doesn't exist!".format(args.domain_list))
sys.exit(1)
with open(args.domain_list, 'r') as domain_list:
try:
targets = list(filter(bool, domain_list.read().split('\n')))
except Exception as e:
out.fatal("Couldn't read {}, {}".format(args.domain_list, e))
sys.exit(1)
for subtarget in targets:
global target
target = subtarget
out.status("Processing domain {}".format(target))
if args.tld:
if "." in target:
out.warn("Warning: TLD scanning works best with just the domain root")
out.good("TLD Scan")
add_tlds(target)
else:
queue.put(target) # Add actual domain as well as subdomains

nameservers = get_nameservers(target)
out.good("Getting nameservers")
targetns = [] # NS servers for target
try: # Subdomains often don't have NS recoards..
for ns in nameservers:
ns = str(ns)[:-1] # Removed trailing dot
res = lookup(ns, "A")
for rdata in res:
targetns.append(rdata.address)
print(rdata.address + " - " + col.brown + ns + col.end)
if outfile:
print(rdata.address + " - " + ns, file=outfile)
zone_transfer(target, ns)
except SystemExit:
sys.exit(0)
except:
out.warn("Getting nameservers failed")
# resolver.nameservers = targetns # Use target's NS servers for lokups
# Missing results using domain's NS - removed for now
out.warn("Zone transfer failed\n")
if args.zonetransfer:
sys.exit(0)

get_v6(target)
get_txt(target)
get_mx(target)
wildcard = get_wildcard(target)
out.status("Scanning " + target + " for " + recordtype + " records")
add_target(target)

for i in range(args.threads):
t.join(1024) # Timeout needed or threads ignore exceptions
except KeyboardInterrupt:
out.fatal("Caught KeyboardInterrupt, quitting...")
if outfile:
outfile.close()
sys.exit(1)
t = scanner(queue)
t.setDaemon(True)
t.start()
try:
for i in range(args.threads):
t.join(1024) # Timeout needed or threads ignore exceptions
except KeyboardInterrupt:
out.fatal("Caught KeyboardInterrupt, quitting...")
if outfile:
outfile.close()
sys.exit(1)
if outfile:
outfile.close()