From f8782d5e9712dcd98ccc10e8908530a17f02a3d8 Mon Sep 17 00:00:00 2001 From: thewhiteh4t Date: Sat, 29 Jun 2024 13:30:56 +0530 Subject: [PATCH] hunter.how added in subdomain enum --- finalrecon.py | 2 +- modules/subdom.py | 4 +- modules/subdomain_modules/hunter_subs.py | 88 ++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 modules/subdomain_modules/hunter_subs.py diff --git a/finalrecon.py b/finalrecon.py index 4153e0b..54207f9 100644 --- a/finalrecon.py +++ b/finalrecon.py @@ -140,7 +140,7 @@ def banner(): def save_key(key_string): - valid_keys = ['bevigil', 'binedge', 'facebook', 'netlas', 'shodan', 'virustotal', 'zoomeye'] + valid_keys = ['bevigil', 'binedge', 'facebook', 'netlas', 'shodan', 'virustotal', 'zoomeye', 'hunter'] key_parts = key_string.split('@', 1) key_name = key_parts[0] key_str = key_parts[1] diff --git a/modules/subdom.py b/modules/subdom.py index e4deb69..14ad799 100644 --- a/modules/subdom.py +++ b/modules/subdom.py @@ -18,6 +18,7 @@ from modules.subdomain_modules.binedge_subs import binedge from modules.subdomain_modules.zoomeye_subs import zoomeye from modules.subdomain_modules.netlas_subs import netlas +from modules.subdomain_modules.hunter_subs import hunter R = '\033[31m' # red G = '\033[32m' # green @@ -44,7 +45,8 @@ async def query(hostname, tout, conf_path): crtsh(hostname, session), binedge(hostname, conf_path, session), zoomeye(hostname, conf_path, session), - netlas(hostname, conf_path, session) + netlas(hostname, conf_path, session), + hunter(hostname, conf_path, session) ) await session.close() diff --git a/modules/subdomain_modules/hunter_subs.py b/modules/subdomain_modules/hunter_subs.py new file mode 100644 index 0000000..635baea --- /dev/null +++ b/modules/subdomain_modules/hunter_subs.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 + +from os import environ +from base64 import b64encode +from json import loads, dumps +import modules.subdom as parent +from modules.write_log import log_writer +from datetime import datetime, timedelta + +R = '\033[31m' # red +G = '\033[32m' # green +C = '\033[36m' # cyan +W = '\033[0m' # white +Y = '\033[33m' # yellow + + +async def hunter(hostname, conf_path, session): + hunter_key = environ.get('FR_HUNTER_KEY') + + if not hunter_key: + log_writer('[hunter_subs] key missing in env') + with open(f'{conf_path}/keys.json', 'r') as keyfile: + json_read = keyfile.read() + + json_load = loads(json_read) + try: + hunter_key = json_load['hunter'] + except KeyError: + log_writer('[hunter_subs] key missing in keys.json') + with open(f'{conf_path}/keys.json', 'w') as outfile: + json_load['hunter'] = None + hunter_key = None + outfile.write( + dumps(json_load, sort_keys=True, indent=4) + ) + + if hunter_key is not None: + print(f'{Y}[!] {C}Requesting {G}Hunter{W}') + url = f'https://api.hunter.how/search' + query = f'domain.suffix=="{hostname}"' + query64 = b64encode(query.encode()).decode() + start_year = datetime.today().year - 1 + start_month = datetime.today().month + start_day = datetime.today().day + try: + start_date = datetime.strptime( + f'{start_year}-{start_month}-{start_day}', '%Y-%m-%d').strftime('%Y-%m-%d') + except ValueError: + # handle leap year + start_date = datetime.strptime( + f'{start_year}-{start_month}-{start_day - 1}', '%Y-%m-%d').strftime('%Y-%m-%d') + end_date = (datetime.today() - timedelta(days=2)).strftime('%Y-%m-%d') + + payload = { + 'api-key': hunter_key, + 'query': query64, + 'page': 1, + 'page_size': 1000, + 'start_time': start_date, + 'end_time': end_date + } + try: + async with session.get(url, params=payload) as resp: + status = resp.status + if status == 200: + json_data = await resp.json() + resp_code = json_data['code'] + if resp_code != 200: + resp_msg = json_data['message'] + print(f'{R}[-] {C}Hunter Status : {W}{resp_code}, {resp_msg}') + log_writer(f'[hunter_subs] Status = {resp_code}, expected 200') + return + subdomain_list = json_data['data']['list'] + subdomains = [] + for entry in subdomain_list: + subdomains.append(entry['domain']) + print(f'{G}[+] {Y}hunter {W}found {C}{len(subdomains)} {W}subdomains!') + parent.found.extend(subdomains) + else: + print(f'{R}[-] {C}Hunter Status : {W}{status}') + log_writer(f'[hunter_subs] Status = {status}, expected 200') + except Exception as exc: + print(f'{R}[-] {C}Hunter Exception : {W}{exc}') + log_writer(f'[hunter_subs] Exception = {exc}') + else: + print(f'{Y}[!] Skipping hunter : {W}API key not found!') + log_writer('[hunter_subs] API key not found') + log_writer('[hunter_subs] Completed')