class Tip: parser = Parser() config = Config() badges = Badges() colors = Colors() colors_script = ColorsScript() def print_random_tip(self): if os.path.exists(self.config.path_config['tips_path']): tips = [] all_tips = os.listdir(self.config.path_config['tips_path']) for tip in all_tips: tips.append(tip) if tips: tip = "" while not tip: random_tip = random.randint(0, len(tips) - 1) tip = self.colors_script.parse_colors_script( self.config.path_config['tips_path'] + tips[random_tip]) self.badges.print_empty( f"%newline%endHatSploit Tip: {tip}%end%newline") else: self.badges.print_warning("No tips detected.") else: self.badges.print_warning("No tips detected.")
class Blinder: badges = Badges() post_tools = PostTools() def blinder(self, sender, args={}): self.badges.print_empty() self.badges.print_information( "Welcome to Blinder, blind command injection handler.") self.badges.print_information( "Blinder is not a reverse shell, just a blind command injection.") self.badges.print_empty() while True: commands = self.badges.input_empty("%lineblinder%end > ") command = ' '.join(commands) if not command.strip() or command == 'exit': return self.badges.print_process("Sending command to target...") output = self.post_tools.post_command(sender, command, args) if output: self.badges.print_empty(f'\n{output}') self.badges.print_empty('')
def __init__(self): self.badges = Badges() self.local_storage = LocalStorage() self.user_path = f'{pathlib.Path.home()}/.hsf/' self.base_path = f'{os.path.dirname(os.path.dirname(__file__))}/' self.config_path = self.base_path + 'config/' self.db_config_file = self.config_path + 'db_config.yml' self.core_config_file = self.config_path + 'core_config.yml' self.db_config = self.local_storage.get("db_config") self.path_config = { 'user_path': self.user_path, 'loot_path': f'{self.user_path}loot/', 'db_path': f'{self.user_path}db/', 'accept_path': f'{self.user_path}accept', 'history_path': f'{self.user_path}history', 'startup_path': f'{self.user_path}startup.hsf', 'root_path': self.base_path, 'data_path': f'{self.base_path}data/', 'tips_path': f'{self.base_path}data/tips/', 'banners_path': f'{self.base_path}data/banners/', 'wordlists_path': f'{self.base_path}data/wordlists/', 'exploits_path': f'{self.base_path}data/exploits/', 'modules_path': f'{self.base_path}modules/', 'plugins_path': f'{self.base_path}plugins/', 'commands_path': f'{self.base_path}commands/', 'payloads_path': f'{self.base_path}payloads/', 'storage_path': f'{self.base_path}config/storage.json' } self.core_config = self.local_storage.get("core_config")
class FSTools: badges = Badges() def exists(self, path): if os.path.isdir(path): return True, True directory = os.path.split(path)[0] if not directory: return True, False if self.exists_dir(directory): return True, False return False, False def exists_dir(self, path): if os.path.exists(path): if not os.path.isdir(path): self.badges.print_error(f"Local path: {path}: is not a directory!") return False return True self.badges.print_error(f"Local directory: {directory}: does not exist!") return False def exists_file(self, path): if os.path.exists(path): if os.path.isdir(path): self.badges.print_error(f"Local path: {path}: is a directory!") return False return True self.badges.print_error(f"Local file: {path}: does not exist!") return False
class Update: config = Config() badges = Badges() def check_update(self): try: remote_config = requests.get( 'https://raw.githubusercontent.com/EntySec/HatSploit/main/hatsploit/config/core_config.yml', stream=True).content except Exception: remote_config = None if remote_config: remote_version = self.config.get_config_file( remote_config)['details']['version'] local_version = self.config.core_config['details']['version'] return version.parse(local_version) < version.parse(remote_version) return remote_config def update(self): if self.check_update(): self.badges.print_process("Updating HatSploit Framework...") shutil.rmtree(os.path.abspath( self.config.path_config['root_path'])) subprocess.call([ 'pip3', 'install', 'git+https://github.com/EntySec/HatSploit', '--ignore-installed' ], shell=False) self.badges.print_success("HatSploit updated successfully!") return self.badges.print_warning("Your HatSploit is up-to-date.")
class Banner: parser = Parser() config = Config() badges = Badges() colors = Colors() colors_script = ColorsScript() def print_random_banner(self): if os.path.exists(self.config.path_config['banners_path']): banners = [] all_banners = os.listdir(self.config.path_config['banners_path']) for banner in all_banners: banners.append(banner) if banners: banner = "" while not banner: random_banner = random.randint(0, len(banners) - 1) banner = self.colors_script.parse_colors_script( self.config.path_config['banners_path'] + banners[random_banner]) self.badges.print_empty(f"%newline%end{banner}%end%newline") else: self.badges.print_warning("No banners detected.") else: self.badges.print_warning("No banners detected.")
class Tables: badges = Badges() def print_table(self, name, headers, *args, **kwargs) -> None: extra_fill = kwargs.get("extra_fill", 4) header_separator = kwargs.get("header_separator", "-") if not all(map(lambda x: len(x) == len(headers), args)): return def custom_len(x): x = str(x) try: if '\033' in x: return len(x) - 9 * x.count('\033') // 2 return len(x) except TypeError: return 0 fill = [] headers_line = ' ' headers_separator_line = ' ' for idx, header in enumerate(headers): column = [custom_len(arg[idx]) for arg in args] column.append(len(header)) current_line_fill = max(column) + extra_fill fill.append(current_line_fill) headers_line = "".join( (headers_line, "{header:<{fill}}".format(header=header, fill=current_line_fill))) headers_separator_line = "".join( (headers_separator_line, "{:<{}}".format(header_separator * len(header), current_line_fill))) self.badges.print_empty('\n' + name.split()[0].title() + name[len(name.split()[0]):] + ':') self.badges.print_empty() self.badges.print_empty(headers_line) self.badges.print_empty(headers_separator_line) for arg in args: content_line = " " for idx, element in enumerate(arg): element = str(element) fill_line = fill[idx] if '\033' in element: fill_line = fill[idx] + 9 * element.count('\033') // 2 content_line = "".join( (content_line, "{:<{}}".format(element, fill_line))) self.badges.print_empty(content_line) self.badges.print_empty()
class Loader: badges = Badges() importer = Importer() builder = Builder() update = Update() config = Config() build = True def load_update_process(self): if self.update.check_update(): self.badges.print_warning("Your HatSploit Framework is out-dated.") self.badges.print_information("Consider running %greenhsf --update%end.") time.sleep(1) def load_components(self): if not self.builder.check_base_built() and self.build: self.builder.build_base() self.importer.import_all(self.build) def load_everything(self): self.load_components() def load_all(self): self.load_update_process() if not self.builder.check_base_built(): build = self.badges.input_question("Do you want to build and connect base databases? [y/n] ") if build[0].lower() in ['y', 'yes']: self.build = True else: self.build = False loading_process = threading.Thread(target=self.load_everything) loading_process.start() base_line = "Loading the HatSploit Framework..." cycle = 0 while loading_process.is_alive(): for char in "/-\|": status = base_line + char cycle += 1 if status[cycle % len(status)] in list(string.ascii_lowercase): status = status[:cycle % len(status)] + status[cycle % len(status)].upper() + status[cycle % len( status) + 1:] elif status[cycle % len(status)] in list(string.ascii_uppercase): status = status[:cycle % len(status)] + status[cycle % len(status)].lower() + status[cycle % len( status) + 1:] self.badges.print_process(status, '', '\r') time.sleep(.1) loading_process.join()
class Log: config = Config() badges = Badges() storage_path = config.path_config['storage_path'] global_storage = GlobalStorage(storage_path) def enable_log(self, filename): if os.access(filename, os.R_OK): self.global_storage.set("log", filename) self.global_storage.set_all() self.badges.print_information("HatSploit log: on") def disable_log(self): self.global_storage.set("log", None) self.global_storage.set_all() self.badges.print_information("HatSploit log: off")
class HatSploit: jobs = Jobs() console = Console() badges = Badges() check = Check() update = Update() path_config = config.path_config def accept_terms_of_service(self): if not os.path.exists(self.path_config['accept_path']): self.badges.print_information( "--( The HatSploit Terms of Service )--") terms = """ This tool is designed for educational purposes only. Adequate defenses can only be built by researching attack techniques available to malicious actors. Using this tool against target systems without prior permission is illegal in most jurisdictions. The authors are not liable for any damages from misuse of this information or code. If you are planning on using this tool for malicious purposes that are not authorized by the company you are performing assessments for, you are violating the terms of service and license. By accepting our terms of service, you agree that you will only use this tool for lawful purposes only. """ self.badges.print_empty(terms) agree = self.badges.input_question( "Accept HatSploit Framework Terms of Service? [y/n] ") if agree[0].lower() not in ['y', 'yes']: return False open(self.path_config['accept_path'], 'w').close() return True return True def launch(self, do_shell=True, script=[]): if self.console.check_install(): if self.accept_terms_of_service(): if not script: if do_shell: self.console.shell() else: self.console.script(script, do_shell)
class History: config = Config() badges = Badges() local_storage = LocalStorage() history = config.path_config['history_path'] storage_path = config.path_config['storage_path'] global_storage = GlobalStorage(storage_path) def enable_history(self): self.global_storage.set("history", True) self.global_storage.set_all() self.badges.print_information("HatSploit history: on") def disable_history(self): self.global_storage.set("history", False) self.global_storage.set_all() readline.clear_history() with open(self.history, 'w') as history: history.write("") self.badges.print_information("HatSploit history: off") def clear_history(self): readline.clear_history() with open(self.history, 'w') as history: history.write("") def list_history(self): using_history = self.local_storage.get("history") if using_history: if readline.get_current_history_length() > -1: self.badges.print_information("HatSploit history:") for index in range(1, readline.get_current_history_length() + 1): self.badges.print_empty(" * " + readline.get_history_item(index)) else: self.badges.print_warning("HatSploit history empty.") else: self.badges.print_warning("No HatSploit history detected.")
class Commands: show = Show() importer = Importer() badges = Badges() execute = Execute() modules = Modules() local_storage = LocalStorage() def load_commands(self, path): return self.importer.import_commands(path) def execute_command(self, commands): self.execute.execute_command(commands) def execute_system_command(self, commands): self.execute.execute_system(commands) def execute_custom_command(self, commands, handler, error=True): if commands: if not self.execute.execute_builtin_method(commands): if not self.execute.execute_custom_command(commands, handler): if error: self.badges.print_error( f"Unrecognized command: {commands[0]}!") return False return True def show_commands(self, handler): self.show.show_custom_commands(handler) def commands_completer(self, text): return [ command for command in self.get_all_commands() if command.startswith(text) ] def get_commands(self): return self.local_storage.get("commands") def get_modules_commands(self): module = self.modules.get_current_module_object() if module: return module.commands if hasattr(module, "commands") else {} return {} def get_plugins_commands(self): plugins = self.local_storage.get("loaded_plugins") commands = {} if plugins: for plugin in plugins: if hasattr(plugins[plugin], "commands"): for label in plugins[plugin].commands: commands.update(plugins[plugin].commands[label]) return commands def get_all_commands(self): commands = {} module = self.modules.get_current_module_object() if module: if hasattr(module, "commands"): commands.update(module.commands) plugins = self.local_storage.get("loaded_plugins") if plugins: for plugin in plugins: if hasattr(plugins[plugin], "commands"): for label in plugins[plugin].commands: commands.update(plugins[plugin].commands[label]) commands.update(self.local_storage.get("commands")) return commands
class Check: config = Config() importer = Importer() badges = Badges() def check_modules(self): one_fail = False self.badges.print_process("Checking all base modules...") modules_path = os.path.normpath( self.config.path_config['modules_path']) for dest, _, files in os.walk(modules_path): for file in files: if file.endswith('.py') and file != '__init__.py': module = dest + '/' + file[:-3] try: module_object = self.importer.import_module(module) keys = [ 'Category', 'Name', 'Module', 'Authors', 'Description', 'Platform', 'Rank' ] assert (all(key in module_object.details for key in keys)) self.badges.print_success(f"{module}: OK") except Exception: self.badges.print_error(f"{module}: FAIL") one_fail = True return not one_fail def check_payloads(self): one_fail = False self.badges.print_process("Checking all base payloads...") payloads_path = os.path.normpath( self.config.path_config['payloads_path']) for dest, _, files in os.walk(payloads_path): for file in files: if file.endswith('.py') and file != '__init__.py': payload = dest + '/' + file[:-3] try: payload_object = self.importer.import_payload(payload) keys = [ 'Category', 'Name', 'Payload', 'Authors', 'Description', 'Architecture', 'Platform', 'Rank', 'Type' ] assert (all(key in payload_object.details for key in keys)) self.badges.print_success(f"{payload}: OK") except Exception: self.badges.print_error(f"{payload}: FAIL") one_fail = True return not one_fail def check_plugins(self): one_fail = False self.badges.print_process("Checking all base plugins...") plugins_path = os.path.normpath( self.config.path_config['plugins_path']) for dest, _, files in os.walk(plugins_path): for file in files: if file.endswith('.py') and file != '__init__.py': plugin = dest + '/' + file[:-3] try: plugin_object = self.importer.import_plugin(plugin) keys = ['Name', 'Authors', 'Description'] assert (all(key in plugin_object.details for key in keys)) self.badges.print_success(f"{plugin}: OK") except Exception: self.badges.print_error(f"{plugin}: FAIL") one_fail = True return not one_fail def check_all(self): fails = [] fails.append(self.check_modules()) fails.append(self.check_payloads()) fails.append(self.check_plugins()) for fail in fails: if not fail: self.badges.print_error("Not all checks passed!") return False self.badges.print_success("All checks passed!") return True
class Payloads: hatvenom = HatVenom() types = TypeTools() importer = Importer() options = Options() local_storage = LocalStorage() badges = Badges() def get_payloads(self): return self.local_storage.get("payloads") def get_imported_payloads(self): return self.local_storage.get("imported_payloads") def payloads_completer(self, text): payloads = self.get_payloads() matches = [] if payloads: for database in payloads: for payload in payloads[database]: if payload.startswith(text): matches.append(payload) return matches def check_exist(self, name): all_payloads = self.get_payloads() if all_payloads: for database in all_payloads: payloads = all_payloads[database] if name in payloads: return True return False def get_payload_object(self, name): if self.check_exist(name): database = self.get_database(name) return self.get_payloads()[database][name] return None def check_module_compatible(self, value, categories, types, platforms, architectures): if self.check_exist(value): payload = self.get_payload_object(value) if categories: if payload['Category'] not in categories: return False if types: if payload['Type'] not in types: return False if platforms: if payload['Platform'] not in platforms: return False if architectures: if payload['Architecture'] not in architectures: return False return True return False def get_database(self, name): all_payloads = self.get_payloads() if all_payloads: for database in all_payloads: payloads = all_payloads[database] if name in payloads: return database return None def check_current_module(self): if self.local_storage.get("current_module"): if len(self.local_storage.get("current_module")) > 0: return True return False def get_current_module_object(self): if self.check_current_module(): return self.local_storage.get_array( "current_module", self.local_storage.get("current_module_number")) return None def get_current_module_name(self): if self.check_current_module(): return self.local_storage.get_array( "current_module", self.local_storage.get( "current_module_number")).details['Module'] return None def get_payload(self, name): payloads = self.get_payload_object(name) try: payload_object = self.importer.import_payload(payloads['Path']) except Exception: return None return payload_object def import_payload(self, module_name, name): payload_object = self.get_payload(name) if payload_object: current_module_name = module_name imported_payloads = self.get_imported_payloads() if imported_payloads: if current_module_name in imported_payloads: imported_payloads[current_module_name].update( {payload_object.details['Payload']: payload_object}) else: imported_payloads.update({ current_module_name: { payload_object.details['Payload']: payload_object } }) else: imported_payloads = { current_module_name: { payload_object.details['Payload']: payload_object } } self.local_storage.set("imported_payloads", imported_payloads) return payload_object def check_imported(self, module_name, name): imported_payloads = self.get_imported_payloads() current_module_name = module_name if imported_payloads: if current_module_name in imported_payloads: if name in imported_payloads[current_module_name]: return True return False def validate_options(self, payload_object): current_payload = payload_object missed = "" if hasattr(current_payload, "options"): for option in current_payload.options: current_option = current_payload.options[option] if not current_option['Value'] and current_option[ 'Value'] != 0 and current_option['Required']: missed += option + ', ' return missed def run_payload(self, payload_object): current_payload = payload_object if not self.validate_options(current_payload): payload_options = None if hasattr(current_payload, "options"): payload_options = current_payload.options payload_data = current_payload.run() payload_details = current_payload.details executable = 'raw' for executable_format in self.types.formats: if payload_details['Platform'] in self.types.formats[ executable_format]: executable = executable_format break if isinstance(payload_data, tuple): raw = self.hatvenom.generate('raw', 'generic', payload_data[0], payload_data[1]) payload = self.hatvenom.generate( executable if payload_details['Architecture'] != 'generic' else 'raw', payload_details['Architecture'], payload_data[0], payload_data[1]) else: raw = self.hatvenom.generate('raw', 'generic', payload_data) payload = self.hatvenom.generate( executable if payload_details['Architecture'] != 'generic' else 'raw', payload_details['Architecture'], payload_data) return { 'Options': payload_options, 'Details': payload_details, 'Payload': payload, 'Raw': raw } return {'Options': None, 'Details': None, 'Payload': None, 'Raw': None} def generate_payload(self, name, options={}, raw=False): payload_object = self.get_payload(name) if payload_object: self.options.add_payload_handler(payload_object) if hasattr(payload_object, "options"): for option in options: payload_object.options[option]['Value'] = options[option] result = self.run_payload(payload_object) return result['Raw'] if raw else result['Payload'] return None def get_current_payload(self): imported_payloads = self.get_imported_payloads() current_module_object = self.get_current_module_object() if current_module_object: current_module_name = current_module_object.details['Module'] if hasattr(current_module_object, "payload"): name = current_module_object.payload['Value'] if imported_payloads: if current_module_name in imported_payloads: if name in imported_payloads[current_module_name]: return imported_payloads[current_module_name][name] return None def add_payload(self, module_name, name): if not self.check_imported(module_name, name): payload_object = self.import_payload(module_name, name) if not payload_object: self.badges.print_error( "Failed to select payload from database!") return False return True
class Sessions: badges = Badges() config = Config() storage_path = config.path_config['storage_path'] global_storage = GlobalStorage(storage_path) local_storage = LocalStorage() def get_all_sessions(self): sessions = self.local_storage.get("sessions") return sessions def close_dead(self): sessions = self.local_storage.get("sessions") if sessions: for session in list(sessions): if not sessions[session]['object'].heartbeat(): self.badges.print_warning( f"Session {str(session)} is dead (no heartbeat).") self.close_session(session) def close_sessions(self): if not self.local_storage.get("sessions"): return True self.badges.print_warning("You have some opened sessions.") if self.badges.input_question("Exit anyway? [y/N] ")[0].lower() in [ 'yes', 'y' ]: self.badges.print_process("Closing all sessions...") self.close_all_sessions() return True return False def add_session(self, session_platform, session_architecture, session_type, session_host, session_port, session_object): if not self.local_storage.get("sessions"): self.local_storage.set("sessions", {}) session_id = 0 while (session_id in self.local_storage.get("sessions") or session_id < len(self.local_storage.get("sessions"))): session_id += 1 sessions = { session_id: { 'platform': session_platform, 'architecture': session_architecture, 'type': session_type, 'host': session_host, 'port': session_port, 'object': session_object } } self.local_storage.update("sessions", sessions) return session_id def check_exist(self, session_id, session_platform=None, session_architecture=None, session_type=None): sessions = self.local_storage.get("sessions") if sessions: if int(session_id) in sessions: valid = True if session_platform: if sessions[int( session_id)]['platform'] != session_platform: valid = False if session_type: if sessions[int(session_id)]['type'] != session_type: valid = False if session_architecture: if sessions[int(session_id )]['architecture'] != session_architecture: valid = False return valid return False def enable_auto_interaction(self): self.global_storage.set("auto_interaction", True) self.global_storage.set_all() self.badges.print_information("Auto interaction: on") def disable_auto_interaction(self): self.global_storage.set("auto_interaction", False) self.global_storage.set_all() self.badges.print_information("Auto interaction: off") def interact_with_session(self, session_id): sessions = self.local_storage.get("sessions") if self.check_exist(session_id): self.badges.print_process( f"Interacting with session {str(session_id)}...%newline") sessions[int(session_id)]['object'].interact() else: self.badges.print_error("Invalid session given!") def session_download(self, session_id, remote_file, local_path): sessions = self.local_storage.get("sessions") if self.check_exist(session_id): return sessions[int(session_id)]['object'].download( remote_file, local_path) self.badges.print_error("Invalid session given!") return None def session_upload(self, session_id, local_file, remote_path): sessions = self.local_storage.get("sessions") if self.check_exist(session_id): return sessions[int(session_id)]['object'].upload( local_file, remote_path) self.badges.print_error("Invalid session given!") return None def close_session(self, session_id): sessions = self.local_storage.get("sessions") if self.check_exist(session_id): try: sessions[int(session_id)]['object'].close() del sessions[int(session_id)] self.local_storage.update("sessions", sessions) except Exception: self.badges.print_error("Failed to close session!") else: self.badges.print_error("Invalid session given!") def close_all_sessions(self): sessions = self.local_storage.get("sessions") if sessions: for session in list(sessions): try: sessions[session]['object'].close() del sessions[session] self.local_storage.update("sessions", sessions) except Exception: self.badges.print_error("Failed to close session!") def get_session(self, session_id, session_platform=None, session_architecture=None, session_type=None): sessions = self.local_storage.get("sessions") if self.check_exist(session_id, session_platform, session_architecture, session_type): return sessions[int(session_id)]['object'] self.badges.print_error("Invalid session given!") return None
class Jobs: exceptions = Exceptions() tables = Tables() badges = Badges() local_storage = LocalStorage() modules = Modules() job_process = None def stop_dead(self): jobs = self.local_storage.get("jobs") if jobs: for job_id in list(jobs): if not jobs[job_id]['job_process'].is_alive(): self.delete_job(job_id) hidden_jobs = self.local_storage.get("hidden_jobs") if hidden_jobs: for job_id in list(hidden_jobs): if not hidden_jobs[job_id]['job_process'].is_alive(): self.delete_job(job_id, True) def count_jobs(self): jobs = self.local_storage.get("jobs") if jobs: return len(jobs) return 0 def exit_jobs(self): if not self.local_storage.get("jobs"): if self.local_storage.get("hidden_jobs"): self.stop_all_jobs() return True self.badges.print_warning("You have some running jobs.") if self.badges.input_question("Exit anyway? [y/N] ")[0].lower() in [ 'yes', 'y' ]: self.badges.print_process("Stopping all jobs...") self.stop_all_jobs() return True return False def stop_all_jobs(self): jobs = self.local_storage.get("jobs") if jobs: for job_id in list(jobs): self.delete_job(job_id) hidden_jobs = self.local_storage.get("hidden_jobs") if hidden_jobs: for job_id in list(hidden_jobs): self.delete_job(job_id, True) def stop_job(self, job): if job.is_alive(): exc = ctypes.py_object(SystemExit) res = ctypes.pythonapi.PyThreadState_SetAsyncExc( ctypes.c_long(job.ident), exc) if res == 0: raise self.exceptions.GlobalException if res > 1: ctypes.pythonapi.PyThreadState_SetAsyncExc(job.ident, None) raise self.exceptions.GlobalException def start_job(self, job_function, job_arguments): self.job_process = threading.Thread(target=job_function, args=job_arguments) self.job_process.setDaemon(True) self.job_process.start() def delete_job(self, job_id, hidden=False): jobs_var = "jobs" if hidden: jobs_var = "hidden_jobs" if self.local_storage.get(jobs_var): job_id = int(job_id) if job_id in list(self.local_storage.get(jobs_var)): try: self.stop_job( self.local_storage.get(jobs_var)[job_id] ['job_process']) self.local_storage.delete_element(jobs_var, job_id) except Exception: self.badges.print_error("Failed to stop job!") else: self.badges.print_error("Invalid job given!") else: self.badges.print_error("Invalid job given!") def create_job(self, job_name, module_name, job_function, job_arguments=[], hidden=False): jobs_var = "jobs" if hidden: jobs_var = "hidden_jobs" self.start_job(job_function, job_arguments) if not self.local_storage.get(jobs_var): self.local_storage.set(jobs_var, {}) job_id = len(self.local_storage.get(jobs_var)) job_data = { job_id: { 'job_name': job_name, 'module_name': module_name, 'job_process': self.job_process } } self.local_storage.update(jobs_var, job_data)
class Execute: jobs = Jobs() fmt = FMT() badges = Badges() tables = Tables() local_storage = LocalStorage() modules = Modules() show = Show() def execute_command(self, commands): if commands: if not self.execute_builtin_method(commands): if not self.execute_core_command(commands): if not self.execute_module_command(commands): if not self.execute_plugin_command(commands): self.badges.print_error( f"Unrecognized command: {commands[0]}!") def execute_builtin_method(self, commands): if commands[0][0] == '#': return True if commands[0][0] == '?': self.show.show_all_commands() return True if commands[0][0] == '&': commands[0] = commands[0][1:] self.jobs.create_job(commands[0], None, self.execute_command, [commands], True) return True if commands[0][0] == '!': if len(commands[0]) > 1: commands[0] = commands[0].replace('!', '', 1) self.execute_system(commands) else: self.badges.print_usage("!<command>") return True return False def execute_system(self, commands): self.badges.print_process(f"Executing system command: {commands[0]}\n") try: subprocess.call(commands) except Exception: self.badges.print_error( f"Unrecognized system command: {commands[0]}!") def execute_custom_command(self, commands, handler): if handler: if commands[0] in handler: command = handler[commands[0]] if not self.check_arguments(commands, command.details): self.parse_usage(command.details) else: command.run(len(commands), commands) return True return False def check_arguments(self, commands, details): if (len(commands) - 1) < details['MinArgs']: return False if 'Options' in details: if len(commands) > 1: if commands[1] in details['Options']: if (len(commands) - 2) < len( details['Options'][commands[1]][0].split()): return False else: return False if len(commands) > 1: if commands[1] == '?': return False return True def parse_usage(self, details): self.badges.print_usage(details['Usage']) if 'Options' in details: headers = ('Option', 'Arguments', 'Description') data = [] for option in details['Options']: info = details['Options'][option] data.append((option, info[0], info[1])) self.tables.print_table('Options', headers, *data) def execute_core_command(self, commands): return self.execute_custom_command(commands, self.local_storage.get("commands")) def execute_module_command(self, commands): if self.modules.check_current_module(): if hasattr(self.modules.get_current_module_object(), "commands"): if commands[0] in self.modules.get_current_module_object( ).commands: command_object = self.modules.get_current_module_object() command = self.modules.get_current_module_object( ).commands[commands[0]] self.parse_and_execute_command(commands, command, command_object) return True return False def execute_plugin_command(self, commands): if self.local_storage.get("loaded_plugins"): for plugin in self.local_storage.get("loaded_plugins"): if hasattr( self.local_storage.get("loaded_plugins")[plugin], "commands"): for label in self.local_storage.get( "loaded_plugins")[plugin].commands: if commands[0] in self.local_storage.get( "loaded_plugins")[plugin].commands[label]: command_object = self.local_storage.get( "loaded_plugins")[plugin] command = command_object.commands[label][ commands[0]] self.parse_and_execute_command( commands, command, command_object) return True return False def parse_and_execute_command(self, commands, command, command_object): if hasattr(command_object, commands[0]): if not self.check_arguments(commands, command): self.parse_usage(command) else: getattr(command_object, commands[0])(len(commands), commands) else: self.badges.print_error("Failed to execute command!")
class Modules: types = TypeTools() badges = Badges() sessions = Sessions() payloads = Payloads() local_storage = LocalStorage() importer = Importer() def get_modules(self): return self.local_storage.get("modules") def get_imported_modules(self): return self.local_storage.get("imported_modules") def modules_completer(self, text): modules = self.get_modules() matches = [] if modules: for database in modules: for module in modules[database]: if module.startswith(text): matches.append(module) return matches def check_exist(self, name): all_modules = self.get_modules() if all_modules: for database in all_modules: modules = all_modules[database] if name in modules: return True return False def check_imported(self, name): imported_modules = self.get_imported_modules() if imported_modules: if name in imported_modules: return True return False def check_current_module(self): if self.local_storage.get("current_module"): if len(self.local_storage.get("current_module")) > 0: return True return False def check_if_already_used(self, module): if self.check_current_module(): if module == self.get_current_module_name(): return True return False def get_module_object(self, name): if self.check_exist(name): database = self.get_database(name) return self.get_modules()[database][name] return None def get_current_module_object(self): if self.check_current_module(): return self.local_storage.get_array( "current_module", self.local_storage.get("current_module_number")) return None def get_current_module_platform(self): if self.check_current_module(): return self.local_storage.get_array( "current_module", self.local_storage.get( "current_module_number")).details['Platform'] return None def get_current_module_name(self): if self.check_current_module(): return self.local_storage.get_array( "current_module", self.local_storage.get( "current_module_number")).details['Module'] return None def get_database(self, name): all_modules = self.get_modules() if all_modules: for database in all_modules: modules = all_modules[database] if name in modules: return database return None def compare_type(self, name, value, checker, module=True): value = str(value) if value.startswith('file:') and len(value) > 5 and module: file = value.split(':')[1] if not os.path.isfile(file): self.badges.print_error(f"Local file: {file}: does not exist!") return False with open(file, 'r') as f: for line in f.read().split('\n'): if line.strip(): if not checker(line.strip()): self.badges.print_error( f"File contains invalid value, expected valid {name}!" ) return False return True if not checker(value): self.badges.print_error(f"Invalid value, expected valid {name}!") return False return True def compare_session(self, value_type, value): session = value_type.lower().replace(' ', '') session = session.split('->') session_platforms = [] session_platform = self.get_current_module_platform() session_type = "shell" if len(session) == 2: if session[1].startswith('[') and session[1].endswith(']'): session_platforms = session[1][1:-1].split(',') else: session_type = session[1] elif len(session) == 3: if session[1].startswith('[') and session[1].endswith(']'): session_platforms = session[1][1:-1].split(',') else: session_type = session[1] if session[2].startswith('[') and session[2].endswith(']'): session_platforms = session[2][1:-1].split(',') else: session_type = session[2] if not session_platforms: if not self.sessions.check_exist(value, session_platform, session_type): self.badges.print_error( "Invalid value, expected valid session!") return False else: session = 0 for platform in session_platforms: if self.sessions.check_exist(value, platform.strip(), session_type): session = 1 break if not session: self.badges.print_error( "Invalid value, expected valid session!") return False return True def compare_types(self, value_type, value, module=True): if value_type and not value_type.lower == 'all': if value_type.lower() == 'mac': return self.compare_type("MAC", value, self.types.is_mac, module) if value_type.lower() == 'ip': return self.compare_type("IP", value, self.types.is_ip, module) if value_type.lower() == 'ipv4': return self.compare_type("IPv4", value, self.types.is_ipv4, module) if value_type.lower() == 'ipv6': return self.compare_type("IPv6", value, self.types.is_ipv6, module) if value_type.lower() == 'ipv4_range': return self.compare_type("IPv4 range", value, self.types.is_ipv4_range, module) if value_type.lower() == 'ipv6_range': return self.compare_type("IPv6 range", value, self.types.is_ipv6_range, module) if value_type.lower() == 'port': return self.compare_type("port", value, self.types.is_port, module) if value_type.lower() == 'port_range': return self.compare_type("port range", value, self.types.is_port_range, module) if value_type.lower() == 'number': return self.compare_type("number", value, self.types.is_number, module) if value_type.lower() == 'integer': return self.compare_type("integer", value, self.types.is_integer, module) if value_type.lower() == 'float': return self.compare_type("float", value, self.types.is_float, module) if value_type.lower() == 'boolean': return self.compare_type("boolean", value, self.types.is_boolean, module) if value_type.lower() == 'payload': current_module = self.get_current_module_object() module_name = self.get_current_module_name() module_payload = current_module.payload categories = module_payload['Categories'] types = module_payload['Types'] platforms = module_payload['Platforms'] architectures = module_payload['Architectures'] if self.payloads.check_module_compatible( value, categories, types, platforms, architectures): if self.payloads.add_payload(module_name, value): return True self.badges.print_error( "Invalid valud, expected valid payload!") return False if 'session' in value_type.lower(): value = str(value) if value.startswith('file:') and len(value) > 5 and module: file = value.split(':')[1] if not os.path.isfile(file): self.badges.print_error( f"Local file: {file}: does not exist!") return False with open(file, 'r') as f: for line in f.read().split('\n'): if line.strip(): if not self.compare_session( value_type, line.strip()): self.badges.print_error( f"File contains invalid value, expected valid session!" ) return False return True return self.compare_session(value_type, value) return True def set_current_module_option(self, option, value): if self.check_current_module(): current_module = self.get_current_module_object() if not hasattr(current_module, "options") and not hasattr( current_module, "payload"): self.badges.print_warning("Module has no options.") return if hasattr(current_module, "options"): if option in current_module.options: value_type = current_module.options[option]['Type'] if value_type == 'payload': payloads_shorts = self.local_storage.get( "payload_shorts") if payloads_shorts: if value.isdigit(): payload_number = int(value) if payload_number in payloads_shorts: value = payloads_shorts[payload_number] if self.compare_types(value_type, value): self.badges.print_information(option + " ==> " + value) if option.lower() == 'blinder': if value.lower() in ['y', 'yes']: current_module.payload['Value'] = None if value_type == 'payload': self.local_storage.set_module_payload( "current_module", self.local_storage.get( "current_module_number"), value) else: self.local_storage.set_module_option( "current_module", self.local_storage.get( "current_module_number"), option, value) return if hasattr(current_module, "payload"): current_payload = self.payloads.get_current_payload() if current_payload and hasattr(current_payload, "options"): if option in current_payload.options: value_type = current_payload.options[option]['Type'] if self.compare_types(value_type, value, False): self.badges.print_information(option + " ==> " + value) self.local_storage.set_payload_option( current_module.details['Module'], current_payload.details['Payload'], option, value) else: self.badges.print_error("Unrecognized option!") else: self.badges.print_error("Unrecognized option!") else: self.badges.print_error("Unrecognized option!") else: self.badges.print_warning("No module selected.") def import_module(self, name): modules = self.get_module_object(name) try: module_object = self.importer.import_module(modules['Path']) if not self.get_imported_modules(): self.local_storage.set("imported_modules", {}) self.local_storage.update("imported_modules", {name: module_object}) except Exception: return None return module_object def add_module(self, name): imported_modules = self.get_imported_modules() if self.check_imported(name): module_object = imported_modules[name] self.add_to_global(module_object) else: module_object = self.import_module(name) if module_object: if hasattr(module_object, "payload"): payload_name = module_object.payload['Value'] if payload_name: self.badges.print_process( f"Using default payload {payload_name}...") if self.payloads.check_exist(payload_name): if self.payloads.add_payload(name, payload_name): self.add_to_global(module_object) return self.badges.print_error("Invalid default payload!") return self.add_to_global(module_object) else: self.badges.print_error( "Failed to select module from database!") def add_to_global(self, module_object): if self.check_current_module(): self.local_storage.add_array("current_module", '') self.local_storage.set( "current_module_number", self.local_storage.get("current_module_number") + 1) self.local_storage.set_array( "current_module", self.local_storage.get("current_module_number"), module_object) else: self.local_storage.set("current_module", []) self.local_storage.set("current_module_number", 0) self.local_storage.add_array("current_module", '') self.local_storage.set_array( "current_module", self.local_storage.get("current_module_number"), module_object) def use_module(self, module): modules_shorts = self.local_storage.get("module_shorts") if modules_shorts: if module.isdigit(): module_number = int(module) if module_number in modules_shorts: module = modules_shorts[module_number] if not self.check_if_already_used(module): if self.check_exist(module): self.add_module(module) else: self.badges.print_error("Invalid module!") def go_back(self): if self.check_current_module(): self.local_storage.set( "current_module_number", self.local_storage.get("current_module_number") - 1) self.local_storage.set( "current_module", self.local_storage.get("current_module")[0:-1]) if not self.local_storage.get("current_module"): self.local_storage.set("current_module_number", 0) def entry_to_module(self, current_module): values = [] for option in current_module.options: opt = current_module.options[option] val = str(opt['Value']) if val.startswith('file:') and len(val) > 5: file = val[5:] with open(file, 'r') as f: vals = f.read().strip() values.append(vals.split('\n')) if not values: current_module.run() return if not all(len(value) == len(values[0]) for value in values): self.badges.print_error( "All files should contain equal number of values!") return save = copy.deepcopy(current_module.options) for i in range(0, len(values[0])): count = 0 for option in current_module.options: opt = current_module.options[option] val = str(opt['Value']) if val.startswith('file:') and len(val) > 5: current_module.options[option]['Value'] = values[count][i] count += 1 try: current_module.run() except (KeyboardInterrupt, EOFError): pass current_module.options = save save = copy.deepcopy(current_module.options) def validate_options(self, module_object): current_module = module_object missed = "" if hasattr(current_module, "options"): for option in current_module.options: current_option = current_module.options[option] if not current_option['Value'] and current_option[ 'Value'] != 0 and current_option['Required']: missed += option + ', ' return missed def run_current_module(self): if self.check_current_module(): current_module = self.get_current_module_object() current_module_name = self.get_current_module_name() current_payload = self.payloads.get_current_payload() payload_data = {} missed = self.validate_options(current_module) if current_payload: missed += self.payloads.validate_options(current_payload) if missed: self.badges.print_error( f"These options are failed to validate: {missed[:-2]}!") else: try: if current_payload: payload_data = self.payloads.run_payload( current_payload) for entry in payload_data: current_module.payload[entry] = payload_data[entry] self.badges.print_empty() self.entry_to_module(current_module) self.badges.print_success( f"{current_module_name.split('/')[0].title()} module completed!" ) except (KeyboardInterrupt, EOFError): self.badges.print_warning( f"{current_module_name.split('/')[0].title()} module interrupted." ) except Exception as e: self.badges.print_error( f"An error occurred in module: {str(e)}!") self.badges.print_error( f"{current_module_name.split('/')[0].title()} module failed!" ) if current_payload: for entry in payload_data: del current_module.payload[entry] else: self.badges.print_warning("No module selected.")
class Handler: blinder = Blinder() post = Post() post_tools = PostTools() server_handle = Handle() sessions = Sessions() modules = Modules() jobs = Jobs() types = TypeTools() badges = Badges() local_storage = LocalStorage() def do_job(self, payload_type, target, args): if payload_type == 'one_side': target(*args) else: self.jobs.create_job( None, None, target, args, True ) def ensure_linemax(self, payload, linemax): min_size = 10000 max_size = 100000 if len(payload) >= max_size and linemax not in range(min_size, max_size): self.badges.print_process(f"Ensuring payload size ({str(len(payload))} bytes)...") linemax = max_size return linemax def send(self, sender, payload, args={}): if isinstance(payload, bytes): self.badges.print_process(f"Sending payload stage ({str(len(payload))} bytes)...") else: self.badges.print_process("Sending command payload stage...") self.post_tools.post_command(sender, payload, args) def open_session(self, host, port, session_platform, session_architecture, session_type, session, action=None): session_id = self.sessions.add_session(session_platform, session_architecture, session_type, host, port, session) time = datetime.datetime.now().astimezone().strftime("%Y-%m-%d %H:%M:%S %Z") self.badges.print_success(f"{session_type.title()} session {str(session_id)} opened at {time}!") if action: action() if self.local_storage.get("auto_interaction"): self.sessions.interact_with_session(session_id) def module_handle(self, host=None, sender=None, args={}, concat=None, location=None, background=None, method=None, timeout=None, linemax=100, ensure=False, on_session=None): module = self.modules.get_current_module_object() rhost = host options = module.handler payload = module.payload if 'BLINDER' in options: if options['BLINDER'].lower() in ['yes', 'y']: if sender is not None: self.handle( sender=sender, args=args, blinder=True ) return True stage = payload['Payload'] if method != 'raw' else payload['Raw'] if payload['Details']['Type'] == 'bind_tcp': host = options['RBHOST'] port = options['RBPORT'] elif payload['Details']['Type'] == 'reverse_tcp': host = options['LHOST'] port = options['LPORT'] else: host, port = None, None if 'Session' in payload['Details']: session = payload['Details']['Session'] else: session = None if 'Arguments' in payload['Details']: arguments = payload['Details']['Arguments'] else: arguments = None platform = payload['Details']['Platform'] architecture = payload['Details']['Architecture'] if platform in self.types.platforms: module_platform = module.details['Platform'] if module_platform not in self.types.platforms: platform = module_platform return self.handle( payload=stage, sender=sender, host=host, port=port, rhost=rhost, payload_category=payload['Details']['Category'], payload_type=payload['Details']['Type'], args=args, concat=concat, location=location, background=background, method=method, timeout=timeout, linemax=linemax, platform=platform, architecture=architecture, ensure=ensure, blinder=False, session=session, arguments=arguments, on_session=on_session ) def handle(self, payload=None, sender=None, host=None, port=None, rhost=None, payload_category='stager', payload_type='one_side', args={}, concat=None, location=None, background=None, method=None, timeout=None, linemax=100, platform='generic', architecture='generic', ensure=False, blinder=False, session=None, arguments=None, on_session=None): if blinder: self.blinder.shell(sender, args) return True if not self.send_payload( payload=payload, sender=sender, payload_category=payload_category, payload_type=payload_type, args=args, concat=concat, location=location, background=background, method=method, linemax=linemax, platform=platform, ensure=ensure, arguments=arguments ): self.badges.print_error("Failed to send payload stage!") return False remote = self.handle_session( host=host, port=port, payload_type=payload_type, session=session, timeout=timeout ) if not remote: self.badges.print_warning("Payload sent but no session was opened.") return True session_type = remote[0].details['Type'] remote[0].details['Post'] = method remote[0].details['Platform'] = platform remote[0].details['Architecture'] = architecture if remote[1] not in ('127.0.0.1', '0.0.0.0'): rhost = remote[1] self.open_session(rhost, port, platform, architecture, session_type, remote[0], on_session) return True def module_handle_session(self, payload_type='one_side', session=None, timeout=None): module = self.modules.get_current_module_object() options = module.handler session = session if session is not None else HatSploitSession if payload_type == 'reverse_tcp': new_session, host = self.server_handle.listen_session( options['LHOST'], options['LPORT'], session, timeout ) if not new_session and not host: return None elif payload_type == 'bind_tcp': host = options['RBHOST'] new_session = self.server_handle.connect_session( options['RBHOST'], options['RBPORT'], session, timeout ) if not new_session: return None else: return None return new_session, host def handle_session(self, host=None, port=None, payload_type='one_side', session=None, timeout=None): session = session if session is not None else HatSploitSession if payload_type == 'reverse_tcp': if not host or not port: return None new_session, host = self.server_handle.listen_session(host, port, session, timeout) if not new_session and not host: return None elif payload_type == 'bind_tcp': if not host or not port: return None new_session = self.server_handle.connect_session(host, port, session, timeout) if not new_session: return None elif payload_type == 'one_side': return None else: self.badges.print_error("Invalid payload type!") return None return new_session, host def send_payload(self, payload=None, sender=None, payload_category='stager', payload_type='one_side', args={}, concat=None, location=None, background=None, method=None, linemax=100, platform='generic', ensure=False, arguments=None): if payload is None: self.badges.print_error("Payload stage is not found!") return False if sender is None: self.badges.print_error("No sender found!") return False if ensure: linemax = self.ensure_linemax(payload['Payload'], linemax) if payload_category == 'stager': self.badges.print_process(f"Sending payload stage ({str(len(payload))} bytes)...") if method != 'raw': self.do_job( payload_type, self.post.post, [ platform, sender, payload, args, arguments, method, location, concat, background, linemax ] ) return True if payload_category == 'singler' or method == 'raw': self.do_job( payload_type, self.send, [ sender, payload, args ] ) else: self.badges.print_error("Invalid payload category!") return False return True
class Loot(StringTools, FSTools): badges = Badges() loot = Config().path_config['loot_path'] data = Config().path_config['data_path'] def create_loot(self): if not os.path.isdir(self.loot): os.mkdir(self.loot) def specific_loot(self, filename): return self.loot + filename def random_loot(self, extension=None): filename = self.random_string(16) if extension: filename += '.' + extension return self.loot + filename def get_file(self, filename): if self.exists_file(filename): with open(filename, 'rb') as f: return f.read() return None def save_file(self, location, data, extension=None, filename=None): exists, is_dir = self.exists(location) if exists: if is_dir: if location.endswith('/'): location += os.path.split( filename)[1] if filename else self.random_string(16) else: location += '/' + os.path.split( filename)[1] if filename else self.random_string(16) if extension: if not location.endswith('.' + extension): location += '.' + extension with open(location, 'wb') as f: f.write(data) self.badges.print_success(f"Saved to {location}!") return os.path.abspath(location) return None def remove_file(self, filename): if self.exists_file(filename): os.remove(filename) self.badges.print_success(f"Removed {filename}!") return True return False def get_loot(self, filename): filename = os.path.split(filename)[1] return self.get_file(self.loot + filename) def save_loot(self, filename, data): filename = os.path.split(filename)[1] return self.save_file(self.loot + filename, data) def remove_loot(self, filename): filename = os.path.split(filename)[1] return self.remove_file(self.loot + filename) def get_data(self, filename): if os.path.exists(self.data + filename): with open(self.data + filename, 'rb') as f: return f.read() else: self.badges.print_error("Invalid data given!") def list_loot(self): loots = [] for loot in os.listdir(self.loot): loots.append( (loot, self.loot + loot, datetime.datetime.fromtimestamp( os.path.getmtime(self.loot + loot)).astimezone().strftime( "%Y-%m-%d %H:%M:%S %Z"))) return loots
class Builder: modules = Modules() payloads = Payloads() badges = Badges() config = Config() importer = Importer() local_storage = LocalStorage() def check_base_built(self): if (os.path.exists(self.config.path_config['db_path'] + self.config.db_config['base_dbs']['module_database']) and os.path.exists(self.config.path_config['db_path'] + self.config.db_config['base_dbs']['payload_database']) and os.path.exists(self.config.path_config['db_path'] + self.config.db_config['base_dbs']['plugin_database'])): return True return False def build_base(self): if not self.check_base_built(): if not os.path.exists(self.config.path_config['db_path']): os.mkdir(self.config.path_config['db_path']) self.build_module_database(self.config.path_config['modules_path'], (self.config.path_config['db_path'] + self.config.db_config['base_dbs']['module_database'])) self.build_payload_database(self.config.path_config['payloads_path'], (self.config.path_config['db_path'] + self.config.db_config['base_dbs']['payload_database'])) self.build_plugin_database(self.config.path_config['plugins_path'], (self.config.path_config['db_path'] + self.config.db_config['base_dbs']['plugin_database'])) def build_payload_database(self, input_path, output_path): database_path = output_path database = { "__database__": { "type": "payloads" } } payloads_path = os.path.normpath(input_path) for dest, _, files in os.walk(payloads_path): for file in files: if file.endswith('.py') and file != '__init__.py': payload = dest + '/' + file[:-3] try: payload_object = self.importer.import_payload(payload) payload_name = payload_object.details['Payload'] database.update({ payload_name: { "Path": payload, "Category": payload_object.details['Category'], "Name": payload_object.details['Name'], "Payload": payload_object.details['Payload'], "Authors": payload_object.details['Authors'], "Description": payload_object.details['Description'], "Architecture": payload_object.details['Architecture'], "Platform": payload_object.details['Platform'], "Rank": payload_object.details['Rank'], "Type": payload_object.details['Type'] } }) except Exception: self.badges.print_error(f"Failed to add {payload} to payload database!") with open(database_path, 'w') as f: json.dump(database, f) def build_module_database(self, input_path, output_path): database_path = output_path database = { "__database__": { "type": "modules" } } modules_path = os.path.normpath(input_path) for dest, _, files in os.walk(modules_path): for file in files: if file.endswith('.py') and file != '__init__.py': module = dest + '/' + file[:-3] try: module_object = self.importer.import_module(module) module_name = module_object.details['Module'] database.update({ module_name: { "Path": module, "Category": module_object.details['Category'], "Name": module_object.details['Name'], "Module": module_object.details['Module'], "Authors": module_object.details['Authors'], "Description": module_object.details['Description'], "Platform": module_object.details['Platform'], "Rank": module_object.details['Rank'] } }) except Exception: self.badges.print_error(f"Failed to add {module} to module database!") with open(database_path, 'w') as f: json.dump(database, f) def build_plugin_database(self, input_path, output_path): database_path = output_path database = { "__database__": { "type": "plugins" } } plugins_path = os.path.normpath(input_path) for dest, _, files in os.walk(plugins_path): for file in files: if file.endswith('.py') and file != '__init__.py': plugin = dest + '/' + file[:-3] try: plugin_object = self.importer.import_plugin(plugin) plugin_name = plugin_object.details['Plugin'] database.update({ plugin_name: { "Path": plugin, "Name": plugin_object.details['Name'], "Plugin": plugin_object.details['Plugin'], "Authors": plugin_object.details['Authors'], "Description": plugin_object.details['Description'] } }) except Exception: self.badges.print_error(f"Failed to add {plugin} to plugin database!") with open(database_path, 'w') as f: json.dump(database, f)
class Handle: badges = Badges() tcp_client = TCPClient() tcp_listener = TCPListener() http_listener = HTTPListener() def listen_server(self, local_host, local_port, methods={}): listener = self.http_listener.listen_http(local_host, local_port, methods) self.badges.print_process( f"Starting HTTP listener on port {str(local_port)}...") if listener.listen(): while True: listener.accept() listener.stop() else: self.badges.print_error( f"Failed to start HTTP listener on port {str(local_port)}!") def listen_session(self, local_host, local_port, session, timeout=None): listener = self.tcp_listener.listen_tcp(local_host, local_port, timeout) self.badges.print_process( f"Starting TCP listener on port {str(local_port)}...") if listener.listen(): if listener.accept(): address = listener.address self.badges.print_process( f"Establishing connection ({address[0]}:{str(address[1])} -> {local_host}:{str(local_port)})..." ) listener.stop() session = session() session.open(listener.client) return session, address[0] self.badges.print_warning("Timeout waiting for connection.") else: self.badges.print_error( f"Failed to start TCP listener on port {str(local_port)}!") self.badges.print_error("Failed to handle session!") return None, None def connect_session(self, remote_host, remote_port, session, timeout=None): client = self.tcp_client.open_tcp(remote_host, remote_port, timeout) self.badges.print_process( f"Connecting to {local_host}:{str(local_port)}...") if client.connect(): self.badges.print_process( f"Establishing connection (0.0.0.0:{str(remote_port)} -> {remote_host}:{str(remote_port)})..." ) session = session() session.open(client.sock) return session self.badges.print_error(f"Failed to connect to {str(remote_host)}!") self.badges.print_error("Failed to handle session!") return None
class Importer: db = DB() badges = Badges() local_storage = LocalStorage() config = Config() exceptions = Exceptions() @staticmethod def import_check(module_name): try: __import__(module_name) except ModuleNotFoundError: return False except Exception: return True return True def import_command(self, command_path): try: if not command_path.endswith('.py'): command_path = command_path + '.py' spec = importlib.util.spec_from_file_location( command_path, command_path) command = importlib.util.module_from_spec(spec) spec.loader.exec_module(command) command = command.HatSploitCommand() except Exception as e: self.badges.print_information('Reason: ' + str(e)) raise self.exceptions.GlobalException return command def import_payload(self, payload_path): try: if not payload_path.endswith('.py'): payload_path = payload_path + '.py' spec = importlib.util.spec_from_file_location( payload_path, payload_path) payload = importlib.util.module_from_spec(spec) spec.loader.exec_module(payload) payload = payload.HatSploitPayload() except Exception as e: self.badges.print_information('Reason: ' + str(e)) raise self.exceptions.GlobalException return payload def import_module(self, module_path): try: if not module_path.endswith('.py'): module_path = module_path + '.py' spec = importlib.util.spec_from_file_location( module_path, module_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) module = module.HatSploitModule() except Exception as e: self.badges.print_information('Reason: ' + str(e)) raise self.exceptions.GlobalException return module def import_plugin(self, plugin_path): try: if not plugin_path.endswith('.py'): plugin_path = plugin_path + '.py' spec = importlib.util.spec_from_file_location( plugin_path, plugin_path) plugin = importlib.util.module_from_spec(spec) spec.loader.exec_module(plugin) plugin = plugin.HatSploitPlugin() except Exception as e: self.badges.print_information('Reason: ' + str(e)) raise self.exceptions.GlobalException return plugin def import_main_commands(self): commands = self.import_commands( self.config.path_config['commands_path']) self.local_storage.set("commands", commands) def import_commands(self, path): if not path.endswith('/'): path += '/' commands = {} command_path = os.path.split(path)[0] try: for file in os.listdir(command_path): if file.endswith('py'): try: command_object = self.import_command(command_path + '/' + file[:-3]) command_name = command_object.details['Name'] commands[command_name] = command_object except Exception: self.badges.print_error( f"Failed to load {file[:-3]} command!") except Exception: pass return commands def import_database(self): self.db.connect_module_database( self.config.db_config['base_dbs']['module_database_name'], self.config.path_config['db_path'] + self.config.db_config['base_dbs']['module_database']) self.db.connect_payload_database( self.config.db_config['base_dbs']['payload_database_name'], self.config.path_config['db_path'] + self.config.db_config['base_dbs']['payload_database']) self.db.connect_plugin_database( self.config.db_config['base_dbs']['plugin_database_name'], self.config.path_config['db_path'] + self.config.db_config['base_dbs']['plugin_database']) def import_all(self, import_database): self.import_main_commands() if import_database: self.import_database()
class Plugins: badges = Badges() importer = Importer() local_storage = LocalStorage() def get_plugins(self): return self.local_storage.get("plugins") def get_loaded_plugins(self): return self.local_storage.get("loaded_plugins") def plugins_completer(self, text): plugins = self.get_plugins() matches = [] if plugins: for database in plugins: for plugin in plugins[database]: if plugin.startswith(text): matches.append(plugin) return matches def loaded_plugins_completer(self, text): plugins = self.get_loaded_plugins() if plugins: return [plugin for plugin in plugins if plugin.startswith(text)] return [] def check_exist(self, name): all_plugins = self.get_plugins() if all_plugins: for database in all_plugins: plugins = all_plugins[database] if name in plugins: return True return False def check_loaded(self, name): loaded_plugins = self.get_loaded_plugins() if loaded_plugins: if name in loaded_plugins: return True return False def get_database(self, name): all_plugins = self.get_plugins() if all_plugins: for database in all_plugins: plugins = all_plugins[database] if name in plugins: return database return None def import_plugin(self, database, plugin): loaded_plugins = {} plugins = self.get_plugins()[database][plugin] try: loaded_plugins[plugin] = self.importer.import_plugin( plugins['Path']) except Exception: return None return loaded_plugins def add_plugin(self, database, plugin): plugins = self.get_plugins()[database][plugin] plugin_object = self.import_plugin(database, plugin) if plugin_object: if self.get_loaded_plugins(): self.local_storage.update("loaded_plugins", plugin_object) else: self.local_storage.set("loaded_plugins", plugin_object) self.get_loaded_plugins()[plugin].run() self.badges.print_success(f"Successfully loaded {plugin} plugin!") else: self.badges.print_error("Failed to load plugin!") def load_plugin(self, plugin): plugins_shorts = self.local_storage.get("plugin_shorts") if plugins_shorts: if plugin.isdigit(): plugin_number = int(plugin) if plugin_number in plugins_shorts: plugin = plugins_shorts[plugin_number] self.badges.print_process(f"Loading {plugin} plugin...") if not self.check_loaded(plugin): if self.check_exist(plugin): database = self.get_database(plugin) self.add_plugin(database, plugin) else: self.badges.print_error("Invalid plugin!") else: self.badges.print_error("Already loaded!") def unload_plugin(self, plugin): plugins_shorts = self.local_storage.get("plugin_shorts") if plugins_shorts: if plugin.isdigit(): plugin_number = int(plugin) if plugin_number in plugins_shorts: plugin = plugins_shorts[plugin_number] self.badges.print_process(f"Unloading {plugin} plugin...") if self.check_loaded(plugin): self.local_storage.delete_element("loaded_plugins", plugin) self.badges.print_success( f"Successfully unloaded {plugin} plugin!") else: self.badges.print_error("Plugin not loaded!")
class DB: badges = Badges() config = Config() local_storage = LocalStorage() def disconnect_payload_database(self, name): if self.local_storage.get("connected_payload_databases"): if name in self.local_storage.get("connected_payload_databases"): self.local_storage.delete_element( "connected_payload_databases", name) self.local_storage.delete_element("payloads", name) return self.badges.print_error("No such payload database connected!") def disconnect_module_database(self, name): if self.local_storage.get("connected_module_databases"): if name in self.local_storage.get("connected_module_databases"): self.local_storage.delete_element("connected_module_databases", name) self.local_storage.delete_element("modules", name) return self.badges.print_error("No such module database connected!") def disconnect_plugin_database(self, name): if self.local_storage.get("connected_plugin_databases"): if name in self.local_storage.get("connected_plugin_databases"): self.local_storage.delete_element("connected_plugin_databases", name) self.local_storage.delete_element("plugins", name) return self.badges.print_error("No such plugin database connected!") def connect_payload_database(self, name, path): if self.local_storage.get("connected_payload_databases"): if name in self.local_storage.get("connected_payload_databases"): self.badges.print_error("Payload database already connected!") return if not os.path.exists(path) or not str.endswith(path, "json"): self.badges.print_error("Not a payload database!") return try: database = json.load(open(path)) except Exception: self.badges.print_error("Failed to connect payload database!") return if '__database__' not in database: self.badges.print_error("No __database__ section found!") return if database['__database__']['type'] != "payloads": self.badges.print_error("Not a payload database!") return del database['__database__'] payloads = {name: database} data = {name: {'path': path}} if not self.local_storage.get("connected_payload_databases"): self.local_storage.set("connected_payload_databases", {}) self.local_storage.update("connected_payload_databases", data) if self.local_storage.get("payloads"): self.local_storage.update("payloads", payloads) else: self.local_storage.set("payloads", payloads) def connect_module_database(self, name, path): if self.local_storage.get("connected_module_databases"): if name in self.local_storage.get("connected_module_databases"): self.badges.print_error("Module database already connected!") return if not os.path.exists(path) or not str.endswith(path, "json"): self.badges.print_error("Not a module database!") return try: database = json.load(open(path)) except Exception: self.badges.print_error("Failed to connect module database!") return if '__database__' not in database: self.badges.print_error("No __database__ section found!") return if database['__database__']['type'] != "modules": self.badges.print_error("Not a module database!") return del database['__database__'] modules = {name: database} data = {name: {'path': path}} if not self.local_storage.get("connected_module_databases"): self.local_storage.set("connected_module_databases", {}) self.local_storage.update("connected_module_databases", data) if self.local_storage.get("modules"): self.local_storage.update("modules", modules) else: self.local_storage.set("modules", modules) def connect_plugin_database(self, name, path): if self.local_storage.get("connected_plugin_databases"): if name in self.local_storage.get("connected_plugin_databases"): self.badges.print_error("Plugin database already connected!") return if not os.path.exists(path) or not str.endswith(path, "json"): self.badges.print_error("Not a database!") return try: database = json.load(open(path)) except Exception: self.badges.print_error("Failed to connect plugin database!") return if '__database__' not in database: self.badges.print_error("No __database__ section found!") return if database['__database__']['type'] != "plugins": self.badges.print_error("Not a plugin database!") return del database['__database__'] plugins = {name: database} data = {name: {'path': path}} if not self.local_storage.get("connected_plugin_databases"): self.local_storage.set("connected_plugin_databases", {}) self.local_storage.update("connected_plugin_databases", data) if self.local_storage.get("plugins"): self.local_storage.update("plugins", plugins) else: self.local_storage.set("plugins", plugins)
class Console: exceptions = Exceptions() execute = Execute() loader = Loader() fmt = FMT() badges = Badges() completer = Completer() banner = Banner() tip = Tip() loot = Loot() config = Config() jobs = Jobs() options = Options() sessions = Sessions() modules = Modules() payloads = Payloads() local_storage = LocalStorage() history = config.path_config['history_path'] prompt = config.core_config['details']['prompt'] handler_options = { 'Module': {}, 'Payload': {} } completion = None def check_install(self): if os.path.exists(self.config.path_config['root_path']): workspace = self.config.path_config['user_path'] loot = self.config.path_config['loot_path'] if not os.path.isdir(workspace): self.badges.print_process(f"Creating workspace at {workspace}...") os.mkdir(workspace) if not os.path.isdir(loot): self.loot.create_loot() return True self.badges.print_error("HatSploit is not installed!") self.badges.print_information("Consider running installation.") return False def start_hsf(self): try: self.loader.load_all() except Exception: sys.exit(1) def update_events(self): current_module = self.modules.get_current_module_object() current_payload = self.payloads.get_current_payload() self.jobs.stop_dead() self.sessions.close_dead() self.options.add_handler_options(current_module, current_payload) def launch_menu(self): while True: try: if not self.modules.check_current_module(): prompt = f'({self.prompt})> ' else: current_module = self.modules.get_current_module_object() category = current_module.details['Category'] name = current_module.details['Name'] prompt = f'({self.prompt}: {category}: %red{name}%end)> ' commands = self.badges.input_empty(prompt) self.update_events() self.execute.execute_command(commands) self.update_events() if self.local_storage.get("history"): readline.write_history_file(self.history) except (KeyboardInterrupt, EOFError, self.exceptions.GlobalException): pass except Exception as e: self.badges.print_error(f"An error occurred: {str(e)}!") def enable_history_file(self): if not os.path.exists(self.history): open(self.history, 'w').close() readline.read_history_file(self.history) def launch_history(self): readline.set_auto_history(False) using_history = self.local_storage.get("history") if using_history: readline.set_auto_history(True) self.enable_history_file() readline.set_completer(self.completer.completer) readline.set_completer_delims(" \t\n;") readline.parse_and_bind("tab: complete") def launch_shell(self): version = self.config.core_config['details']['version'] codename = self.config.core_config['details']['codename'] if self.config.core_config['console']['clear']: self.badges.print_empty("%clear", end='') if self.config.core_config['console']['banner']: self.banner.print_random_banner() if self.config.core_config['console']['header']: plugins = self.local_storage.get("plugins") modules = self.local_storage.get("modules") payloads = self.local_storage.get("payloads") plugins_total = 0 modules_total = 0 payloads_total = 0 if payloads: for database in payloads: payloads_total += len(payloads[database]) if plugins: for database in plugins: plugins_total += len(plugins[database]) if modules: for database in modules: modules_total += len(modules[database]) header = "" header += "%end" if codename: header += f" --=( %yellowHatSploit Framework {version} {codename}%end\n" else: header += f" --=( %yellowHatSploit Framework {version}%end\n" header += "--==--=( Developed by EntySec (%linehttps://entysec.netlify.app/%end)\n" header += f" --=( {modules_total} modules | {payloads_total} payloads | {plugins_total} plugins" header += "%end" self.badges.print_empty(header) if self.config.core_config['console']['tip']: self.tip.print_random_tip() def shell(self): self.start_hsf() self.launch_history() self.launch_shell() self.launch_menu() def script(self, input_files, do_shell=False): self.start_hsf() self.launch_shell() for input_file in input_files: if os.path.exists(input_file): file = open(input_file, 'r') file_text = file.read().split('\n') file.close() for line in file_text: commands = self.fmt.format_commands(line) self.add_handler_options() self.jobs.stop_dead() self.execute.execute_command(commands) if do_shell: self.launch_history() self.launch_menu()
class Show: jobs = Jobs() loot = Loot() local_storage = LocalStorage() modules = Modules() payloads = Payloads() sessions = Sessions() colors = Colors() badges = Badges() tables = Tables() def show_custom_commands(self, handler): commands_data = {} headers = ("Command", "Description") commands = handler for command in sorted(commands): label = commands[command].details['Category'] commands_data[label] = [] for command in sorted(commands): label = commands[command].details['Category'] commands_data[label].append( (command, commands[command].details['Description'])) for label in sorted(commands_data): self.tables.print_table(label.title() + " Commands", headers, *commands_data[label]) def show_interface_commands(self): if self.local_storage.get("commands"): self.show_custom_commands(self.local_storage.get("commands")) else: self.badges.print_warning("No commands available.") def show_plugin_commands(self): for plugin in self.local_storage.get("loaded_plugins"): loaded_plugin = self.local_storage.get("loaded_plugins")[plugin] if hasattr(loaded_plugin, "commands"): commands_data = {} headers = ("Command", "Description") commands = loaded_plugin.commands for label in sorted(commands): commands_data[label] = [] for command in sorted(commands[label]): commands_data[label].append( (command, commands[label][command]['Description'])) for label in sorted(commands_data): self.tables.print_table(label.title() + " Commands", headers, *commands_data[label]) def show_module_commands(self): current_module = self.modules.get_current_module_object() if hasattr(current_module, "commands"): commands_data = [] headers = ("Command", "Description") commands = current_module.commands for command in sorted(commands): commands_data.append( (command, commands[command]['Description'])) self.tables.print_table("Module Commands", headers, *commands_data) def show_all_commands(self): self.show_interface_commands() if self.modules.check_current_module(): self.show_module_commands() if self.local_storage.get("loaded_plugins"): self.show_plugin_commands() def show_jobs(self): if self.local_storage.get("jobs"): jobs_data = [] headers = ("ID", "Name", "Module") jobs = self.local_storage.get("jobs") for job_id in jobs: jobs_data.append((job_id, jobs[job_id]['job_name'], jobs[job_id]['module_name'])) self.tables.print_table("Active Jobs", headers, *jobs_data) else: self.badges.print_warning("No running jobs available.") def show_loot(self): loots = self.loot.list_loot() if loots: headers = ("Loot", "Path", "Time") self.tables.print_table("Collected Loot", headers, *loots) else: self.badges.print_warning("No loot collected yet.") def show_module_databases(self): if self.local_storage.get("connected_module_databases"): databases_data = [] number = 0 headers = ("Number", "Name", "Path") databases = self.local_storage.get("connected_module_databases") for name in databases: databases_data.append((number, name, databases[name]['path'])) number += 1 self.tables.print_table("Connected Module Databases", headers, *databases_data) else: self.badges.print_warning("No module database connected.") def show_payload_databases(self): if self.local_storage.get("connected_payload_databases"): databases_data = [] number = 0 headers = ("Number", "Name", "Path") databases = self.local_storage.get("connected_payload_databases") for name in databases: databases_data.append((number, name, databases[name]['path'])) number += 1 self.tables.print_table("Connected Payload Databases", headers, *databases_data) else: self.badges.print_warning("No payload database connected.") def show_plugin_databases(self): if self.local_storage.get("connected_plugin_databases"): databases_data = [] number = 0 headers = ("Number", "Name", "Path") databases = self.local_storage.get("connected_plugin_databases") for name in databases: databases_data.append((number, name, databases[name]['path'])) number += 1 self.tables.print_table("Connected Plugin Databases", headers, *databases_data) else: self.badges.print_warning("No plugin database connected.") def show_plugins(self): all_plugins = self.local_storage.get("plugins") headers = ("Number", "Plugin", "Name") plugins_shorts = {} for database in sorted(all_plugins): number = 0 plugins_data = [] plugins = all_plugins[database] for plugin in sorted(plugins): plugins_data.append((number, plugins[plugin]['Plugin'], plugins[plugin]['Name'])) plugins_shorts.update({number: plugins[plugin]['Plugin']}) number += 1 self.tables.print_table(f"Plugins ({database})", headers, *plugins_data) self.local_storage.set("plugin_shorts", plugins_shorts) def show_modules(self, category=None): all_modules = self.local_storage.get("modules") headers = ("Number", "Category", "Module", "Rank", "Name") modules_shorts = {} for database in sorted(all_modules): number = 0 modules_data = [] modules = all_modules[database] for module in sorted(modules): if category: if category == modules[module]['Category']: modules_data.append( (number, modules[module]['Category'], modules[module]['Module'], modules[module]['Rank'], modules[module]['Name'])) modules_shorts.update( {number: modules[module]['Module']}) number += 1 else: modules_data.append( (number, modules[module]['Category'], modules[module]['Module'], modules[module]['Rank'], modules[module]['Name'])) modules_shorts.update({number: modules[module]['Module']}) number += 1 if category: self.tables.print_table( f"{category.title()} Modules ({database})", headers, *modules_data) else: self.tables.print_table(f"Modules ({database})", headers, *modules_data) self.local_storage.set("module_shorts", modules_shorts) def show_payloads(self, category=None): all_payloads = self.local_storage.get("payloads") headers = ("Number", "Category", "Payload", "Rank", "Name") payloads_shorts = {} for database in sorted(all_payloads): number = 0 payloads_data = [] payloads = all_payloads[database] for payload in sorted(payloads): if category: if category == payloads[payload]['Category']: payloads_data.append( (number, payloads[payload]['Category'], payloads[payload]['Payload'], payloads[payload]['Rank'], payloads[payload]['Name'])) payloads_shorts.update( {number: payloads[payload]['Payload']}) number += 1 else: payloads_data.append( (number, payloads[payload]['Category'], payloads[payload]['Payload'], payloads[payload]['Rank'], payloads[payload]['Name'])) payloads_shorts.update( {number: payloads[payload]['Payload']}) number += 1 if category: self.tables.print_table( f"{category.title()} Payloads ({database})", headers, *payloads_data) else: self.tables.print_table(f"Payloads ({database})", headers, *payloads_data) self.local_storage.set("payload_shorts", payloads_shorts) def show_search_plugins(self, keyword): all_plugins = self.local_storage.get("plugins") plugins_shorts = {} if all_plugins: headers = ("Number", "Plugin", "Name") for database in all_plugins: number = 0 plugins_data = [] plugins = all_plugins[database] for plugin in sorted(plugins): if keyword in plugins[plugin][ 'Plugin'] or keyword in plugins[plugin]['Name']: name = plugins[plugin]['Plugin'].replace( keyword, self.colors.RED + keyword + self.colors.END) description = plugins[plugin]['Name'].replace( keyword, self.colors.RED + keyword + self.colors.END) plugins_data.append((number, name, description)) plugins_shorts.update( {number: plugins[plugin]['Plugin']}) number += 1 if plugins_data: self.tables.print_table(f"Plugins ({database})", headers, *plugins_data) self.local_storage.set("plugin_shorts", plugins_shorts) def show_search_modules(self, keyword): all_modules = self.local_storage.get("modules") modules_shorts = {} if all_modules: headers = ("Number", "Module", "Rank", "Name") for database in all_modules: number = 0 modules_data = [] modules = all_modules[database] for module in sorted(modules): if keyword in modules[module][ 'Module'] or keyword in modules[module]['Name']: name = modules[module]['Module'].replace( keyword, self.colors.RED + keyword + self.colors.END) description = modules[module]['Name'].replace( keyword, self.colors.RED + keyword + self.colors.END) modules_data.append( (number, name, modules[module]['Rank'], description)) modules_shorts.update( {number: modules[module]['Module']}) number += 1 if modules_data: self.tables.print_table(f"Modules ({database})", headers, *modules_data) self.local_storage.set("module_shorts", modules_shorts) def show_search_payloads(self, keyword): all_payloads = self.local_storage.get("payloads") payloads_shorts = {} if all_payloads: headers = ("Number", "Category", "Payload", "Rank", "Name") for database in all_payloads: number = 0 payloads_data = [] payloads = all_payloads[database] for payload in sorted(payloads): if keyword in payloads[payload][ 'Payload'] or keyword in payloads[payload]['Name']: name = payloads[payload]['Payload'].replace( keyword, self.colors.RED + keyword + self.colors.END) description = payloads[payload]['Name'].replace( keyword, self.colors.RED + keyword + self.colors.END) payloads_data.append( (number, payloads[payload]['Category'], name, payloads[payload]['Rank'], description)) payloads_shorts.update( {number: payloads[payload]['Payload']}) number += 1 if payloads_data: self.tables.print_table(f"Payloads ({database})", headers, *payloads_data) self.local_storage.set("payload_shorts", payloads_shorts) def show_sessions(self): sessions = self.local_storage.get("sessions") if sessions: sessions_data = [] headers = ("ID", "Platform", "Architecture", "Type", "Host", "Port") for session_id in sessions: session_platform = sessions[session_id]['platform'] session_architecture = sessions[session_id]['architecture'] session_type = sessions[session_id]['type'] host = sessions[session_id]['host'] port = sessions[session_id]['port'] sessions_data.append( (session_id, session_platform, session_architecture, session_type, host, port)) self.tables.print_table("Opened Sessions", headers, *sessions_data) else: self.badges.print_warning("No opened sessions available.") def show_module_information(self, current_module_details): current_module = current_module_details authors = "" for author in current_module['Authors']: authors += author + ", " authors = authors[:-2] self.badges.print_information("Module information:") self.badges.print_empty("") if current_module['Name']: self.badges.print_empty(" Name: " + current_module['Name']) if current_module['Module']: self.badges.print_empty(" Module: " + current_module['Module']) if authors: self.badges.print_empty(" Authors: ") for author in current_module['Authors']: self.badges.print_empty(" " + author) if current_module['Description']: self.badges.print_empty(" Description: " + current_module['Description']) if current_module['Rank']: self.badges.print_empty(" Rank: " + current_module['Rank']) self.badges.print_empty("") def show_options(self): current_module = self.modules.get_current_module_object() if not current_module: self.badges.print_warning("No module selected.") return if not hasattr(current_module, "options") and not hasattr( current_module, "payload"): self.badges.print_warning("Module has no options.") return if not hasattr(current_module, "options") and not hasattr( self.payloads.get_current_payload(), "options"): self.badges.print_warning("Module has no options.") return if hasattr(current_module, "options"): options_data = [] headers = ("Option", "Value", "Required", "Description") options = current_module.options for option in sorted(options): value, required = options[option]['Value'], options[option][ 'Required'] if required: required = "yes" else: required = "no" if not value and value != 0: value = "" options_data.append( (option, value, required, options[option]['Description'])) self.tables.print_table( f"Module Options ({current_module.details['Module']})", headers, *options_data) if hasattr(current_module, "payload"): if hasattr(self.payloads.get_current_payload(), "options"): options_data = [] headers = ("Option", "Value", "Required", "Description") current_payload = self.payloads.get_current_payload() if current_payload: for option in sorted(current_payload.options): value, required = current_payload.options[option]['Value'], \ current_payload.options[option]['Required'] if required: required = "yes" else: required = "no" if not value and value != 0: value = "" options_data.append( (option, value, required, current_payload.options[option]['Description'])) self.tables.print_table( f"Payload Options ({current_payload.details['Payload']})", headers, *options_data)