diff --git a/empire b/empire index 6206659..79e6759 100755 --- a/empire +++ b/empire @@ -1248,6 +1248,7 @@ if __name__ == '__main__': generalGroup = parser.add_argument_group('General Options') generalGroup.add_argument('--debug', nargs='?', const='1', help='Debug level for output (default of 1, 2 for msg display).') generalGroup.add_argument('-v', '--version', action='store_true', help='Display current Empire version.') + generalGroup.add_argument('-r','--resource', nargs=1, help='Run the Empire commands in the specified resource file after startup.') cliGroup = parser.add_argument_group('CLI Payload Options') cliGroup.add_argument('-l', '--listener', nargs='?', const="list", help='Display listener options. Displays all listeners if nothing is specified.') diff --git a/lib/common/agents.py b/lib/common/agents.py index 6b60b19..f318015 100644 --- a/lib/common/agents.py +++ b/lib/common/agents.py @@ -1343,6 +1343,20 @@ class Agents: if autorun and autorun[0] != '' and autorun[1] != '': self.add_agent_task_db(sessionID, autorun[0], autorun[1]) + if self.mainMenu.autoRuns.has_key(language.lower()) and len(self.mainMenu.autoRuns[language.lower()]) > 0: + autorunCmds = ["interact %s" % sessionID] + autorunCmds.extend(self.mainMenu.autoRuns[language.lower()]) + autorunCmds.extend(["lastautoruncmd"]) + self.mainMenu.resourceQueue.extend(autorunCmds) + try: + #this will cause the cmdloop() to start processing the autoruns + self.mainMenu.do_agents("kickit") + except Exception as e: + if e.message == "endautorun": + pass + else: + raise e + return "STAGE2: %s" % (sessionID) else: @@ -1399,7 +1413,6 @@ class Agents: TODO: does this need self.lock? """ - if sessionID not in self.agents: dispatcher.send("[!] handle_agent_request(): sessionID %s not present" % (sessionID), sender='Agents') return None @@ -1417,6 +1430,7 @@ class Agents: # build tasking packets for everything we have for tasking in taskings: task_name, task_data, res_id = tasking + all_task_packets += packets.build_task_packet(task_name, task_data, res_id) # get the session key for the agent @@ -1495,6 +1509,7 @@ class Agents: """ agentSessionID = sessionID + keyLogTaskID = None # see if we were passed a name instead of an ID nameid = self.get_agent_id_db(sessionID) @@ -1519,6 +1534,7 @@ class Agents: pk = (pk + 1) % 65536 cur.execute("INSERT INTO results (id, agent, data) VALUES (?,?,?)",(pk, sessionID, data)) else: + keyLogTaskID = cur.execute("SELECT id FROM taskings WHERE agent=? AND data LIKE \"function Get-Keystrokes%\"", [sessionID]).fetchone()[0] cur.execute("UPDATE results SET data=data||? WHERE id=? AND agent=?", [data, taskID, sessionID]) finally: @@ -1703,9 +1719,20 @@ class Agents: elif responseName == "TASK_CMD_JOB": + #check if this is the powershell keylogging task, if so, write output to file instead of screen + if keyLogTaskID and keyLogTaskID == taskID: + safePath = os.path.abspath("%sdownloads/" % self.mainMenu.installPath) + savePath = "%sdownloads/%s/keystrokes.txt" % (self.mainMenu.installPath,sessionID) + if not os.path.abspath(savePath).startswith(safePath): + dispatcher.send("[!] WARNING: agent %s attempted skywalker exploit!" % (self.sessionID), sender='Agents') + return + with open(savePath,"a+") as f: + new_results = data.replace("\r\n","").replace("[SpaceBar]", "").replace('\b', '').replace("[Shift]", "").replace("[Enter]\r","\r\n") + f.write(new_results) + else: + # dynamic script output -> non-blocking + self.update_agent_results_db(sessionID, data) - # dynamic script output -> non-blocking - self.update_agent_results_db(sessionID, data) # update the agent log self.save_agent_log(sessionID, data) diff --git a/lib/common/empire.py b/lib/common/empire.py index 059c82e..9b01345 100644 --- a/lib/common/empire.py +++ b/lib/common/empire.py @@ -93,12 +93,14 @@ class MainMenu(cmd.Cmd): self.stagers = stagers.Stagers(self, args=args) self.modules = modules.Modules(self, args=args) self.listeners = listeners.Listeners(self, args=args) + self.resourceQueue = [] + #A hashtable of autruns based on agent language + self.autoRuns = {} + self.handle_args() dispatcher.send('[*] Empire starting up...', sender="Empire") - - # print the loading menu messages.loading() @@ -137,6 +139,9 @@ class MainMenu(cmd.Cmd): """ Handle any passed arguments. """ + if self.args.resource: + resourceFile = self.args.resource[0] + self.do_resource(resourceFile) if self.args.listener or self.args.stager: # if we're displaying listeners/stagers or generating a stager @@ -230,11 +235,6 @@ class MainMenu(cmd.Cmd): print helpers.color("[!] Please run database_setup.py") sys.exit() - - # def preloop(self): - # traceback.print_stack() - - def cmdloop(self): """ The main cmdloop logic that handles navigation to other menus. @@ -272,6 +272,9 @@ class MainMenu(cmd.Cmd): print " " + helpers.color(str(num_listeners), "green") + " listeners currently active\n" print " " + helpers.color(str(num_agents), "green") + " agents currently active\n\n" + if len(self.resourceQueue) > 0: + self.cmdqueue.append(self.resourceQueue.pop(0)) + cmd.Cmd.cmdloop(self) @@ -378,10 +381,43 @@ class MainMenu(cmd.Cmd): # CMD methods ################################################### + def postcmd(self, stop, line): + if len(self.resourceQueue) > 0: + nextcmd = self.resourceQueue.pop(0) + self.cmdqueue.append(nextcmd) + def default(self, line): "Default handler." pass + def do_resource(self, arg): + "Read and execute a list of Empire commands from a file." + self.resourceQueue.extend(self.buildQueue(arg)) + + def buildQueue(self, resourceFile, autoRun=False): + cmds = [] + if os.path.isfile(resourceFile): + with open(resourceFile, 'r') as f: + lines = [] + lines.extend(f.read().splitlines()) + else: + raise Exception("[!] Error: The resource file specified \"%s\" does not exist" % resourceFile) + for lineFull in lines: + line = lineFull.strip() + #ignore lines that start with the comment symbol (#) + if line.startswith("#"): + continue + #read in another resource file + elif line.startswith("resource "): + rf = line.split(' ')[1] + cmds.extend(self.buildQueue(rf, autoRun)) + #add noprompt option to execute without user confirmation + elif autoRun and line == "execute": + cmds.append(line + " noprompt") + else: + cmds.append(line) + + return cmds def do_exit(self, line): "Exit Empire" @@ -428,7 +464,6 @@ class MainMenu(cmd.Cmd): stager_menu.cmdloop() else: print helpers.color("[!] Error in MainMenu's do_userstager()") - except Exception as e: raise e @@ -704,7 +739,6 @@ class MainMenu(cmd.Cmd): name = line.strip() sessionID = self.agents.get_agent_id_db(name) - if sessionID and sessionID != '' and sessionID in self.agents.agents: AgentMenu(self, sessionID) else: @@ -887,26 +921,59 @@ class MainMenu(cmd.Cmd): mline = line.partition(' ')[2] offs = len(mline) - len(text) return [s[offs:] for s in options if s.startswith(mline)] - -class AgentsMenu(cmd.Cmd): - """ - The main class used by Empire to drive the 'agents' menu. - """ +class SubMenu(cmd.Cmd): + def __init__(self, mainMenu): cmd.Cmd.__init__(self) - self.mainMenu = mainMenu - self.doc_header = 'Commands' + def cmdloop(self): + if len(self.mainMenu.resourceQueue) > 0: + self.cmdqueue.append(self.mainMenu.resourceQueue.pop(0)) + cmd.Cmd.cmdloop(self) - # set the prompt text - self.prompt = '(Empire: ' + helpers.color("agents", color="blue") + ') > ' + def emptyline(self): + pass - messages.display_agents(self.mainMenu.agents.get_agents_db()) - # def preloop(self): - # traceback.print_stack() + def postcmd(self, stop, line): + if line == "back": + return True + if len(self.mainMenu.resourceQueue) > 0: + nextcmd = self.mainMenu.resourceQueue.pop(0) + if nextcmd == "lastautoruncmd": + raise Exception("endautorun") + self.cmdqueue.append(nextcmd) + + + def do_back(self, line): + "Go back a menu." + return True + + def do_listeners(self, line): + "Jump to the listeners menu." + raise NavListeners() + + def do_agents(self, line): + "Jump to the agents menu." + raise NavAgents() + + def do_main(self, line): + "Go back to the main menu." + raise NavMain() + + def do_resource(self, arg): + "Read and execute a list of Empire commands from a file." + self.mainMenu.resourceQueue.extend(self.mainMenu.buildQueue(arg)) + + def do_exit(self, line): + "Exit Empire." + raise KeyboardInterrupt + + def do_creds(self, line): + "Display/return credentials from the database." + self.mainMenu.do_creds(line) # print a nicely formatted help menu # stolen/adapted from recon-ng @@ -919,29 +986,63 @@ class AgentsMenu(cmd.Cmd): self.stdout.write("%s %s\n" % (command.ljust(17), getattr(self, 'do_' + command).__doc__)) self.stdout.write("\n") + # def preloop(self): + # traceback.print_stack() - def emptyline(self): - pass +class AgentsMenu(SubMenu): + """ + The main class used by Empire to drive the 'agents' menu. + """ + def __init__(self, mainMenu): + SubMenu.__init__(self, mainMenu) + self.doc_header = 'Commands' + + # set the prompt text + self.prompt = '(Empire: ' + helpers.color("agents", color="blue") + ') > ' + + messages.display_agents(self.mainMenu.agents.get_agents_db()) def do_back(self, line): "Go back to the main menu." raise NavMain() - - def do_listeners(self, line): - "Jump to the listeners menu." - raise NavListeners() - - - def do_main(self, line): - "Go back to the main menu." - raise NavMain() - - - def do_exit(self, line): - "Exit Empire." - raise KeyboardInterrupt + def do_autorun(self, line): + "Read and execute a list of Empire commands from a file and execute on each new agent \"autorun \" e.g. \"autorun /root/ps.rc powershell\". Or clear any autorun setting with \"autorun clear\" and show current autorun settings with \"autorun show\"" + line = line.strip() + if not line: + print helpers.color("[!] You must specify a resource file, show or clear. e.g. 'autorun /root/res.rc powershell' or 'autorun clear'") + return + cmds = line.split(' ') + resourceFile = cmds[0] + language = None + if len(cmds) > 1: + language = cmds[1].lower() + elif not resourceFile == "show" and not resourceFile == "clear": + print helpers.color("[!] You must specify the agent language to run this module on. e.g. 'autorun /root/res.rc powershell' or 'autorun /root/res.rc python'") + return + #show the current autorun settings by language or all + if resourceFile == "show": + if language: + if self.mainMenu.autoRuns.has_key(language): + print self.mainMenu.autoRuns[language] + else: + print "No autorun commands for language %s" % language + else: + print self.mainMenu.autoRuns + #clear autorun settings by language or all + elif resourceFile == "clear": + if language and not language == "all": + if self.mainMenu.autoRuns.has_key(language): + self.mainMenu.autoRuns.pop(language) + else: + print "No autorun commands for language %s" % language + else: + #clear all autoruns + self.mainMenu.autoRuns.clear() + #read in empire commands from the specified resource file + else: + self.mainMenu.autoRuns[language] = self.mainMenu.buildQueue(resourceFile, True) def do_list(self, line): @@ -954,7 +1055,6 @@ class AgentsMenu(cmd.Cmd): else: self.mainMenu.do_list("agents " + str(line)) - def do_rename(self, line): "Rename a particular agent." @@ -1011,12 +1111,6 @@ class AgentsMenu(cmd.Cmd): except KeyboardInterrupt: print '' - - def do_creds(self, line): - "Display/return credentials from the database." - self.mainMenu.do_creds(line) - - def do_clear(self, line): "Clear one or more agent's taskings." @@ -1410,7 +1504,7 @@ class AgentsMenu(cmd.Cmd): return self.mainMenu.complete_creds(text, line, begidx, endidx) -class AgentMenu(cmd.Cmd): +class AgentMenu(SubMenu): """ An abstracted class used by Empire to determine which agent menu type to instantiate. @@ -1419,25 +1513,24 @@ class AgentMenu(cmd.Cmd): agentLanguage = mainMenu.agents.get_language_db(sessionID) - if agentLanguage.lower() == 'powershell': - agent_menu = PowerShellAgentMenu(mainMenu, sessionID) - agent_menu.cmdloop() - elif agentLanguage.lower() == 'python': - agent_menu = PythonAgentMenu(mainMenu, sessionID) - agent_menu.cmdloop() - else: - print helpers.color("[!] Agent language %s not recognized." % (agentLanguage)) + if agentLanguage.lower() == 'powershell': + agent_menu = PowerShellAgentMenu(mainMenu, sessionID) + agent_menu.cmdloop() + elif agentLanguage.lower() == 'python': + agent_menu = PythonAgentMenu(mainMenu, sessionID) + agent_menu.cmdloop() + else: + print helpers.color("[!] Agent language %s not recognized." % (agentLanguage)) -class PowerShellAgentMenu(cmd.Cmd): +class PowerShellAgentMenu(SubMenu): """ The main class used by Empire to drive an individual 'agent' menu. """ def __init__(self, mainMenu, sessionID): - cmd.Cmd.__init__(self) + SubMenu.__init__(self, mainMenu) - self.mainMenu = mainMenu self.sessionID = sessionID self.doc_header = 'Agent Commands' @@ -1459,7 +1552,6 @@ class PowerShellAgentMenu(cmd.Cmd): # listen for messages from this specific agent dispatcher.connect(self.handle_agent_event, sender=dispatcher.Any) - # def preloop(self): # traceback.print_stack() @@ -1467,49 +1559,22 @@ class PowerShellAgentMenu(cmd.Cmd): """ Handle agent event signals. """ + if '[!] Agent' in signal and 'exiting' in signal: pass name = self.mainMenu.agents.get_agent_name_db(self.sessionID) - if (str(self.sessionID) + " returned results" in signal) or (str(name) + " returned results" in signal): # display any results returned by this agent that are returned - # while we are interacting with it + # while we are interacting with it, unless they are from the powershell keylogger results = self.mainMenu.agents.get_agent_results_db(self.sessionID) - if results: - if sender == "AgentsPsKeyLogger" and ("Job started:" not in results) and ("killed." not in results): - safePath = os.path.abspath("%sdownloads/" % self.mainMenu.installPath) - savePath = "%sdownloads/%s/keystrokes.txt" % (self.mainMenu.installPath,self.sessionID) - if not os.path.abspath(savePath).startswith(safePath): - dispatcher.send("[!] WARNING: agent %s attempted skywalker exploit!" % (self.sessionID), sender='Agents') - return - with open(savePath,"a+") as f: - new_results = results.replace("\r\n","").replace("[SpaceBar]", "").replace('\b', '').replace("[Shift]", "").replace("[Enter]\r","\r\n") - f.write(new_results) - else: - print "\n" + results + if results and not sender == "AgentsPsKeyLogger": + print "\n" + results elif "[+] Part of file" in signal and "saved" in signal: if (str(self.sessionID) in signal) or (str(name) in signal): print helpers.color(signal) - - # print a nicely formatted help menu - # stolen/adapted from recon-ng - def print_topics(self, header, commands, cmdlen, maxcol): - if commands: - self.stdout.write("%s\n" % str(header)) - if self.ruler: - self.stdout.write("%s\n" % str(self.ruler * len(header))) - for command in commands: - self.stdout.write("%s %s\n" % (command.ljust(17), getattr(self, 'do_' + command).__doc__)) - self.stdout.write("\n") - - - def emptyline(self): - pass - - def default(self, line): "Default handler" @@ -1529,27 +1594,6 @@ class PowerShellAgentMenu(cmd.Cmd): print helpers.color("[!] Command not recognized.") print helpers.color("[*] Use 'help' or 'help agentcmds' to see available commands.") - - def do_back(self, line): - "Go back a menu." - return True - - - def do_agents(self, line): - "Jump to the Agents menu." - raise NavAgents() - - - def do_listeners(self, line): - "Jump to the listeners menu." - raise NavListeners() - - - def do_main(self, line): - "Go back to the main menu." - raise NavMain() - - def do_help(self, *args): "Displays the help menu or syntax for particular commands." @@ -1557,8 +1601,7 @@ class PowerShellAgentMenu(cmd.Cmd): print "\n" + helpers.color("[*] Available opsec-safe agent commands:\n") print " " + messages.wrap_columns(", ".join(self.agentCommands), ' ', width1=50, width2=10, indent=5) + "\n" else: - cmd.Cmd.do_help(self, *args) - + SubMenu.do_help(self, *args) def do_list(self, line): "Lists all active agents (or listeners)." @@ -1570,7 +1613,6 @@ class PowerShellAgentMenu(cmd.Cmd): else: print helpers.color("[!] Please use 'list [agents/listeners] '.") - def do_rename(self, line): "Rename the agent." @@ -1586,7 +1628,6 @@ class PowerShellAgentMenu(cmd.Cmd): else: print helpers.color("[!] Please enter a new name for the agent") - def do_info(self, line): "Display information about this agent" @@ -1594,7 +1635,6 @@ class PowerShellAgentMenu(cmd.Cmd): agent = self.mainMenu.agents.get_agent_db(self.sessionID) messages.display_agent(agent) - def do_exit(self, line): "Task agent to exit." @@ -1707,7 +1747,6 @@ class PowerShellAgentMenu(cmd.Cmd): self.mainMenu.agents.add_agent_task_db(self.sessionID, "TASK_SHELL", command) - # update the agent log msg = "Tasked agent to kill process: " + str(process) self.mainMenu.agents.save_agent_log(self.sessionID, msg) @@ -2258,13 +2297,11 @@ class PowerShellAgentMenu(cmd.Cmd): return self.mainMenu.complete_creds(text, line, begidx, endidx) -class PythonAgentMenu(cmd.Cmd): +class PythonAgentMenu(SubMenu): def __init__(self, mainMenu, sessionID): - cmd.Cmd.__init__(self) - - self.mainMenu = mainMenu + SubMenu.__init__(self, mainMenu) self.sessionID = sessionID @@ -2285,9 +2322,6 @@ class PythonAgentMenu(cmd.Cmd): if results: print "\n" + results.rstrip('\r\n') - # def preloop(self): - # traceback.print_stack() - def handle_agent_event(self, signal, sender): """ Handle agent event signals. @@ -2307,51 +2341,13 @@ class PythonAgentMenu(cmd.Cmd): if (str(self.sessionID) in signal) or (str(name) in signal): print helpers.color(signal) - - # print a nicely formatted help menu - # stolen/adapted from recon-ng - def print_topics(self, header, cmds, cmdlen, maxcol): - if cmds: - self.stdout.write("%s\n" % str(header)) - if self.ruler: - self.stdout.write("%s\n" % str(self.ruler * len(header))) - for c in cmds: - self.stdout.write("%s %s\n" % (c.ljust(17), getattr(self, 'do_' + c).__doc__)) - self.stdout.write("\n") - - - def emptyline(self): - pass - - def default(self, line): "Default handler" print helpers.color("[!] Command not recognized, use 'help' to see available commands") - - def do_back(self, line): - "Go back a menu." - return True - - - def do_agents(self, line): - "Jump to the Agents menu." - raise NavAgents() - - - def do_listeners(self, line): - "Jump to the listeners menu." - raise NavListeners() - - - def do_main(self, line): - "Go back to the main menu." - raise NavMain() - - def do_help(self, *args): "Displays the help menu or syntax for particular commands." - cmd.Cmd.do_help(self, *args) + SubMenu.do_help(self, *args) def do_list(self, line): @@ -2677,6 +2673,7 @@ class PythonAgentMenu(cmd.Cmd): # Strip asterisks added by MainMenu.complete_usemodule() module = "python/%s" %(line.strip().rstrip("*")) + if module not in self.mainMenu.modules.modules: print helpers.color("[!] Error: invalid module") else: @@ -2801,14 +2798,12 @@ class PythonAgentMenu(cmd.Cmd): # return helpers.complete_path(text,line) -class ListenersMenu(cmd.Cmd): +class ListenersMenu(SubMenu): """ The main class used by Empire to drive the 'listener' menu. """ def __init__(self, mainMenu): - cmd.Cmd.__init__(self) - - self.mainMenu = mainMenu + SubMenu.__init__(self, mainMenu) self.doc_header = 'Listener Commands' @@ -2818,45 +2813,10 @@ class ListenersMenu(cmd.Cmd): # display all active listeners on menu startup messages.display_active_listeners(self.mainMenu.listeners.activeListeners) - # def preloop(self): - # traceback.print_stack() - - # print a nicely formatted help menu - # stolen/adapted from recon-ng - def print_topics(self, header, commands, cmdlen, maxcol): - if commands: - self.stdout.write("%s\n" % str(header)) - if self.ruler: - self.stdout.write("%s\n" % str(self.ruler * len(header))) - for command in commands: - self.stdout.write("%s %s\n" % (command.ljust(17), getattr(self, 'do_' + command).__doc__)) - self.stdout.write("\n") - - - def emptyline(self): - pass - - def do_back(self, line): "Go back to the main menu." raise NavMain() - - def do_agents(self, line): - "Jump to the Agents menu." - raise NavAgents() - - - def do_main(self, line): - "Go back to the main menu." - raise NavMain() - - - def do_exit(self, line): - "Exit Empire." - raise KeyboardInterrupt - - def do_list(self, line): "List all active listeners (or agents)." @@ -3014,13 +2974,11 @@ class ListenersMenu(cmd.Cmd): return [s[offs:] for s in names if s.startswith(mline)] -class ListenerMenu(cmd.Cmd): +class ListenerMenu(SubMenu): def __init__(self, mainMenu, listenerName): - cmd.Cmd.__init__(self) - - self.mainMenu = mainMenu + SubMenu.__init__(self, mainMenu) if listenerName not in self.mainMenu.listeners.loadedListeners: print helpers.color("[!] Listener '%s' not currently valid!" % (listenerName)) @@ -3034,39 +2992,6 @@ class ListenerMenu(cmd.Cmd): # set the text prompt self.prompt = '(Empire: ' + helpers.color("listeners/%s" % (listenerName), 'red') + ') > ' - - def emptyline(self): - """ - If any empty line is entered, do nothing. - """ - pass - - - def do_back(self, line): - "Go back a menu." - return True - - - def do_agents(self, line): - "Jump to the Agents menu." - raise NavAgents() - - - def do_listeners(self, line): - "Jump to the listeners menu." - raise NavListeners() - - - def do_main(self, line): - "Go back to the main menu." - raise NavMain() - - - def do_exit(self, line): - "Exit Empire." - raise KeyboardInterrupt - - def do_info(self, line): "Display listener module options." messages.display_listener_module(self.listener) @@ -3191,15 +3116,14 @@ class ListenerMenu(cmd.Cmd): return [s[offs:] for s in languages if s.startswith(mline)] -class ModuleMenu(cmd.Cmd): +class ModuleMenu(SubMenu): """ The main class used by Empire to drive the 'module' menu. """ def __init__(self, mainMenu, moduleName, agent=None): - cmd.Cmd.__init__(self) + SubMenu.__init__(self, mainMenu) self.doc_header = 'Module Commands' - self.mainMenu = mainMenu try: # get the current module/name @@ -3218,10 +3142,7 @@ class ModuleMenu(cmd.Cmd): except Exception as e: print helpers.color("[!] ModuleMenu() init error: %s" % (e)) - # def preloop(self): - # traceback.print_stack() - - def validate_options(self): + def validate_options(self, prompt): "Ensure all required module options are completed." # ensure all 'Required=True' options are filled in @@ -3255,8 +3176,9 @@ class ModuleMenu(cmd.Cmd): print helpers.color("[!] Error: module needs to run in an elevated context.") return False - # if the module isn't opsec safe, prompt before running - if ('OpsecSafe' in self.module.info) and (not self.module.info['OpsecSafe']): + # if the module isn't opsec safe, prompt before running (unless "execute noprompt" was issued) + if prompt and ('OpsecSafe' in self.module.info) and (not self.module.info['OpsecSafe']): + try: choice = raw_input(helpers.color("[>] Module is not opsec safe, run? [y/N] ", "red")) if not (choice.lower() != "" and choice.lower()[0] == "y"): @@ -3267,48 +3189,6 @@ class ModuleMenu(cmd.Cmd): return True - - def emptyline(self): - pass - - - # print a nicely formatted help menu - # stolen/adapted from recon-ng - def print_topics(self, header, commands, cmdlen, maxcol): - if commands: - self.stdout.write("%s\n" % str(header)) - if self.ruler: - self.stdout.write("%s\n" % str(self.ruler * len(header))) - for command in commands: - self.stdout.write("%s %s\n" % (command.ljust(17), getattr(self, 'do_' + command).__doc__)) - self.stdout.write("\n") - - - def do_back(self, line): - "Go back a menu." - return True - - - def do_agents(self, line): - "Jump to the Agents menu." - raise NavAgents() - - - def do_listeners(self, line): - "Jump to the listeners menu." - raise NavListeners() - - - def do_main(self, line): - "Go back to the main menu." - raise NavMain() - - - def do_exit(self, line): - "Exit Empire." - raise KeyboardInterrupt - - def do_list(self, line): "Lists all active agents (or listeners)." @@ -3319,7 +3199,6 @@ class ModuleMenu(cmd.Cmd): else: print helpers.color("[!] Please use 'list [agents/listeners] '.") - def do_reload(self, line): "Reload the current module." @@ -3411,7 +3290,11 @@ class ModuleMenu(cmd.Cmd): def do_execute(self, line): "Execute the given Empire module." - if not self.validate_options(): + prompt = True + if line == "noprompt": + prompt = False + + if not self.validate_options(prompt): return if self.moduleName.lower().startswith('external/'): @@ -3601,16 +3484,14 @@ class ModuleMenu(cmd.Cmd): return [s[offs:] for s in names if s.startswith(mline)] -class StagerMenu(cmd.Cmd): +class StagerMenu(SubMenu): """ The main class used by Empire to drive the 'stager' menu. """ def __init__(self, mainMenu, stagerName, listener=None): - cmd.Cmd.__init__(self) + SubMenu.__init__(self, mainMenu) self.doc_header = 'Stager Menu' - self.mainMenu = mainMenu - # get the current stager name self.stagerName = stagerName self.stager = self.mainMenu.stagers.stagers[stagerName] @@ -3624,7 +3505,6 @@ class StagerMenu(cmd.Cmd): listener = self.mainMenu.listeners.get_listener(listener) self.stager.options['Listener']['Value'] = listener - def validate_options(self): "Make sure all required stager options are completed." @@ -3641,48 +3521,6 @@ class StagerMenu(cmd.Cmd): return True - - def emptyline(self): - pass - - - # print a nicely formatted help menu - # stolen/adapted from recon-ng - def print_topics(self, header, commands, cmdlen, maxcol): - if commands: - self.stdout.write("%s\n" % str(header)) - if self.ruler: - self.stdout.write("%s\n" % str(self.ruler * len(header))) - for command in commands: - self.stdout.write("%s %s\n" % (command.ljust(17), getattr(self, 'do_' + command).__doc__)) - self.stdout.write("\n") - - - def do_back(self, line): - "Go back a menu." - return True - - - def do_agents(self, line): - "Jump to the Agents menu." - raise NavAgents() - - - def do_listeners(self, line): - "Jump to the listeners menu." - raise NavListeners() - - - def do_main(self, line): - "Go back to the main menu." - raise NavMain() - - - def do_exit(self, line): - "Exit Empire." - raise KeyboardInterrupt - - def do_list(self, line): "Lists all active agents (or listeners)." @@ -3750,7 +3588,6 @@ class StagerMenu(cmd.Cmd): def do_generate(self, line): "Generate/execute the given Empire stager." - if not self.validate_options(): return @@ -3781,7 +3618,6 @@ class StagerMenu(cmd.Cmd): os.chmod(savePath, 777) print "\n" + helpers.color("[*] Stager output written out to: %s\n" % (savePath)) - else: print stagerOutput