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 IO: local_storage = LocalStorage() fmt = FMT() colors_script = ColorsScript() def print(self, message='', start='%remove', end='%newline'): line = self.colors_script.parse(start + message + end) use_log = self.local_storage.get("log") sys.stdout.write(line) sys.stdout.flush() if use_log: with open(use_log, 'a') as f: f.write(line) f.flush() if self.local_storage.get("prompt"): prompt = self.local_storage.get( "prompt") + readline.get_line_buffer() sys.stdout.write(prompt) sys.stdout.flush() def input(self, message='', start='%remove%end', end='%end'): line = self.colors_script.parse( self.colors_script.libreadline(start + message + end)) use_log = self.local_storage.get("log") self.local_storage.set("prompt", line) if use_log: with open(use_log, 'a') as f: f.write(line) f.flush() commands = input(line) if use_log: with open(use_log, 'a') as f: f.write(commands + '\n') f.flush() commands = self.fmt.format_commands(commands) self.local_storage.set("prompt", None) return commands
class Config: 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") @staticmethod def get_config_file(content): return yaml.safe_load(content) def configure(self): db_config = self.get_config_file(open(self.db_config_file)) core_config = self.get_config_file(open(self.core_config_file)) self.db_config = db_config self.core_config = core_config self.local_storage.set("db_config", self.db_config) self.local_storage.set("core_config", self.core_config) self.global_storage = GlobalStorage(self.path_config['storage_path']) self.global_storage.set_all()
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 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 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 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 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 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 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 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 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 HatSploitCommand(Command): config = Config() storage_path = config.path_config['storage_path'] local_storage = LocalStorage() global_storage = GlobalStorage(storage_path) details = { 'Category': "developer", 'Name': "storage", 'Authors': ['Ivan Nikolsky (enty8080) - command developer'], 'Description': "Manage storage variables.", 'Usage': "storage [global|local] <option> [arguments]", 'MinArgs': 2, 'Options': { '-l': ['', "List all storage variables."], '-v': ['<name>', "Show specified storage variable value."], '-s': ['<name> <value>', "Set storage variable value."], '-d': ['<name>', "Delete storage variable."] } } def run(self, argc, argv): type_of_storage = argv[1] if type_of_storage == "global": choice = argv[2] if choice in ['-l', '--list']: self.print_information("Global storage variables:") for variable in self.global_storage.get_all(): if not str.startswith(variable, '__') and not str.endswith( variable, '__'): self.print_empty(" * " + variable) elif choice in ['-v', '--value']: if argv[3] in self.global_storage.get_all(): self.print_information( argv[3] + " = " + str(self.global_storage.get(argv[3]))) elif choice in ['-s', '--set']: self.global_storage.set(argv[3], argv[4]) elif choice in ['-d', '--delete']: if argv[3] in self.global_storage.get_all(): self.global_storage.delete(argv[3]) else: self.print_error("Invalid storage variable name!") elif type_of_storage == "local": choice = argv[2] if choice in ['-l', '--list']: self.print_information("Local storage variables:") for variable in self.local_storage.get_all(): if not str.startswith(variable, '__') and not str.endswith( variable, '__'): self.print_empty(" * " + variable) elif choice in ['-v', '--value']: if argv[3] in self.local_storage.get_all(): self.print_information( argv[3] + " = " + str(self.local_storage.get(argv[3]))) else: self.print_error("Invalid storage variable name!") elif choice in ['-s', '--set']: self.local_storage.set(argv[3], argv[4]) elif choice in ['-d', '--delete']: if argv[3] in self.local_storage.get_all(): self.local_storage.delete(argv[3]) else: self.print_error("Invalid storage variable name!")
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 Options: local_storage = LocalStorage() handler_options = { 'Module': { 'BLINDER': { 'Description': 'Use Blinder.', 'Value': 'yes', 'Type': "boolean", 'Required': True }, 'PAYLOAD': { 'Description': 'Payload to use.', 'Value': None, 'Type': "payload", 'Required': False }, 'LHOST': { 'Description': "Local host to listen on.", 'Value': "0.0.0.0", 'Type': "ip", 'Required': True }, 'LPORT': { 'Description': "Local port to listen on.", 'Value': 8888, 'Type': "port", 'Required': True }, 'RBHOST': { 'Description': "Remote bind host to connect.", 'Value': None, 'Type': "ip", 'Required': True }, 'RBPORT': { 'Description': "Remote bind port to connect.", 'Value': 8888, 'Type': "port", 'Required': True } }, 'Payload': { 'RHOST': { 'Description': "Remote host to connect.", 'Value': TCPTools.get_local_host(), 'Type': "ip", 'Required': True }, 'RPORT': { 'Description': "Remote port to connect.", 'Value': 8888, 'Type': "port", 'Required': True }, 'BPORT': { 'Description': "Port to bind to.", 'Value': 8888, 'Type': "port", 'Required': True } } } @staticmethod def remove_options(target, options): for option in list(target): if option.upper() in options: target.pop(option) @staticmethod def check_options(target): if not hasattr(target, "options"): return False if not isinstance(target.options, dict): return False return True def add_handler_options(self, current_module, current_payload): if current_module: if hasattr(current_module, "payload"): blinder_option = 'blinder'.upper() payload_option = 'payload'.upper() handler_options = copy.deepcopy(self.handler_options) saved_handler_options = self.local_storage.get( "handler_options") if not saved_handler_options: saved_handler_options = {'Module': {}, 'Payload': {}} module = current_module.details['Module'] if module not in saved_handler_options['Module']: saved_handler_options['Module'][module] = handler_options[ 'Module'] if not self.check_options(current_module): current_module.options = {} current_module.options.update( saved_handler_options['Module'][module]) current_module.options[payload_option][ 'Value'] = current_module.payload['Value'] if not current_payload: current_module.options[blinder_option]['Value'] = 'yes' current_module.options[blinder_option]['Required'] = True else: current_module.options[blinder_option]['Value'] = 'no' current_module.options[blinder_option]['Required'] = False if 'Blinder' in current_module.payload: if not current_module.payload['Blinder']: current_module.options.pop(blinder_option) if blinder_option in current_module.options and not current_payload: if current_module.options[blinder_option]['Value'].lower( ) in ['yes', 'y']: current_module.payload['Value'] = None current_module.options[payload_option]['Value'] = None current_module.options[payload_option][ 'Required'] = False else: current_module.options[payload_option][ 'Required'] = True else: current_module.options[payload_option]['Required'] = True if 'Handler' in current_module.payload: special = current_module.payload['Handler'] else: special = '' if current_payload: payload = current_module.payload['Value'] if payload not in saved_handler_options['Payload']: saved_handler_options['Payload'][ payload] = handler_options['Payload'] if not self.check_options(current_payload): current_payload.options = {} current_payload.options.update( saved_handler_options['Payload'][payload]) if current_payload.details['Type'] == 'reverse_tcp': if special != 'bind_tcp': self.remove_options(current_module.options, ['RBHOST', 'RBPORT']) self.remove_options(current_payload.options, ['BPORT']) elif current_payload.details['Type'] == 'bind_tcp': if special != 'reverse_tcp': self.remove_options(current_module.options, ['LHOST', 'LPORT']) self.remove_options(current_payload.options, ['RHOST', 'RPORT']) else: if special != 'reverse_tcp': self.remove_options(current_module.options, ['LHOST', 'LPORT']) self.remove_options(current_payload.options, ['RHOST', 'RPORT']) if special != 'bind_tcp': self.remove_options(current_module.options, ['RBHOST', 'RBPORT']) self.remove_options(current_payload.options, ['BPORT']) else: if special != 'reverse_tcp': self.remove_options(current_module.options, ['LHOST', 'LPORT']) if special != 'bind_tcp': self.remove_options(current_module.options, ['RBHOST', 'RBPORT']) for option in current_module.options: if option.upper() in handler_options['Module']: saved_handler_options['Module'][module][option][ 'Value'] = current_module.options[option]['Value'] current_module.handler = {} for option in saved_handler_options['Module'][module]: current_module.handler.update({ option: saved_handler_options['Module'][module][option] ['Value'] }) if current_payload: payload = current_module.payload['Value'] for option in current_payload.options: if option.upper() in handler_options['Payload']: saved_handler_options['Payload'][payload][option][ 'Value'] = current_payload.options[option][ 'Value'] current_payload.handler = {} for option in saved_handler_options['Payload'][payload]: value = saved_handler_options['Payload'][payload][ option]['Value'] current_payload.handler.update({option: value}) current_module.handler.update({option: value}) for option in saved_handler_options['Module'][module]: current_payload.handler.update({ option: saved_handler_options['Module'][module][option] ['Value'] }) self.local_storage.set("handler_options", saved_handler_options) def add_payload_handler(self, current_payload): handler_options = {} current_payload.handler = {} handler_options.update(self.handler_options['Payload']) if current_payload.details['Type'] == 'reverse_tcp': self.remove_options(handler_options, ['BPORT']) elif current_payload.details['Type'] == 'bind_tcp': self.remove_options(handler_options, ['RHOST', 'RPORT']) else: self.remove_options(handler_options, ['RHOST', 'RPORT', 'BPORT']) for option in handler_options: current_payload.handler.update( {option: handler_options[option]['Value']})
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)