def keyword_obfuscation(self, keyword: str, replacement: str = None): """ Add key words to to be obfuscated from commands. Empire will generate a random word if no replacement word is provided. CANNOT BE USED WITH OBFUSCATE. Usage: keyword_obfuscation <keyword> [replacement] """ if not replacement: replacement = random.choice(string.ascii_uppercase) + ''.join( random.choice(string.ascii_uppercase + string.digits) for _ in range(4)) print( print_util.color( f'[*] No keyword obfuscation replacement given, generating random string' )) options = { 'keyword_obfuscation': keyword, 'keyword_replacement': replacement } response = state.set_admin_options(options) # Return results and error message if 'success' in response.keys(): print( print_util.color( f'[*] Keyword obfuscation set to replace {keyword} with {replacement}' )) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def execute(self): """ Execute the selected module Usage: execute """ post_body = {} for key, value in self.record_options.items(): post_body[key] = self.record_options[key]['Value'] response = state.execute_module(self.selected, post_body) if 'success' in response.keys(): print( print_util.color('[*] Tasked ' + self.record_options['Agent']['Value'] + ' to run Task ' + str(response['taskID']))) shell_return = threading.Thread(target=self.tasking_id_returns, args=[response['taskID']]) shell_return.daemon = True shell_return.start() elif 'error' in response.keys(): if response['error'].startswith('[!]'): msg = response['error'] else: msg = f"[!] Error: {response['error']}" print(print_util.color(msg))
def init_handlers(self): if self.sio: self.sio.on( "listeners/new", lambda data: [ print( print_util.color("[+] Listener " + data["name"] + " successfully started")), self.get_listeners(), ], ) self.sio.on( "agents/new", lambda data: [ print( print_util.color("[+] New agent " + data["name"] + " checked in")), self.get_agents(), ], ) # Multiple checkin messages or a single one? self.sio.on( "agents/stage2", lambda data: print( print_util.color("[*] Sending agent (stage 2) to " + data[ "name"] + " at " + data["external_ip"])), )
def keyword_obfuscation(self, keyword: str, replacement: str = None): """ Add key words to to be obfuscated from commands. Empire will generate a random word if no replacement word is provided. Usage: keyword_obfuscation <keyword> [replacement] """ if not replacement: replacement = random.choice(string.ascii_uppercase) + "".join( random.choice(string.ascii_uppercase + string.digits) for _ in range(4)) print( print_util.color( f"[*] No keyword obfuscation replacement given, generating random string" )) options = { "keyword_obfuscation": keyword, "keyword_replacement": replacement } response = state.set_admin_options(options) # Return results and error message if "success" in response.keys(): print( print_util.color( f"[*] Keyword obfuscation set to replace {keyword} with {replacement}" )) elif "error" in response.keys(): print(print_util.color("[!] Error: " + response["error"]))
def set(self, key: str, value: str): """ Edit a field for the current record Usage: set <key> <value> """ if not state.listeners[self.selected]["enabled"]: if value.startswith('"') and value.endswith('"'): value = value[1:-1] if key in self.record_options: response = state.edit_listener(self.selected, key, value) if "success" in response.keys(): state.listeners[ self.selected]["options"][key]["Value"] = value print( print_util.color( f"[*] Updated listener {self.selected}: {key} to {value}" )) elif "error" in response.keys(): print(print_util.color("[!] Error: " + response["error"])) else: print(print_util.color(f"Could not find field: {key}")) else: print( print_util.color( f"[!] Listener must be disabled before edits"))
def execute(self): """ Execute the stager Usage: execute """ # todo validation and error handling # Hopefully this will force us to provide more info in api errors ;) post_body = {} for key, value in self.record_options.items(): post_body[key] = self.record_options[key]['Value'] response = state.create_stager(self.selected, post_body) if 'error' in response: print(print_util.color(response['error'])) return elif response[self.selected].get('OutFile', {}).get('Value'): if response[self.selected].get('Output', '') == '': # todo stagers endpoint needs to give modules a way to return errors better. # This says if the output is empty then something must have gone wrong. print(print_util.color('[!] Stager output empty.')) return file_name = response[self.selected].get('OutFile').get('Value').split('/')[-1] output_bytes = base64.b64decode(response[self.selected]['Output']) file = open(f'empire/client/generated-stagers/{file_name}', 'wb') file.write(output_bytes) file.close() print(print_util.color(f'[*] {file_name} written to {os.path.abspath(file.name)}')) else: print(print_util.color(response[self.selected]['Output']))
def history(self, number_tasks: int): """ Display last number of task results received. Usage: history [<number_tasks>] """ if not number_tasks: number_tasks = 5 response = state.get_agent_tasks(self.session_id, str(number_tasks)) if 'agent' in response.keys(): tasks = response['agent'] for task in tasks: if task.get('results'): print( print_util.color( f'[*] Task {task["taskID"]} results received')) for line in task.get('results', '').split('\n'): print(print_util.color(line)) else: print( print_util.color( f'[!] Task {task["taskID"]} No tasking results received' )) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def history(self, number_tasks: int): """ Display last number of task results received. Usage: history [<number_tasks>] """ if not number_tasks: number_tasks = 5 response = state.get_agent_tasks(self.session_id, str(number_tasks)) if "agent" in response.keys(): tasks = response["agent"] for task in tasks: if task.get("results"): print( print_util.color( f'[*] Task {task["taskID"]} results received')) for line in task.get("results", "").split("\n"): print(print_util.color(line)) else: print( print_util.color( f'[!] Task {task["taskID"]} No tasking results received' )) elif "error" in response.keys(): print(print_util.color("[!] Error: " + response["error"]))
def execute(self): """ Execute the selected module Usage: execute """ post_body = {} for key, value in self.record_options.items(): post_body[key] = self.record_options[key]['Value'] response = state.execute_module(self.selected, post_body) if 'success' in response.keys(): if 'Agent' in post_body.keys(): print( print_util.color('[*] Tasked ' + self.record_options['Agent']['Value'] + ' to run Task ' + str(response['taskID']))) menu_state.pop() else: print(print_util.color('[*] ' + str(response['msg']))) elif 'error' in response.keys(): if response['error'].startswith('[!]'): msg = response['error'] else: msg = f"[!] Error: {response['error']}" print(print_util.color(msg))
def execute(self): """ Update selected credential Usage: execute """ if self.selected == 'add': temp = {} for key, val in self.record_options.items(): temp[key] = val['Value'] response = state.add_credential(temp) if 'ID' in response.keys(): print(print_util.color(f'[*] Credential {response["ID"]} successfully added')) state.get_credentials() elif 'error' in response.keys(): if response['error'].startswith('[!]'): msg = response['error'] else: msg = f"[!] Error: {response['error']}" print(print_util.color(msg)) else: temp = {} for key, val in self.record_options.items(): temp[key] = val['Value'] response = state.edit_credential(self.selected, temp) if 'ID' in response.keys(): print(print_util.color(f'[*] Credential {response["ID"]} successfully updated')) state.get_credentials() elif 'error' in response.keys(): if response['error'].startswith('[!]'): msg = response['error'] else: msg = f"[!] Error: {response['error']}" print(print_util.color(msg))
def print_agent_table(data: List[List[str]] = None, formatting: List[List[str]] = None, title: str = ''): if data is None: return # Make header blue for x in range(len(data[0])): data[0][x] = print_utils.color(data[0][x], 'blue') for x in range(len(data))[1:]: # Add asterisk for high-integrity agents if formatting[x][1]: data[x][1] = data[x][1] + '*' # color agents if formatting[x][0]: color = 'red' elif not formatting[x][0]: color = 'green' # Set colors for entire row for y in range(len(data[x])): data[x][y] = print_utils.color(data[x][y], color) table = SingleTable(data) table.title = title table.inner_row_border = True print('') print(table.table) print('')
def set(self, key: str, value: str): """ Edit a field for the current record Usage: set <key> <value> """ if not state.listeners[self.selected]['enabled']: if value.startswith("\"") and value.endswith("\""): value = value[1:-1] if key in self.record_options: response = state.edit_listener(self.selected, key, value) if 'success' in response.keys(): state.listeners[ self.selected]['options'][key]['Value'] = value print( print_util.color( f'[*] Updated listener {self.selected}: {key} to {value}' )) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error'])) else: print(print_util.color(f'Could not find field: {key}')) else: print( print_util.color( f'[!] Listener must be disabled before edits'))
def __init__(self): shortcuts_raw = empire_config.yaml.get('shortcuts', {}) python: Dict[str, Shortcut] = {} powershell: Dict[str, Shortcut] = {} for key, value in shortcuts_raw['python'].items(): try: value['name'] = key python[key] = Shortcut.from_json(json.loads(json.dumps(value))) except TypeError as e: print( print_util.color(f'Could not parse shortcut: {key}', color_name='red')) for key, value in shortcuts_raw['powershell'].items(): try: value['name'] = key powershell[key] = Shortcut.from_json( json.loads(json.dumps(value))) except TypeError as e: print( print_util.color(f'Could not parse shortcut: {key}', color_name='red')) self.shortcuts: Dict[str, Dict[str, Shortcut]] = { 'python': python, 'powershell': powershell }
def sleep(self, delay: int, jitter: int) -> None: """ Tasks an the specified agent to update delay (s) and jitter (0.0 - 1.0) Usage: sleep <delay> <jitter> """ response = state.agent_sleep(self.session_id, delay, jitter) print(print_util.color(f'[*] Tasked agent to sleep delay/jitter {delay}/{jitter}')) print(print_util.color('[*] Tasked ' + self.selected + ' to run Task ' + str(response['taskID'])))
def execute(self): """ Execute the selected module Usage: execute """ # Find file then upload to server if "File" in self.record_options: # if a full path upload to server, else use file from download directory if pathlib.Path(self.record_options["File"]["Value"]).is_file(): file_directory = self.record_options["File"]["Value"] filename = file_directory.split("/")[-1] self.record_options["File"]["Value"] = filename data = get_data_from_file(file_directory) response = state.upload_file(filename, data) if "success" in response.keys(): print( print_util.color( "[+] File uploaded to server successfully")) elif "error" in response.keys(): if response["error"].startswith("[!]"): msg = response["error"] else: msg = f"[!] Error: {response['error']}" print(print_util.color(msg)) # Save copy off to downloads folder so last value points to the correct file data = base64.b64decode(data.encode("UTF-8")) with open(f"{state.directory['downloads']}{filename}", "wb+") as f: f.write(data) post_body = {} for key, value in self.record_options.items(): post_body[key] = self.record_options[key]["Value"] response = state.execute_module(self.selected, post_body) if "success" in response.keys(): if "Agent" in post_body.keys(): print( print_util.color("[*] Tasked " + self.record_options["Agent"]["Value"] + " to run Task " + str(response["taskID"]))) menu_state.pop() else: print(print_util.color("[*] " + str(response["msg"]))) elif "error" in response.keys(): if response["error"].startswith("[!]"): msg = response["error"] else: msg = f"[!] Error: {response['error']}" print(print_util.color(msg))
def connect( self, host: str, config: bool = False, port: int = 1337, socketport: int = 5000, username: str = None, password: str = None, ) -> None: """ Connect to empire instance Usage: connect [--config | -c] <host> [--port=<p>] [--socketport=<sp>] [--username=<u>] [--password=<pw>] Options: host The url for the empire server or the name of a server config from config.yaml --config -c When true, host is a server name from config.yaml [default: False] --port=<p> Port number for empire server. [default: 1337] --socketport=<sp> Port number for empire socketio server. [default: 5000] --username=<u> Username for empire. if not provided, will attempt to pull from yaml --password=<pw> Password for empire. if not provided, will attempt to pull from yaml """ if state.connected: return if config is True: # Check for name in yaml server: dict = empire_config.yaml.get("servers").get(host) if not server: print(f"Could not find server in config.yaml for {host}") server["host"] = patch_protocol(server["host"]) response = state.connect( server["host"], server["port"], server["socketport"], server["username"], server["password"], ) else: host = patch_protocol(host) response = state.connect(host, port, socketport, username, password) if hasattr(response, "status_code"): if response.status_code == 200: print(print_util.color("[*] Connected to " + host)) elif response.status_code == 401: print(print_util.color("[!] Invalid username and/or password")) else: # Print error messages that have reason available try: print( print_util.color("[!] Error: " + response.args[0].reason.args[0])) except: print(print_util.color("[!] Error: " + response.args[0]))
def unset(self, key: str): """ Unset a record option. Usage: unset <key> """ if key in self.record_options: self.record_options[key]['Value'] = '' print(print_util.color('[*] Unset %s' % key)) else: print(print_util.color(f'Could not find field: {key}'))
def execute(self) -> None: """ Tasks an the specified agent to update its proxy chain Usage: execute """ if self.proxy_list: response = state.update_agent_proxy(self.session_id, self.proxy_list) print(print_util.color(f"[*] Tasked agent to update proxy chain")) else: print(print_util.color(f"[!] No proxy chain to configure"))
def kill(self) -> None: """ Kill the selected listener Usage: kill """ response = state.kill_listener(self.selected) if 'success' in response.keys(): print(print_util.color('[*] Listener ' + self.selected + ' killed')) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def enable(self) -> None: """ Enable the selected listener Usage: enable """ response = state.enable_listener(self.selected) if 'success' in response.keys(): print( print_util.color('[*] Listener ' + self.selected + ' enabled')) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def init_handlers(self): if self.sio: self.sio.on('listeners/new', lambda data: [print(print_util.color('[+] Listener ' + data['name'] + ' successfully started')), self.get_listeners()]) self.sio.on('agents/new', lambda data: [print(print_util.color('[+] New agent ' + data['name'] + ' checked in')), self.get_agents()]) # Multiple checkin messages or a single one? self.sio.on('agents/stage2', lambda data: print( print_util.color('[*] Sending agent (stage 2) to ' + data['name'] + ' at ' + data['external_ip'])))
def workinghours(self, working_hours: str) -> None: """ Set an agent's working hours (9:00-17:00) Usage: workinghours <working_hours> """ response = state.update_agent_working_hours(self.session_id, working_hours) if 'success' in response.keys(): print(print_util.color('[*] Updated agent ' + self.selected + ' workinghours to ' + working_hours)) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def killdate(self, kill_date: str) -> None: """ Set an agent's killdate (01/01/2020) Usage: killdate <kill_date> """ response = state.update_agent_killdate(self.session_id, kill_date) if 'success' in response.keys(): print(print_util.color('[*] Updated agent ' + self.selected + ' killdate to ' + kill_date)) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def update_comms(self, listener_name: str) -> None: """ Update the listener for an agent. Usage: update_comms <listener_name> """ response = state.update_agent_comms(self.session_id, listener_name) if 'success' in response.keys(): print(print_util.color('[*] Updated agent ' + self.selected + ' listener ' + listener_name)) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def kill(self, listener_name: str) -> None: """ Kill the selected listener Usage: kill <listener_name> """ response = state.kill_listener(listener_name) if 'success' in response.keys(): print(print_util.color('[*] Listener ' + listener_name + ' killed')) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def download(self, file_name: str) -> None: """ Tasks an the specified agent to download a file. Usage: download <file_name> """ response = state.agent_download_file(self.session_id, file_name) if 'success' in response.keys(): print(print_util.color('[*] Tasked ' + self.selected + ' to run Task ' + str(response['taskID']))) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def enable(self, listener_name: str) -> None: """ Enable the selected listener Usage: enable <listener_name> """ response = state.enable_listener(listener_name) if 'success' in response.keys(): print( print_util.color('[*] Listener ' + listener_name + ' enabled')) elif 'error' in response.keys(): print(print_util.color('[!] Error: ' + response['error']))
def enable(self, listener_name: str) -> None: """ Enable the selected listener Usage: enable <listener_name> """ response = state.enable_listener(listener_name) if "success" in response.keys(): print( print_util.color("[*] Listener " + listener_name + " enabled")) elif "error" in response.keys(): print(print_util.color("[!] Error: " + response["error"]))
def kill(self, listener_name: str) -> None: """ Kill the selected listener Usage: kill <listener_name> """ response = state.kill_listener(listener_name) if "success" in response.keys(): print(print_util.color("[*] Listener " + listener_name + " killed")) elif "error" in response.keys(): print(print_util.color("[!] Error: " + response["error"]))
def kill(self) -> None: """ Kill the selected listener Usage: kill """ response = state.kill_listener(self.selected) if "success" in response.keys(): print(print_util.color("[*] Listener " + self.selected + " killed")) elif "error" in response.keys(): print(print_util.color("[!] Error: " + response["error"]))