Added ability to enable/disable listeners, so they are still stored in the
database, but will not start automatically. Also, listener options can now be edited without deleting the listener and starting a new one from scratch.php_fix
parent
8a27017d43
commit
3bff4e6ef2
|
@ -155,7 +155,9 @@ class MainMenu(cmd.Cmd):
|
|||
# if we're displaying listeners/stagers or generating a stager
|
||||
if self.args.listener:
|
||||
if self.args.listener == 'list':
|
||||
messages.display_active_listeners(self.listeners.activeListeners)
|
||||
messages.display_listeners(self.listeners.activeListeners)
|
||||
messages.display_listeners(self.listeners.get_inactive_listeners(), "Inactive")
|
||||
|
||||
else:
|
||||
activeListeners = self.listeners.activeListeners
|
||||
targetListener = [l for l in activeListeners if self.args.listener in l[1]]
|
||||
|
@ -783,7 +785,8 @@ class MainMenu(cmd.Cmd):
|
|||
|
||||
|
||||
elif parts[0].lower() == 'listeners':
|
||||
messages.display_active_listeners(self.listeners.activeListeners)
|
||||
messages.display_listeners(self.listeners.activeListeners)
|
||||
messages.display_listeners(self.listeners.get_inactive_listeners(), "Inactive")
|
||||
|
||||
|
||||
def do_interact(self, line):
|
||||
|
@ -2912,7 +2915,8 @@ class ListenersMenu(SubMenu):
|
|||
self.prompt = '(Empire: ' + helpers.color('listeners', color='blue') + ') > '
|
||||
|
||||
# display all active listeners on menu startup
|
||||
messages.display_active_listeners(self.mainMenu.listeners.activeListeners)
|
||||
messages.display_listeners(self.mainMenu.listeners.activeListeners)
|
||||
messages.display_listeners(self.mainMenu.listeners.get_inactive_listeners(), "Inactive")
|
||||
|
||||
def do_back(self, line):
|
||||
"Go back to the main menu."
|
||||
|
@ -3027,6 +3031,48 @@ class ListenersMenu(SubMenu):
|
|||
else:
|
||||
print helpers.color("[!] Please enter a valid listenerName")
|
||||
|
||||
def do_enable(self, line):
|
||||
"Enables and starts one or all listners."
|
||||
|
||||
listenerID = line.strip()
|
||||
|
||||
if listenerID == '':
|
||||
print helpers.color("[!] Please provide a listener name")
|
||||
elif listenerID.lower() == 'all':
|
||||
try:
|
||||
choice = raw_input(helpers.color('[>] Start all listeners? [y/N] ', 'red'))
|
||||
if choice.lower() != '' and choice.lower()[0] == 'y':
|
||||
self.mainMenu.listeners.enable_listener('all')
|
||||
except KeyboardInterrupt:
|
||||
print ''
|
||||
|
||||
else:
|
||||
self.mainMenu.listeners.enable_listener(listenerID)
|
||||
|
||||
def do_disable(self, line):
|
||||
"Disables (stops) one or all listeners. The listener(s) will not start automatically with Empire"
|
||||
|
||||
listenerID = line.strip()
|
||||
|
||||
if listenerID.lower() == 'all':
|
||||
try:
|
||||
choice = raw_input(helpers.color('[>] Stop all listeners? [y/N] ', 'red'))
|
||||
if choice.lower() != '' and choice.lower()[0] == 'y':
|
||||
self.mainMenu.listeners.shutdown_listener('all')
|
||||
except KeyboardInterrupt:
|
||||
print ''
|
||||
|
||||
else:
|
||||
self.mainMenu.listeners.disable_listener(listenerID)
|
||||
|
||||
def do_edit(self,line):
|
||||
"Change a listener option, will not take effect until the listener is restarted"
|
||||
|
||||
arguments = line.strip().split(" ")
|
||||
if len(arguments) < 3:
|
||||
print helpers.color("[!] edit <listener name> <option name> <option value>")
|
||||
return
|
||||
self.mainMenu.listeners.update_listener_options(arguments[0], arguments[1], arguments[2])
|
||||
|
||||
def complete_usestager(self, text, line, begidx, endidx):
|
||||
"Tab-complete an Empire stager module path."
|
||||
|
|
|
@ -198,7 +198,7 @@ class Listeners:
|
|||
self.activeListeners[name] = {'moduleName': moduleName, 'options':listenerOptions}
|
||||
pickledOptions = pickle.dumps(listenerObject.options)
|
||||
cur = self.conn.cursor()
|
||||
cur.execute("INSERT INTO listeners (name, module, listener_category, options) VALUES (?,?,?,?)", [name, moduleName, category, pickledOptions])
|
||||
cur.execute("INSERT INTO listeners (name, module, listener_category, enabled, options) VALUES (?,?,?,?,?)", [name, moduleName, category, True, pickledOptions])
|
||||
cur.close()
|
||||
else:
|
||||
print helpers.color('[!] Listener failed to start!')
|
||||
|
@ -216,7 +216,7 @@ class Listeners:
|
|||
oldFactory = self.conn.row_factory
|
||||
self.conn.row_factory = helpers.dict_factory
|
||||
cur = self.conn.cursor()
|
||||
cur.execute("SELECT id,name,module,listener_type,listener_category,options FROM listeners")
|
||||
cur.execute("SELECT id,name,module,listener_type,listener_category,options FROM listeners WHERE enabled=?", [True])
|
||||
results = cur.fetchall()
|
||||
cur.close()
|
||||
|
||||
|
@ -259,6 +259,50 @@ class Listeners:
|
|||
|
||||
self.conn.row_factory = oldFactory
|
||||
|
||||
def enable_listener(self, listenerName):
|
||||
"Starts an existing listener and sets it to enabled"
|
||||
if listenerName in self.activeListeners.keys():
|
||||
print helpers.color("[!] Listener already running!")
|
||||
return False
|
||||
|
||||
oldFactory = self.conn.row_factory
|
||||
self.conn.row_factory = helpers.dict_factory
|
||||
cur = self.conn.cursor()
|
||||
cur.execute("SELECT id,name,module,listener_type,listener_category,options FROM listeners WHERE name=?", [listenerName])
|
||||
result = cur.fetchone()
|
||||
if not result:
|
||||
print helpers.color("[!] Listener %s doesn't exist!" % listenerName)
|
||||
return False
|
||||
moduleName = result['module']
|
||||
options = pickle.loads(result['options'])
|
||||
try:
|
||||
listenerModule = self.loadedListeners[moduleName]
|
||||
|
||||
for option, value in options.iteritems():
|
||||
listenerModule.options[option] = value
|
||||
|
||||
print helpers.color("[*] Starting listener '%s'" % (listenerName))
|
||||
if moduleName == 'redirector':
|
||||
success = True
|
||||
else:
|
||||
success = listenerModule.start(name=listenerName)
|
||||
|
||||
if success:
|
||||
print helpers.color('[+] Listener successfully started!')
|
||||
listenerOptions = copy.deepcopy(listenerModule.options)
|
||||
self.activeListeners[listenerName] = {'moduleName': moduleName, 'options': listenerOptions}
|
||||
cur.execute("UPDATE listeners SET enabled=? WHERE name=? AND NOT module=?", [True, listenerName, 'redirector'])
|
||||
else:
|
||||
print helpers.color('[!] Listener failed to start!')
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
if listenerName in self.activeListeners:
|
||||
del self.activeListeners[listenerName]
|
||||
print helpers.color("[!] Error starting listener: %s" % (e))
|
||||
|
||||
cur.close()
|
||||
self.conn.row_factory = oldFactory
|
||||
|
||||
|
||||
def kill_listener(self, listenerName):
|
||||
"""
|
||||
|
@ -327,6 +371,17 @@ class Listeners:
|
|||
# remove the listener object from the internal cache
|
||||
del self.activeListeners[listenerName]
|
||||
|
||||
def disable_listener(self, listenerName):
|
||||
"Wrapper for shutdown_listener(), also marks listener as 'disabled' so it won't autostart"
|
||||
|
||||
cur = self.conn.cursor()
|
||||
if listenerName.lower() == "all":
|
||||
cur.execute("UPDATE listeners SET enabled=? WHERE NOT module=?", [False, "redirector"])
|
||||
else:
|
||||
cur.execute("UPDATE listeners SET enabled=? WHERE name=? AND NOT module=?", [False, listenerName.lower(), "redirector"])
|
||||
cur.close()
|
||||
cur.close()
|
||||
self.shutdown_listener(listenerName)
|
||||
|
||||
def is_listener_valid(self, name):
|
||||
return name in self.activeListeners
|
||||
|
@ -399,3 +454,45 @@ class Listeners:
|
|||
Return all current listener names.
|
||||
"""
|
||||
return self.activeListeners.keys()
|
||||
|
||||
def get_inactive_listeners(self):
|
||||
"""
|
||||
Returns any listeners that are not currently running
|
||||
"""
|
||||
|
||||
oldFactory = self.conn.row_factory
|
||||
self.conn.row_factory = helpers.dict_factory
|
||||
cur = self.conn.cursor()
|
||||
|
||||
cur.execute("SELECT name,module,options FROM listeners")
|
||||
db_listeners = cur.fetchall()
|
||||
|
||||
inactive_listeners = {}
|
||||
for listener in filter((lambda x: x['name'] not in self.activeListeners.keys()), db_listeners):
|
||||
inactive_listeners[listener['name']] = {'moduleName': listener['module'],
|
||||
'options': pickle.loads(listener['options'])}
|
||||
|
||||
cur.close()
|
||||
self.conn.row_factory = oldFactory
|
||||
return inactive_listeners
|
||||
|
||||
|
||||
def update_listener_options(self, listener_name, option_name, option_value):
|
||||
"Updates a listener option in the database"
|
||||
|
||||
try:
|
||||
cur = self.conn.cursor()
|
||||
cur.execute('SELECT id,options FROM listeners WHERE name=?', [listener_name])
|
||||
listener_id, result = cur.fetchone()
|
||||
options = pickle.loads(result)
|
||||
if not option_name in options.keys():
|
||||
print helpers.color("[!] Listener %s does not have the option %s" % (listener_name, option_name))
|
||||
return
|
||||
options[option_name]['Value'] = option_value
|
||||
pickled_options = pickle.dumps(options)
|
||||
cur.execute('UPDATE listeners SET options=? WHERE id=?', [pickled_options, listener_id])
|
||||
if listener_name in self.activeListeners.keys():
|
||||
print helpers.color("[*] This change will not take effect until the listener is restarted")
|
||||
except ValueError:
|
||||
print helpers.color("[!] Listener %s not found" % listenerName)
|
||||
cur.close()
|
||||
|
|
|
@ -220,14 +220,14 @@ def display_agent(agent, returnAsString=False):
|
|||
print ''
|
||||
|
||||
|
||||
def display_active_listeners(listeners):
|
||||
def display_listeners(listeners, type = "Active"):
|
||||
"""
|
||||
Take an active listeners list and display everything nicely.
|
||||
"""
|
||||
|
||||
if len(listeners) > 0:
|
||||
print ''
|
||||
print helpers.color("[*] Active listeners:\n")
|
||||
print helpers.color("[*] %s listeners:\n" % type)
|
||||
|
||||
print " Name Module Host Delay/Jitter KillDate"
|
||||
print " ---- ------ ---- ------------ --------"
|
||||
|
@ -265,7 +265,8 @@ def display_active_listeners(listeners):
|
|||
print ''
|
||||
|
||||
else:
|
||||
print helpers.color("[!] No listeners currently active ")
|
||||
if(type.lower() != "inactive"):
|
||||
print helpers.color("[!] No listeners currently %s " % type.lower())
|
||||
|
||||
|
||||
def display_active_listener(listener):
|
||||
|
|
|
@ -127,6 +127,7 @@ c.execute('''CREATE TABLE "listeners" (
|
|||
"module" text,
|
||||
"listener_type" text,
|
||||
"listener_category" text,
|
||||
"enabled" boolean,
|
||||
"options" blob
|
||||
)''')
|
||||
|
||||
|
|
Loading…
Reference in New Issue