Last active
October 25, 2020 14:50
-
-
Save StoneSwine/dfd5fab7fabc916c22f8237048f0ad66 to your computer and use it in GitHub Desktop.
Bruteforce resolving subdomains of a domain. I think it ignores wildcard domains, not sure if it works though.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import urllib.request | |
import argparse | |
import shutil | |
import string | |
import random | |
from pathlib import Path | |
from json import JSONDecodeError | |
import json | |
import os | |
import subprocess | |
import tempfile | |
import argparse | |
# ... | |
parser = argparse.ArgumentParser() | |
parser.add_argument( | |
"-d", | |
"--domain", | |
required=True, | |
action="append" | |
) | |
args = parser.parse_args() | |
domains=args.domain | |
program_path="massdns" | |
if shutil.which(program_path) is None: | |
print(f"[ERROR]: '{program_path}' needs to be installed or in path") | |
exit(1) | |
subdomain_wordlist = "wl.txt" | |
url = "https://gist.githubusercontent.com/StoneSwine/e2704c582c66ef350fb2ce965ed1b7ca/raw/afb633277399ddb9cc5009efdb7975ca391e47ed/subdomains_v1.txt" | |
urllib.request.urlretrieve(url, subdomain_wordlist) | |
tmp_dom=Path(tempfile.mkstemp()[1]) | |
resolver_list = "rs.txt" | |
url = "https://raw.githubusercontent.com/TheRook/subbrute/master/resolvers.txt" | |
urllib.request.urlretrieve(url, resolver_list) | |
subdomain_list = [] | |
for i in domains: | |
for word in open(subdomain_wordlist).readlines(): | |
subdomain_list.append(f'{word.strip()}.{i}') | |
with open(tmp_dom, "w") as f: | |
f.writelines("\n".join(subdomain_list)) | |
def has_type_a(i): | |
for j in i: | |
if j["type"] == "A": | |
return True | |
return False | |
def run_massdns_command(infile, outfile): | |
command = [ | |
program_path, | |
'-s', '10000', | |
'-t', 'A', | |
'-o', 'J', | |
'-r', str(resolver_list), | |
'-w', str(outfile), | |
'--verify-ip', '-q', | |
str(infile) | |
] | |
subprocess.run(command, stdout=subprocess.DEVNULL) | |
massdns_out = Path(tempfile.mkstemp()[1]) | |
massdns_in = tmp_dom | |
wildcard_in = Path(tempfile.mkstemp()[1]) | |
wildcard_out = Path(tempfile.mkstemp()[1]) | |
wildcard_list = [] | |
wildcard = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(60)) | |
wildcard_domains = [f"{wildcard}.{d}" for d in domains] | |
with open(wildcard_in, "a") as f: | |
f.writelines("\n".join(wildcard_domains)) | |
run_massdns_command(wildcard_in, wildcard_out) | |
with open(str(wildcard_out), "r") as f: | |
for i in f.readlines(): | |
try: | |
i = json.loads(i.strip()) | |
if has_type_a(i["data"]["answers"]): | |
for j in i["data"]["answers"]: | |
if j['type'] == "A": # IPv4 DNS record | |
ans_rdata = j['data'] | |
if ans_rdata not in wildcard_list: | |
wildcard_list.append(str(ans_rdata)) | |
except (KeyError, JSONDecodeError): | |
pass | |
# Write the rest of the subdomains to the file created by bruteforce subdomains | |
with open(massdns_in, "a") as f: | |
f.writelines("\n".join(domains)) | |
run_massdns_command(massdns_in, massdns_out) | |
with open(str(massdns_out), "r") as f: | |
for i in f.readlines(): | |
try: | |
# Make sure a wildcard response is not in the line: This is essential to speed up the parsing process | |
if not any([True for wip in wildcard_list if wip in i]): # The goal here is for any to return false on empty array | |
i = json.loads(i.strip()) | |
if has_type_a(i["data"]["answers"]): | |
for j in i["data"]["answers"]: | |
ans_type = j['type'] | |
ans_rdat = j['data'] | |
ans_rname = j['name'][:-1] if j['name'][-1] == "." else j['name'] | |
if ans_type == "A" and any([i in ans_rname for i in domains]): # IPv4 DNS record | |
print(f"{ans_rname}:{ans_rdat}") | |
except (KeyError, JSONDecodeError): | |
pass | |
for f in [subdomain_wordlist, resolver_list]: | |
if os.path.exists(f): | |
os.remove(f) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment