From 7fa2ae3085d860c1eadf37ca97078624e52845e8 Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Wed, 23 Jun 2021 11:13:00 +0200 Subject: [PATCH 1/4] Pass request_timeout to general_enum The request_timeout variable is used inside of the general_enum function, but the variable is not defined in that scope, so we pass it as a parameter --- dnsrecon.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsrecon.py b/dnsrecon.py index 04a80d83..170d84a1 100755 --- a/dnsrecon.py +++ b/dnsrecon.py @@ -907,7 +907,7 @@ def check_recursive(res, ns_server, timeout): return is_recursive -def general_enum(res, domain, do_axfr, do_bing, do_yandex, do_spf, do_whois, do_crt, zw, thread_num=None): +def general_enum(res, domain, do_axfr, do_bing, do_yandex, do_spf, do_whois, do_crt, zw, request_timeout, thread_num=None): """ Function for performing general enumeration of a domain. It gets SOA, NS, MX A, AAAA and SRV records for a given domain. It will first try a Zone Transfer @@ -1648,7 +1648,7 @@ def main(): elif type_ == 'std': print_status(f"{type_}: Performing General Enumeration against: {domain}...") std_enum_records = general_enum(res, domain, xfr, bing, yandex, - spf_enum, do_whois, do_crt, zonewalk, + spf_enum, do_whois, do_crt, zonewalk, request_timeout, thread_num=thread_num) if do_output: returned_records.extend(std_enum_records) From ab219fd539e7c4711cad6b9ddcebb889354d3efc Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Wed, 23 Jun 2021 11:16:11 +0200 Subject: [PATCH 2/4] Change user-agent and add timeout for bing enum Bing is sometimes not coopearting with the default user-agent it seems, so a custom user-agent seems appropriate here. A timeout is also good practice as running into the timeout will allow dnsrecon to continue even this request fails. --- lib/bingenum.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/bingenum.py b/lib/bingenum.py index 03709f23..e951eca5 100644 --- a/lib/bingenum.py +++ b/lib/bingenum.py @@ -37,7 +37,15 @@ def scrape_bing(dom): for n in searches: url = "http://www.bing.com/search?q=domain%3A" + dom + "&qs=n&first=" + n - sock = urllib.request.urlopen(url) + req = urllib.request.Request( + url, + data=None, + headers={ + 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36' + } + ) + + sock = urllib.request.urlopen(req, timeout=10) data = sock.read().decode("utf-8") results.extend(re.findall(r"([a-zA-Z0-9\-.]+" + dom + ")/?", data)) sock.close() From e360b1f1d5dd6851eeb1667909a55d447db54552 Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Wed, 23 Jun 2021 11:19:47 +0200 Subject: [PATCH 3/4] Add timeouts to crt.sh and yandex enumerations With the timeout set for the enum requests, dnsrecon may continue running even if one of the services is temporarily down or not reachable. crt.sh sometimes takes longer to respond, so a higher 30 second timeout was chosen here. --- lib/crtenum.py | 2 +- lib/yandexenum.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/crtenum.py b/lib/crtenum.py index 3a900fa7..a203315b 100644 --- a/lib/crtenum.py +++ b/lib/crtenum.py @@ -34,7 +34,7 @@ def scrape_crtsh(dom): req = Request(url=url, headers=headers) try: - resp = urlopen(req) + resp = urlopen(req, timeout=30) data = resp.read() except HTTPError as e: print_error(f'Bad http status from crt.sh: "{e.code}"') diff --git a/lib/yandexenum.py b/lib/yandexenum.py index ce92fe51..ddf5c7ec 100644 --- a/lib/yandexenum.py +++ b/lib/yandexenum.py @@ -16,7 +16,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - import urllib import re import time @@ -42,7 +41,7 @@ def scrape_yandex(dom): for _ in searches: url = "https://yandex.com/search/?text=site%3A" + dom try: - sock = urllib.request.urlopen(url) + sock = urllib.request.urlopen(url, timeout=10) data = sock.read().decode("utf-8") sock.close() except Exception as e: From acaacb45cf966d6ebb3520ff06fd8a8c384ac6c2 Mon Sep 17 00:00:00 2001 From: Markus Schneider Date: Wed, 23 Jun 2021 11:21:24 +0200 Subject: [PATCH 4/4] Check if variables are non-empty before using Some variables may be None in some circumstances if something went wrong, these checks will prevent dnsrecon from crashing in those cases. --- dnsrecon.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dnsrecon.py b/dnsrecon.py index 170d84a1..2639a0ac 100755 --- a/dnsrecon.py +++ b/dnsrecon.py @@ -453,7 +453,7 @@ def brute_domain(res, dictfile, dom, filter_=None, verbose=False, ignore_wildcar if type_ in ['A', 'AAAA']: # Filter Records if filtering was enabled if filter_: - if address_or_target_ not in wildcard_set: + if wildcard_set and address_or_target_ not in wildcard_set: print_and_append = True found_dict["address"] = address_or_target_ else: @@ -1073,10 +1073,11 @@ def general_enum(res, domain, do_axfr, do_bing, do_yandex, do_spf, do_whois, do_ if do_crt: print_status("Performing Crt.sh Search Enumeration") crt_rcd = se_result_process(res, scrape_crtsh(domain)) - for r in crt_rcd: - if "address" in crt_rcd: - ip_for_whois.append(r["address"]) - returned_records.extend(crt_rcd) + if crt_rcd: + for r in crt_rcd: + if "address" in crt_rcd: + ip_for_whois.append(r["address"]) + returned_records.extend(crt_rcd) if do_whois: whois_rcd = whois_ips(res, ip_for_whois) @@ -1650,7 +1651,7 @@ def main(): std_enum_records = general_enum(res, domain, xfr, bing, yandex, spf_enum, do_whois, do_crt, zonewalk, request_timeout, thread_num=thread_num) - if do_output: + if do_output and std_enum_records: returned_records.extend(std_enum_records) elif type_ == 'rvl':