Merge pull request #750 from clr2of8/dev

Added resource file and auto run functionality as in Metasploit
websockets-multiuser
Chris Ross 2017-10-18 16:31:17 -04:00 committed by GitHub
commit 1cb3e1e375
3 changed files with 206 additions and 342 deletions

1
empire
View File

@ -1248,6 +1248,7 @@ if __name__ == '__main__':
generalGroup = parser.add_argument_group('General Options') 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('--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('-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 = 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.') cliGroup.add_argument('-l', '--listener', nargs='?', const="list", help='Display listener options. Displays all listeners if nothing is specified.')

View File

@ -1343,6 +1343,20 @@ class Agents:
if autorun and autorun[0] != '' and autorun[1] != '': if autorun and autorun[0] != '' and autorun[1] != '':
self.add_agent_task_db(sessionID, autorun[0], 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) return "STAGE2: %s" % (sessionID)
else: else:
@ -1399,7 +1413,6 @@ class Agents:
TODO: does this need self.lock? TODO: does this need self.lock?
""" """
if sessionID not in self.agents: if sessionID not in self.agents:
dispatcher.send("[!] handle_agent_request(): sessionID %s not present" % (sessionID), sender='Agents') dispatcher.send("[!] handle_agent_request(): sessionID %s not present" % (sessionID), sender='Agents')
return None return None
@ -1417,6 +1430,7 @@ class Agents:
# build tasking packets for everything we have # build tasking packets for everything we have
for tasking in taskings: for tasking in taskings:
task_name, task_data, res_id = tasking task_name, task_data, res_id = tasking
all_task_packets += packets.build_task_packet(task_name, task_data, res_id) all_task_packets += packets.build_task_packet(task_name, task_data, res_id)
# get the session key for the agent # get the session key for the agent
@ -1495,6 +1509,7 @@ class Agents:
""" """
agentSessionID = sessionID agentSessionID = sessionID
keyLogTaskID = None
# see if we were passed a name instead of an ID # see if we were passed a name instead of an ID
nameid = self.get_agent_id_db(sessionID) nameid = self.get_agent_id_db(sessionID)
@ -1519,6 +1534,7 @@ class Agents:
pk = (pk + 1) % 65536 pk = (pk + 1) % 65536
cur.execute("INSERT INTO results (id, agent, data) VALUES (?,?,?)",(pk, sessionID, data)) cur.execute("INSERT INTO results (id, agent, data) VALUES (?,?,?)",(pk, sessionID, data))
else: 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]) cur.execute("UPDATE results SET data=data||? WHERE id=? AND agent=?", [data, taskID, sessionID])
finally: finally:
@ -1703,9 +1719,20 @@ class Agents:
elif responseName == "TASK_CMD_JOB": 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 # update the agent log
self.save_agent_log(sessionID, data) self.save_agent_log(sessionID, data)

View File

@ -93,12 +93,14 @@ class MainMenu(cmd.Cmd):
self.stagers = stagers.Stagers(self, args=args) self.stagers = stagers.Stagers(self, args=args)
self.modules = modules.Modules(self, args=args) self.modules = modules.Modules(self, args=args)
self.listeners = listeners.Listeners(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() self.handle_args()
dispatcher.send('[*] Empire starting up...', sender="Empire") dispatcher.send('[*] Empire starting up...', sender="Empire")
# print the loading menu # print the loading menu
messages.loading() messages.loading()
@ -137,6 +139,9 @@ class MainMenu(cmd.Cmd):
""" """
Handle any passed arguments. 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 self.args.listener or self.args.stager:
# if we're displaying listeners/stagers or generating a 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") print helpers.color("[!] Please run database_setup.py")
sys.exit() sys.exit()
# def preloop(self):
# traceback.print_stack()
def cmdloop(self): def cmdloop(self):
""" """
The main cmdloop logic that handles navigation to other menus. 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_listeners), "green") + " listeners currently active\n"
print " " + helpers.color(str(num_agents), "green") + " agents currently active\n\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) cmd.Cmd.cmdloop(self)
@ -378,10 +381,43 @@ class MainMenu(cmd.Cmd):
# CMD methods # 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): def default(self, line):
"Default handler." "Default handler."
pass 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): def do_exit(self, line):
"Exit Empire" "Exit Empire"
@ -428,7 +464,6 @@ class MainMenu(cmd.Cmd):
stager_menu.cmdloop() stager_menu.cmdloop()
else: else:
print helpers.color("[!] Error in MainMenu's do_userstager()") print helpers.color("[!] Error in MainMenu's do_userstager()")
except Exception as e: except Exception as e:
raise e raise e
@ -704,7 +739,6 @@ class MainMenu(cmd.Cmd):
name = line.strip() name = line.strip()
sessionID = self.agents.get_agent_id_db(name) sessionID = self.agents.get_agent_id_db(name)
if sessionID and sessionID != '' and sessionID in self.agents.agents: if sessionID and sessionID != '' and sessionID in self.agents.agents:
AgentMenu(self, sessionID) AgentMenu(self, sessionID)
else: else:
@ -888,25 +922,58 @@ class MainMenu(cmd.Cmd):
offs = len(mline) - len(text) offs = len(mline) - len(text)
return [s[offs:] for s in options if s.startswith(mline)] return [s[offs:] for s in options if s.startswith(mline)]
class SubMenu(cmd.Cmd):
class AgentsMenu(cmd.Cmd):
"""
The main class used by Empire to drive the 'agents' menu.
"""
def __init__(self, mainMenu): def __init__(self, mainMenu):
cmd.Cmd.__init__(self) cmd.Cmd.__init__(self)
self.mainMenu = mainMenu 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 def emptyline(self):
self.prompt = '(Empire: ' + helpers.color("agents", color="blue") + ') > ' pass
messages.display_agents(self.mainMenu.agents.get_agents_db())
# def preloop(self): def postcmd(self, stop, line):
# traceback.print_stack() 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 # print a nicely formatted help menu
# stolen/adapted from recon-ng # 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("%s %s\n" % (command.ljust(17), getattr(self, 'do_' + command).__doc__))
self.stdout.write("\n") self.stdout.write("\n")
# def preloop(self):
# traceback.print_stack()
def emptyline(self): class AgentsMenu(SubMenu):
pass """
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): def do_back(self, line):
"Go back to the main menu." "Go back to the main menu."
raise NavMain() raise NavMain()
def do_autorun(self, line):
def do_listeners(self, line): "Read and execute a list of Empire commands from a file and execute on each new agent \"autorun <resource file> <agent language>\" e.g. \"autorun /root/ps.rc powershell\". Or clear any autorun setting with \"autorun clear\" and show current autorun settings with \"autorun show\""
"Jump to the listeners menu." line = line.strip()
raise NavListeners() 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
def do_main(self, line): cmds = line.split(' ')
"Go back to the main menu." resourceFile = cmds[0]
raise NavMain() language = None
if len(cmds) > 1:
language = cmds[1].lower()
def do_exit(self, line): elif not resourceFile == "show" and not resourceFile == "clear":
"Exit Empire." 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'")
raise KeyboardInterrupt 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): def do_list(self, line):
@ -954,7 +1055,6 @@ class AgentsMenu(cmd.Cmd):
else: else:
self.mainMenu.do_list("agents " + str(line)) self.mainMenu.do_list("agents " + str(line))
def do_rename(self, line): def do_rename(self, line):
"Rename a particular agent." "Rename a particular agent."
@ -1011,12 +1111,6 @@ class AgentsMenu(cmd.Cmd):
except KeyboardInterrupt: except KeyboardInterrupt:
print '' print ''
def do_creds(self, line):
"Display/return credentials from the database."
self.mainMenu.do_creds(line)
def do_clear(self, line): def do_clear(self, line):
"Clear one or more agent's taskings." "Clear one or more agent's taskings."
@ -1410,7 +1504,7 @@ class AgentsMenu(cmd.Cmd):
return self.mainMenu.complete_creds(text, line, begidx, endidx) 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 An abstracted class used by Empire to determine which agent menu type
to instantiate. to instantiate.
@ -1419,25 +1513,24 @@ class AgentMenu(cmd.Cmd):
agentLanguage = mainMenu.agents.get_language_db(sessionID) agentLanguage = mainMenu.agents.get_language_db(sessionID)
if agentLanguage.lower() == 'powershell': if agentLanguage.lower() == 'powershell':
agent_menu = PowerShellAgentMenu(mainMenu, sessionID) agent_menu = PowerShellAgentMenu(mainMenu, sessionID)
agent_menu.cmdloop() agent_menu.cmdloop()
elif agentLanguage.lower() == 'python': elif agentLanguage.lower() == 'python':
agent_menu = PythonAgentMenu(mainMenu, sessionID) agent_menu = PythonAgentMenu(mainMenu, sessionID)
agent_menu.cmdloop() agent_menu.cmdloop()
else: else:
print helpers.color("[!] Agent language %s not recognized." % (agentLanguage)) 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. The main class used by Empire to drive an individual 'agent' menu.
""" """
def __init__(self, mainMenu, sessionID): def __init__(self, mainMenu, sessionID):
cmd.Cmd.__init__(self) SubMenu.__init__(self, mainMenu)
self.mainMenu = mainMenu
self.sessionID = sessionID self.sessionID = sessionID
self.doc_header = 'Agent Commands' self.doc_header = 'Agent Commands'
@ -1459,7 +1552,6 @@ class PowerShellAgentMenu(cmd.Cmd):
# listen for messages from this specific agent # listen for messages from this specific agent
dispatcher.connect(self.handle_agent_event, sender=dispatcher.Any) dispatcher.connect(self.handle_agent_event, sender=dispatcher.Any)
# def preloop(self): # def preloop(self):
# traceback.print_stack() # traceback.print_stack()
@ -1467,49 +1559,22 @@ class PowerShellAgentMenu(cmd.Cmd):
""" """
Handle agent event signals. Handle agent event signals.
""" """
if '[!] Agent' in signal and 'exiting' in signal: if '[!] Agent' in signal and 'exiting' in signal:
pass pass
name = self.mainMenu.agents.get_agent_name_db(self.sessionID) 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): 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 # 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) results = self.mainMenu.agents.get_agent_results_db(self.sessionID)
if results: if results and not sender == "AgentsPsKeyLogger":
if sender == "AgentsPsKeyLogger" and ("Job started:" not in results) and ("killed." not in results): print "\n" + 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
elif "[+] Part of file" in signal and "saved" in signal: elif "[+] Part of file" in signal and "saved" in signal:
if (str(self.sessionID) in signal) or (str(name) in signal): if (str(self.sessionID) in signal) or (str(name) in signal):
print helpers.color(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): def default(self, line):
"Default handler" "Default handler"
@ -1529,27 +1594,6 @@ class PowerShellAgentMenu(cmd.Cmd):
print helpers.color("[!] Command not recognized.") print helpers.color("[!] Command not recognized.")
print helpers.color("[*] Use 'help' or 'help agentcmds' to see available commands.") 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): def do_help(self, *args):
"Displays the help menu or syntax for particular commands." "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 "\n" + helpers.color("[*] Available opsec-safe agent commands:\n")
print " " + messages.wrap_columns(", ".join(self.agentCommands), ' ', width1=50, width2=10, indent=5) + "\n" print " " + messages.wrap_columns(", ".join(self.agentCommands), ' ', width1=50, width2=10, indent=5) + "\n"
else: else:
cmd.Cmd.do_help(self, *args) SubMenu.do_help(self, *args)
def do_list(self, line): def do_list(self, line):
"Lists all active agents (or listeners)." "Lists all active agents (or listeners)."
@ -1570,7 +1613,6 @@ class PowerShellAgentMenu(cmd.Cmd):
else: else:
print helpers.color("[!] Please use 'list [agents/listeners] <modifier>'.") print helpers.color("[!] Please use 'list [agents/listeners] <modifier>'.")
def do_rename(self, line): def do_rename(self, line):
"Rename the agent." "Rename the agent."
@ -1586,7 +1628,6 @@ class PowerShellAgentMenu(cmd.Cmd):
else: else:
print helpers.color("[!] Please enter a new name for the agent") print helpers.color("[!] Please enter a new name for the agent")
def do_info(self, line): def do_info(self, line):
"Display information about this agent" "Display information about this agent"
@ -1594,7 +1635,6 @@ class PowerShellAgentMenu(cmd.Cmd):
agent = self.mainMenu.agents.get_agent_db(self.sessionID) agent = self.mainMenu.agents.get_agent_db(self.sessionID)
messages.display_agent(agent) messages.display_agent(agent)
def do_exit(self, line): def do_exit(self, line):
"Task agent to exit." "Task agent to exit."
@ -1707,7 +1747,6 @@ class PowerShellAgentMenu(cmd.Cmd):
self.mainMenu.agents.add_agent_task_db(self.sessionID, "TASK_SHELL", command) self.mainMenu.agents.add_agent_task_db(self.sessionID, "TASK_SHELL", command)
# update the agent log
msg = "Tasked agent to kill process: " + str(process) msg = "Tasked agent to kill process: " + str(process)
self.mainMenu.agents.save_agent_log(self.sessionID, msg) 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) return self.mainMenu.complete_creds(text, line, begidx, endidx)
class PythonAgentMenu(cmd.Cmd): class PythonAgentMenu(SubMenu):
def __init__(self, mainMenu, sessionID): def __init__(self, mainMenu, sessionID):
cmd.Cmd.__init__(self) SubMenu.__init__(self, mainMenu)
self.mainMenu = mainMenu
self.sessionID = sessionID self.sessionID = sessionID
@ -2285,9 +2322,6 @@ class PythonAgentMenu(cmd.Cmd):
if results: if results:
print "\n" + results.rstrip('\r\n') print "\n" + results.rstrip('\r\n')
# def preloop(self):
# traceback.print_stack()
def handle_agent_event(self, signal, sender): def handle_agent_event(self, signal, sender):
""" """
Handle agent event signals. Handle agent event signals.
@ -2307,51 +2341,13 @@ class PythonAgentMenu(cmd.Cmd):
if (str(self.sessionID) in signal) or (str(name) in signal): if (str(self.sessionID) in signal) or (str(name) in signal):
print helpers.color(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): def default(self, line):
"Default handler" "Default handler"
print helpers.color("[!] Command not recognized, use 'help' to see available commands") 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): def do_help(self, *args):
"Displays the help menu or syntax for particular commands." "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): def do_list(self, line):
@ -2677,6 +2673,7 @@ class PythonAgentMenu(cmd.Cmd):
# Strip asterisks added by MainMenu.complete_usemodule() # Strip asterisks added by MainMenu.complete_usemodule()
module = "python/%s" %(line.strip().rstrip("*")) module = "python/%s" %(line.strip().rstrip("*"))
if module not in self.mainMenu.modules.modules: if module not in self.mainMenu.modules.modules:
print helpers.color("[!] Error: invalid module") print helpers.color("[!] Error: invalid module")
else: else:
@ -2801,14 +2798,12 @@ class PythonAgentMenu(cmd.Cmd):
# return helpers.complete_path(text,line) # return helpers.complete_path(text,line)
class ListenersMenu(cmd.Cmd): class ListenersMenu(SubMenu):
""" """
The main class used by Empire to drive the 'listener' menu. The main class used by Empire to drive the 'listener' menu.
""" """
def __init__(self, mainMenu): def __init__(self, mainMenu):
cmd.Cmd.__init__(self) SubMenu.__init__(self, mainMenu)
self.mainMenu = mainMenu
self.doc_header = 'Listener Commands' self.doc_header = 'Listener Commands'
@ -2818,45 +2813,10 @@ class ListenersMenu(cmd.Cmd):
# display all active listeners on menu startup # display all active listeners on menu startup
messages.display_active_listeners(self.mainMenu.listeners.activeListeners) 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): def do_back(self, line):
"Go back to the main menu." "Go back to the main menu."
raise NavMain() 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): def do_list(self, line):
"List all active listeners (or agents)." "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)] return [s[offs:] for s in names if s.startswith(mline)]
class ListenerMenu(cmd.Cmd): class ListenerMenu(SubMenu):
def __init__(self, mainMenu, listenerName): def __init__(self, mainMenu, listenerName):
cmd.Cmd.__init__(self) SubMenu.__init__(self, mainMenu)
self.mainMenu = mainMenu
if listenerName not in self.mainMenu.listeners.loadedListeners: if listenerName not in self.mainMenu.listeners.loadedListeners:
print helpers.color("[!] Listener '%s' not currently valid!" % (listenerName)) print helpers.color("[!] Listener '%s' not currently valid!" % (listenerName))
@ -3034,39 +2992,6 @@ class ListenerMenu(cmd.Cmd):
# set the text prompt # set the text prompt
self.prompt = '(Empire: ' + helpers.color("listeners/%s" % (listenerName), 'red') + ') > ' 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): def do_info(self, line):
"Display listener module options." "Display listener module options."
messages.display_listener_module(self.listener) 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)] 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. The main class used by Empire to drive the 'module' menu.
""" """
def __init__(self, mainMenu, moduleName, agent=None): def __init__(self, mainMenu, moduleName, agent=None):
cmd.Cmd.__init__(self) SubMenu.__init__(self, mainMenu)
self.doc_header = 'Module Commands' self.doc_header = 'Module Commands'
self.mainMenu = mainMenu
try: try:
# get the current module/name # get the current module/name
@ -3218,10 +3142,7 @@ class ModuleMenu(cmd.Cmd):
except Exception as e: except Exception as e:
print helpers.color("[!] ModuleMenu() init error: %s" % (e)) print helpers.color("[!] ModuleMenu() init error: %s" % (e))
# def preloop(self): def validate_options(self, prompt):
# traceback.print_stack()
def validate_options(self):
"Ensure all required module options are completed." "Ensure all required module options are completed."
# ensure all 'Required=True' options are filled in # 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.") print helpers.color("[!] Error: module needs to run in an elevated context.")
return False return False
# if the module isn't opsec safe, prompt before running # if the module isn't opsec safe, prompt before running (unless "execute noprompt" was issued)
if ('OpsecSafe' in self.module.info) and (not self.module.info['OpsecSafe']): if prompt and ('OpsecSafe' in self.module.info) and (not self.module.info['OpsecSafe']):
try: try:
choice = raw_input(helpers.color("[>] Module is not opsec safe, run? [y/N] ", "red")) choice = raw_input(helpers.color("[>] Module is not opsec safe, run? [y/N] ", "red"))
if not (choice.lower() != "" and choice.lower()[0] == "y"): if not (choice.lower() != "" and choice.lower()[0] == "y"):
@ -3267,48 +3189,6 @@ class ModuleMenu(cmd.Cmd):
return True 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): def do_list(self, line):
"Lists all active agents (or listeners)." "Lists all active agents (or listeners)."
@ -3319,7 +3199,6 @@ class ModuleMenu(cmd.Cmd):
else: else:
print helpers.color("[!] Please use 'list [agents/listeners] <modifier>'.") print helpers.color("[!] Please use 'list [agents/listeners] <modifier>'.")
def do_reload(self, line): def do_reload(self, line):
"Reload the current module." "Reload the current module."
@ -3411,7 +3290,11 @@ class ModuleMenu(cmd.Cmd):
def do_execute(self, line): def do_execute(self, line):
"Execute the given Empire module." "Execute the given Empire module."
if not self.validate_options(): prompt = True
if line == "noprompt":
prompt = False
if not self.validate_options(prompt):
return return
if self.moduleName.lower().startswith('external/'): 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)] 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. The main class used by Empire to drive the 'stager' menu.
""" """
def __init__(self, mainMenu, stagerName, listener=None): def __init__(self, mainMenu, stagerName, listener=None):
cmd.Cmd.__init__(self) SubMenu.__init__(self, mainMenu)
self.doc_header = 'Stager Menu' self.doc_header = 'Stager Menu'
self.mainMenu = mainMenu
# get the current stager name # get the current stager name
self.stagerName = stagerName self.stagerName = stagerName
self.stager = self.mainMenu.stagers.stagers[stagerName] self.stager = self.mainMenu.stagers.stagers[stagerName]
@ -3624,7 +3505,6 @@ class StagerMenu(cmd.Cmd):
listener = self.mainMenu.listeners.get_listener(listener) listener = self.mainMenu.listeners.get_listener(listener)
self.stager.options['Listener']['Value'] = listener self.stager.options['Listener']['Value'] = listener
def validate_options(self): def validate_options(self):
"Make sure all required stager options are completed." "Make sure all required stager options are completed."
@ -3641,48 +3521,6 @@ class StagerMenu(cmd.Cmd):
return True 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): def do_list(self, line):
"Lists all active agents (or listeners)." "Lists all active agents (or listeners)."
@ -3750,7 +3588,6 @@ class StagerMenu(cmd.Cmd):
def do_generate(self, line): def do_generate(self, line):
"Generate/execute the given Empire stager." "Generate/execute the given Empire stager."
if not self.validate_options(): if not self.validate_options():
return return
@ -3781,7 +3618,6 @@ class StagerMenu(cmd.Cmd):
os.chmod(savePath, 777) os.chmod(savePath, 777)
print "\n" + helpers.color("[*] Stager output written out to: %s\n" % (savePath)) print "\n" + helpers.color("[*] Stager output written out to: %s\n" % (savePath))
else: else:
print stagerOutput print stagerOutput