def __init__(self, args=None): cmd.Cmd.__init__(self) # set up the event handling system dispatcher.connect(self.handle_event, sender=dispatcher.Any) # globalOptions[optionName] = (value, required, description) self.globalOptions = {} # currently active plugins: # {'pluginName': classObject} self.loadedPlugins = {} time.sleep(1) self.lock = threading.Lock() # pull out some common configuration information ( self.isroot, self.installPath, self.ipWhiteList, self.ipBlackList, self.obfuscate, self.obfuscateCommand ) = data_util.get_config( 'rootuser, install_path,ip_whitelist,ip_blacklist,obfuscate,obfuscate_command' ) # change the default prompt for the user self.prompt = '(Empire) > ' self.do_help.__func__.__doc__ = '''Displays the help menu.''' self.doc_header = 'Commands' # Main, Agents, or self.menu_state = 'Main' # parse/handle any passed command line arguments self.args = args # instantiate the agents, listeners, and stagers objects self.agents = agents.Agents(self, args=args) self.credentials = credentials.Credentials(self, args=args) self.stagers = stagers.Stagers(self, args=args) self.modules = modules.Modules(self, args=args) self.listeners = listeners.Listeners(self, args=args) self.users = users.Users(self) self.load_malleable_profiles() hooks_internal.initialize() self.socketio: Optional[SocketIO] = None self.resourceQueue = [] # A hashtable of autruns based on agent language self.autoRuns = {} self.startup_plugins() message = "[*] Empire starting up..." signal = json.dumps({'print': True, 'message': message}) dispatcher.send(signal, sender="empire")
def __init__(self, mainMenu, params=[]): self.info = { 'Name': 'HTTP[S]', 'Author': ['@harmj0y'], 'Description': ("Starts a 'foreign' http[s] Empire listener."), 'Category': ('client_server'), 'Comments': [] } # any options needed by the stager, settable during runtime self.options = { # format: # value_name : {description, required, default_value} 'Name': { 'Description': 'Name for the listener.', 'Required': True, 'Value': 'http_foreign' }, 'Host': { 'Description': 'Hostname/IP for staging.', 'Required': True, 'Value': "http://%s" % (helpers.lhost()) }, 'Port': { 'Description': 'Port for the listener.', 'Required': True, 'Value': '' }, 'Launcher': { 'Description': 'Launcher string.', 'Required': True, 'Value': 'powershell -noP -sta -w 1 -enc ' }, 'StagingKey': { 'Description': 'Staging key for initial agent negotiation.', 'Required': True, 'Value': '2c103f2c4ed1e59c0b4e2e01821770fa' }, 'DefaultDelay': { 'Description': 'Agent delay/reach back interval (in seconds).', 'Required': True, 'Value': 5 }, 'DefaultJitter': { 'Description': 'Jitter in agent reachback interval (0.0-1.0).', 'Required': True, 'Value': 0.0 }, 'DefaultLostLimit': { 'Description': 'Number of missed checkins before exiting', 'Required': True, 'Value': 60 }, 'DefaultProfile': { 'Description': 'Default communication profile for the agent.', 'Required': True, 'Value': "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko" }, 'KillDate': { 'Description': 'Date for the listener to exit (MM/dd/yyyy).', 'Required': False, 'Value': '' }, 'WorkingHours': { 'Description': 'Hours for the agent to operate (09:00-17:00).', 'Required': False, 'Value': '' }, 'SlackURL': { 'Description': 'Your Slack Incoming Webhook URL to communicate with your Slack instance.', 'Required': False, 'Value': '' } } # required: self.mainMenu = mainMenu self.threads = {} # optional/specific for this module self.app = None self.uris = [ a.strip('/') for a in self.options['DefaultProfile'] ['Value'].split('|')[0].split(',') ] # set the default staging key to the controller db default self.options['StagingKey']['Value'] = str( data_util.get_config('staging_key')[0])
def __init__(self, mainMenu, params=[]): self.info = { 'Name': 'Onedrive', 'Author': ['@mr64bit'], 'Description': ('Starts a Onedrive listener. Setup instructions here: gist.github.com/mr64bit/3fd8f321717c9a6423f7949d494b6cd9' ), 'Category': ('third_party'), 'Comments': [ "Note that deleting STAGE0-PS.txt from the staging folder will break existing launchers" ] } self.options = { 'Name': { 'Description': 'Name for the listener.', 'Required': True, 'Value': 'onedrive' }, 'ClientID': { 'Description': 'Application ID of the OAuth App.', 'Required': True, 'Value': '' }, 'ClientSecret': { 'Description': 'Client secret of the OAuth App.', 'Required': True, 'Value': '' }, 'AuthCode': { 'Description': 'Auth code given after authenticating OAuth App.', 'Required': True, 'Value': '' }, 'BaseFolder': { 'Description': 'The base Onedrive folder to use for comms.', 'Required': True, 'Value': 'empire' }, 'StagingFolder': { 'Description': 'The nested Onedrive staging folder.', 'Required': True, 'Value': 'staging' }, 'TaskingsFolder': { 'Description': 'The nested Onedrive taskings folder.', 'Required': True, 'Value': 'taskings' }, 'ResultsFolder': { 'Description': 'The nested Onedrive results folder.', 'Required': True, 'Value': 'results' }, 'Launcher': { 'Description': 'Launcher string.', 'Required': True, 'Value': 'powershell -noP -sta -w 1 -enc ' }, 'StagingKey': { 'Description': 'Staging key for intial agent negotiation.', 'Required': True, 'Value': 'asdf' }, 'PollInterval': { 'Description': 'Polling interval (in seconds) to communicate with Onedrive.', 'Required': True, 'Value': '5' }, 'DefaultDelay': { 'Description': 'Agent delay/reach back interval (in seconds).', 'Required': True, 'Value': 10 }, 'DefaultJitter': { 'Description': 'Jitter in agent reachback interval (0.0-1.0).', 'Required': True, 'Value': 0.0 }, 'DefaultLostLimit': { 'Description': 'Number of missed checkins before exiting', 'Required': True, 'Value': 10 }, 'DefaultProfile': { 'Description': 'Default communication profile for the agent.', 'Required': True, 'Value': "N/A|Microsoft SkyDriveSync 17.005.0107.0008 ship; Windows NT 10.0 (16299)" }, 'KillDate': { 'Description': 'Date for the listener to exit (MM/dd/yyyy).', 'Required': False, 'Value': '' }, 'WorkingHours': { 'Description': 'Hours for the agent to operate (09:00-17:00).', 'Required': False, 'Value': '' }, 'RefreshToken': { 'Description': 'Refresh token used to refresh the auth token', 'Required': False, 'Value': '' }, 'RedirectURI': { 'Description': 'Redirect URI of the registered application', 'Required': True, 'Value': "https://login.live.com/oauth20_desktop.srf" }, 'SlackURL': { 'Description': 'Your Slack Incoming Webhook URL to communicate with your Slack instance.', 'Required': False, 'Value': '' } } self.mainMenu = mainMenu self.threads = {} self.options['StagingKey']['Value'] = str( data_util.get_config('staging_key')[0])
def __init__(self, mainMenu, params=[]): self.info = { 'Name': 'HTTP[S] COM', 'Author': ['@harmj0y'], 'Description': ('Starts a http[s] listener (PowerShell only) that uses a GET/POST approach ' 'using a hidden Internet Explorer COM object. If using HTTPS, valid certificate required.' ), 'Category': ('client_server'), 'Comments': [] } # any options needed by the stager, settable during runtime self.options = { # format: # value_name : {description, required, default_value} 'Name': { 'Description': 'Name for the listener.', 'Required': True, 'Value': 'http_com' }, 'Host': { 'Description': 'Hostname/IP for staging.', 'Required': True, 'Value': "http://%s" % (helpers.lhost()) }, 'BindIP': { 'Description': 'The IP to bind to on the control server.', 'Required': True, 'Value': '0.0.0.0' }, 'Port': { 'Description': 'Port for the listener.', 'Required': True, 'Value': '' }, 'Launcher': { 'Description': 'Launcher string.', 'Required': True, 'Value': 'powershell -noP -sta -w 1 -enc ' }, 'StagingKey': { 'Description': 'Staging key for initial agent negotiation.', 'Required': True, 'Value': '2c103f2c4ed1e59c0b4e2e01821770fa' }, 'DefaultDelay': { 'Description': 'Agent delay/reach back interval (in seconds).', 'Required': True, 'Value': 5 }, 'DefaultJitter': { 'Description': 'Jitter in agent reachback interval (0.0-1.0).', 'Required': True, 'Value': 0.0 }, 'DefaultLostLimit': { 'Description': 'Number of missed checkins before exiting', 'Required': True, 'Value': 60 }, 'DefaultProfile': { 'Description': 'Default communication profile for the agent.', 'Required': True, 'Value': "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko" }, 'CertPath': { 'Description': 'Certificate path for https listeners.', 'Required': False, 'Value': '' }, 'KillDate': { 'Description': 'Date for the listener to exit (MM/dd/yyyy).', 'Required': False, 'Value': '' }, 'WorkingHours': { 'Description': 'Hours for the agent to operate (09:00-17:00).', 'Required': False, 'Value': '' }, 'RequestHeader': { 'Description': 'Cannot use Cookie header, choose a different HTTP request header for comms.', 'Required': True, 'Value': 'CF-RAY' }, 'Headers': { 'Description': 'Headers for the control server.', 'Required': True, 'Value': 'Server:Microsoft-IIS/7.5' }, 'SlackURL': { 'Description': 'Your Slack Incoming Webhook URL to communicate with your Slack instance.', 'Required': False, 'Value': '' } } # required: self.mainMenu = mainMenu self.threads = {} # optional/specific for this module self.app = None self.uris = [ a.strip('/') for a in self.options['DefaultProfile'] ['Value'].split('|')[0].split(',') ] # set the default staging key to the controller db default self.options['StagingKey']['Value'] = str( data_util.get_config('staging_key')[0]) # randomize the length of the default_response and index_page headers to evade signature based scans self.header_offset = random.randint(0, 64)
class RequestHandler(BaseHTTPRequestHandler): """ Main HTTP handler we're overwriting in order to modify the HTTPServer behavior. """ # retrieve the server headers from the common config serverVersion = data_util.get_config('server_version')[0] # fake out our server headers base BaseHTTPRequestHandler.server_version = serverVersion BaseHTTPRequestHandler.sys_version = "" def do_GET(self): # get the requested path and the client IP resource = self.path clientIP = self.client_address[0] sessionID = None cookie = self.headers.getheader("Cookie") if cookie: # search for a SESSIONID value in the cookie parts = cookie.split(";") for part in parts: if "SESSIONID" in part: # extract the sessionID value name, sessionID = part.split("=", 1) # fire off an event for this GET (for logging) message = "[*] {resource} requested from {session_id} at {client_ip}".format( resource=resource, session_id=sessionID, client_ip=clientIP ) signal = json.dumps({ 'print': True, 'message': message }) dispatcher.send(signal, sender="empire") # get the appropriate response from the agent handler (code, responsedata) = self.server.agents.process_get(self.server.server_port, clientIP, sessionID, resource) # write the response out self.send_response(code) self.end_headers() self.wfile.write(responsedata) self.wfile.flush() # self.wfile.close() # causes an error with HTTP comms def do_POST(self): resource = self.path clientIP = self.client_address[0] sessionID = None cookie = self.headers.getheader("Cookie") if cookie: # search for a SESSIONID value in the cookie parts = cookie.split(";") for part in parts: if "SESSIONID" in part: # extract the sessionID value name, sessionID = part.split("=", 1) # fire off an event for this POST (for logging) message = "[*] Post to {resource} from {session_id} at {client_ip}".format( resource=resource, session_id=sessionID, client_ip=clientIP ) signal = json.dumps({ 'print': True, 'message': message }) dispatcher.send(signal, sender="empire") # read in the length of the POST data if self.headers.getheader('content-length'): length = int(self.headers.getheader('content-length')) postData = self.rfile.read(length) # get the appropriate response for this agent (code, responsedata) = self.server.agents.process_post(self.server.server_port, clientIP, sessionID, resource, postData) # write the response out self.send_response(code) self.end_headers() self.wfile.write(responsedata) self.wfile.flush() # self.wfile.close() # causes an error with HTTP comms # supress all the stupid default stdout/stderr output def log_message(*arg): pass
def __init__(self, mainMenu, params=[]): self.info = { 'Name': 'Template', 'Author': ['@harmj0y'], 'Description': ("Listener template"), # categories - client_server, peer_to_peer, broadcast, third_party 'Category' : ('client_server'), 'Comments': [] } # any options needed by the stager, settable during runtime self.options = { # format: # value_name : {description, required, default_value} 'Name' : { 'Description' : 'Name for the listener.', 'Required' : True, 'Value' : 'http' }, 'Host' : { 'Description' : 'Hostname/IP for staging.', 'Required' : True, 'Value' : "http://%s" % (helpers.lhost()) }, 'BindIP' : { 'Description' : 'The IP to bind to on the control server.', 'Required' : True, 'Value' : '0.0.0.0' }, 'Port' : { 'Description' : 'Port for the listener.', 'Required' : True, 'Value' : '' }, 'Launcher' : { 'Description' : 'Launcher string.', 'Required' : True, 'Value' : 'powershell -noP -sta -w 1 -enc ' }, 'StagingKey' : { 'Description' : 'Staging key for initial agent negotiation.', 'Required' : True, 'Value' : '2c103f2c4ed1e59c0b4e2e01821770fa' }, 'DefaultDelay' : { 'Description' : 'Agent delay/reach back interval (in seconds).', 'Required' : True, 'Value' : 5 }, 'DefaultJitter' : { 'Description' : 'Jitter in agent reachback interval (0.0-1.0).', 'Required' : True, 'Value' : 0.0 }, 'DefaultLostLimit' : { 'Description' : 'Number of missed checkins before exiting', 'Required' : True, 'Value' : 60 }, 'DefaultProfile' : { 'Description' : 'Default communication profile for the agent.', 'Required' : True, 'Value' : "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko" }, 'CertPath' : { 'Description' : 'Certificate path for https listeners.', 'Required' : False, 'Value' : '' }, 'KillDate' : { 'Description' : 'Date for the listener to exit (MM/dd/yyyy).', 'Required' : False, 'Value' : '' }, 'WorkingHours' : { 'Description' : 'Hours for the agent to operate (09:00-17:00).', 'Required' : False, 'Value' : '' }, 'ServerVersion' : { 'Description' : 'Server header for the control server.', 'Required' : True, 'Value' : 'Microsoft-IIS/7.5' }, 'StagerURI' : { 'Description' : 'URI for the stager. Example: stager.php', 'Required' : False, 'Value' : '' }, 'UserAgent' : { 'Description' : 'User-agent string to use for the staging request (default, none, or other).', 'Required' : False, 'Value' : 'default' }, 'Proxy' : { 'Description' : 'Proxy to use for request (default, none, or other).', 'Required' : False, 'Value' : 'default' }, 'ProxyCreds' : { 'Description' : 'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).', 'Required' : False, 'Value' : 'default' }, 'SlackURL' : { 'Description' : 'Your Slack Incoming Webhook URL to communicate with your Slack instance.', 'Required' : False, 'Value' : '' } } # required: self.mainMenu = mainMenu self.threads = {} # used to keep track of any threaded instances of this server # optional/specific for this module # set the default staging key to the controller db default self.options['StagingKey']['Value'] = str(data_util.get_config('staging_key')[0])
def __init__(self, mainMenu, params=[]): self.info = { 'Name': 'HTTP[S] + MAPI', 'Author': ['@harmj0y', '@_staaldraad'], 'Description': ('Starts a http[s] listener (PowerShell) which can be used with Liniaal for C2 through Exchange' ), 'Category': ('client_server'), 'Comments': [ 'This requires the Liniaal agent to translate messages from MAPI to HTTP. More info: https://github.com/sensepost/liniaal' ] } # any options needed by the stager, settable during runtime self.options = { # format: # value_name : {description, required, default_value} 'Name': { 'Description': 'Name for the listener.', 'Required': True, 'Value': 'mapi' }, 'Host': { 'Description': 'Hostname/IP for staging.', 'Required': True, 'Value': "http://%s" % (helpers.lhost()) }, 'BindIP': { 'Description': 'The IP to bind to on the control server.', 'Required': True, 'Value': '0.0.0.0' }, 'Port': { 'Description': 'Port for the listener.', 'Required': True, 'Value': '' }, 'Launcher': { 'Description': 'Launcher string.', 'Required': True, 'Value': 'powershell -noP -sta -w 1 -enc ' }, 'StagingKey': { 'Description': 'Staging key for initial agent negotiation.', 'Required': True, 'Value': '2c103f2c4ed1e59c0b4e2e01821770fa' }, 'DefaultDelay': { 'Description': 'Agent delay/reach back interval (in seconds).', 'Required': True, 'Value': 0 }, 'DefaultJitter': { 'Description': 'Jitter in agent reachback interval (0.0-1.0).', 'Required': True, 'Value': 0.0 }, 'DefaultLostLimit': { 'Description': 'Number of missed checkins before exiting', 'Required': True, 'Value': 60 }, 'DefaultProfile': { 'Description': 'Default communication profile for the agent.', 'Required': True, 'Value': "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko" }, 'CertPath': { 'Description': 'Certificate path for https listeners.', 'Required': False, 'Value': '' }, 'KillDate': { 'Description': 'Date for the listener to exit (MM/dd/yyyy).', 'Required': False, 'Value': '' }, 'WorkingHours': { 'Description': 'Hours for the agent to operate (09:00-17:00).', 'Required': False, 'Value': '' }, 'Headers': { 'Description': 'Headers for the control server.', 'Required': True, 'Value': 'Server:Microsoft-IIS/7.5' }, 'Folder': { 'Description': 'The hidden folder in Exchange to user', 'Required': True, 'Value': 'Liniaal' }, 'Email': { 'Description': 'The email address of our target', 'Required': False, 'Value': '' }, 'SlackURL': { 'Description': 'Your Slack Incoming Webhook URL to communicate with your Slack instance.', 'Required': False, 'Value': '' } } # required: self.mainMenu = mainMenu self.threads = {} # optional/specific for this module self.app = None self.uris = [ a.strip('/') for a in self.options['DefaultProfile'] ['Value'].split('|')[0].split(',') ] # set the default staging key to the controller db default self.options['StagingKey']['Value'] = str( data_util.get_config('staging_key')[0])
def __init__(self, mainMenu, params=[]): self.info = { "Name": "HTTP[S]", "Author": ["@harmj0y"], "Description": ("Starts a 'foreign' http[s] Empire listener."), "Category": ("client_server"), "Comments": [], } # any options needed by the stager, settable during runtime self.options = { # format: # value_name : {description, required, default_value} "Name": { "Description": "Name for the listener.", "Required": True, "Value": "http_foreign", }, "Host": { "Description": "Hostname/IP for staging.", "Required": True, "Value": "http://%s" % (helpers.lhost()), }, "Port": { "Description": "Port for the listener.", "Required": True, "Value": "", }, "Launcher": { "Description": "Launcher string.", "Required": True, "Value": "powershell -noP -sta -w 1 -enc ", }, "StagingKey": { "Description": "Staging key for initial agent negotiation.", "Required": True, "Value": "2c103f2c4ed1e59c0b4e2e01821770fa", }, "DefaultDelay": { "Description": "Agent delay/reach back interval (in seconds).", "Required": True, "Value": 5, }, "DefaultJitter": { "Description": "Jitter in agent reachback interval (0.0-1.0).", "Required": True, "Value": 0.0, }, "DefaultLostLimit": { "Description": "Number of missed checkins before exiting", "Required": True, "Value": 60, }, "DefaultProfile": { "Description": "Default communication profile for the agent.", "Required": True, "Value": "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko", }, "KillDate": { "Description": "Date for the listener to exit (MM/dd/yyyy).", "Required": False, "Value": "", }, "WorkingHours": { "Description": "Hours for the agent to operate (09:00-17:00).", "Required": False, "Value": "", }, "SlackURL": { "Description": "Your Slack Incoming Webhook URL to communicate with your Slack instance.", "Required": False, "Value": "", }, } # required: self.mainMenu = mainMenu self.threads = {} # optional/specific for this module self.app = None self.uris = [ a.strip("/") for a in self.options["DefaultProfile"] ["Value"].split("|")[0].split(",") ] # set the default staging key to the controller db default self.options["StagingKey"]["Value"] = str( data_util.get_config("staging_key")[0])
def __init__(self, mainMenu, params=[]): self.info = { "Name": "HTTP[S] COM", "Author": ["@harmj0y"], "Description": ( "Starts a http[s] listener (PowerShell only) that uses a GET/POST approach " "using a hidden Internet Explorer COM object. If using HTTPS, valid certificate required." ), "Category": ("client_server"), "Comments": [], } # any options needed by the stager, settable during runtime self.options = { # format: # value_name : {description, required, default_value} "Name": { "Description": "Name for the listener.", "Required": True, "Value": "http_com", }, "Host": { "Description": "Hostname/IP for staging.", "Required": True, "Value": "http://%s" % (helpers.lhost()), }, "BindIP": { "Description": "The IP to bind to on the control server.", "Required": True, "Value": "0.0.0.0", }, "Port": { "Description": "Port for the listener.", "Required": True, "Value": "", }, "Launcher": { "Description": "Launcher string.", "Required": True, "Value": "powershell -noP -sta -w 1 -enc ", }, "StagingKey": { "Description": "Staging key for initial agent negotiation.", "Required": True, "Value": "2c103f2c4ed1e59c0b4e2e01821770fa", }, "DefaultDelay": { "Description": "Agent delay/reach back interval (in seconds).", "Required": True, "Value": 5, }, "DefaultJitter": { "Description": "Jitter in agent reachback interval (0.0-1.0).", "Required": True, "Value": 0.0, }, "DefaultLostLimit": { "Description": "Number of missed checkins before exiting", "Required": True, "Value": 60, }, "DefaultProfile": { "Description": "Default communication profile for the agent.", "Required": True, "Value": "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko", }, "CertPath": { "Description": "Certificate path for https listeners.", "Required": False, "Value": "", }, "KillDate": { "Description": "Date for the listener to exit (MM/dd/yyyy).", "Required": False, "Value": "", }, "WorkingHours": { "Description": "Hours for the agent to operate (09:00-17:00).", "Required": False, "Value": "", }, "RequestHeader": { "Description": "Cannot use Cookie header, choose a different HTTP request header for comms.", "Required": True, "Value": "CF-RAY", }, "Headers": { "Description": "Headers for the control server.", "Required": True, "Value": "Server:Microsoft-IIS/7.5", }, "SlackURL": { "Description": "Your Slack Incoming Webhook URL to communicate with your Slack instance.", "Required": False, "Value": "", }, } # required: self.mainMenu = mainMenu self.threads = {} # optional/specific for this module self.app = None self.uris = [ a.strip("/") for a in self.options["DefaultProfile"]["Value"].split("|")[0].split(",") ] # set the default staging key to the controller db default self.options["StagingKey"]["Value"] = str( data_util.get_config("staging_key")[0] ) # randomize the length of the default_response and index_page headers to evade signature based scans self.header_offset = random.randint(0, 64)
def __init__(self, mainMenu, params=[]): self.info = { "Name": "Template", "Author": ["@harmj0y"], "Description": ("Listener template"), # categories - client_server, peer_to_peer, broadcast, third_party "Category": ("client_server"), "Comments": [], } # any options needed by the stager, settable during runtime self.options = { # format: # value_name : {description, required, default_value} "Name": { "Description": "Name for the listener.", "Required": True, "Value": "http", }, "Host": { "Description": "Hostname/IP for staging.", "Required": True, "Value": "http://%s" % (helpers.lhost()), }, "BindIP": { "Description": "The IP to bind to on the control server.", "Required": True, "Value": "0.0.0.0", }, "Port": { "Description": "Port for the listener.", "Required": True, "Value": "", }, "Launcher": { "Description": "Launcher string.", "Required": True, "Value": "powershell -noP -sta -w 1 -enc ", }, "StagingKey": { "Description": "Staging key for initial agent negotiation.", "Required": True, "Value": "2c103f2c4ed1e59c0b4e2e01821770fa", }, "DefaultDelay": { "Description": "Agent delay/reach back interval (in seconds).", "Required": True, "Value": 5, }, "DefaultJitter": { "Description": "Jitter in agent reachback interval (0.0-1.0).", "Required": True, "Value": 0.0, }, "DefaultLostLimit": { "Description": "Number of missed checkins before exiting", "Required": True, "Value": 60, }, "DefaultProfile": { "Description": "Default communication profile for the agent.", "Required": True, "Value": "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko", }, "CertPath": { "Description": "Certificate path for https listeners.", "Required": False, "Value": "", }, "KillDate": { "Description": "Date for the listener to exit (MM/dd/yyyy).", "Required": False, "Value": "", }, "WorkingHours": { "Description": "Hours for the agent to operate (09:00-17:00).", "Required": False, "Value": "", }, "ServerVersion": { "Description": "Server header for the control server.", "Required": True, "Value": "Microsoft-IIS/7.5", }, "StagerURI": { "Description": "URI for the stager. Example: stager.php", "Required": False, "Value": "", }, "UserAgent": { "Description": "User-agent string to use for the staging request (default, none, or other).", "Required": False, "Value": "default", }, "Proxy": { "Description": "Proxy to use for request (default, none, or other).", "Required": False, "Value": "default", }, "ProxyCreds": { "Description": "Proxy credentials ([domain\]username:password) to use for request (default, none, or other).", "Required": False, "Value": "default", }, "SlackURL": { "Description": "Your Slack Incoming Webhook URL to communicate with your Slack instance.", "Required": False, "Value": "", }, } # required: self.mainMenu = mainMenu self.threads = { } # used to keep track of any threaded instances of this server # optional/specific for this module # set the default staging key to the controller db default self.options["StagingKey"]["Value"] = str( data_util.get_config("staging_key")[0])
def __init__(self, mainMenu, params=[]): self.info = { "Name": "Onedrive", "Author": ["@mr64bit"], "Description": ( "Starts a Onedrive listener. Setup instructions here: gist.github.com/mr64bit/3fd8f321717c9a6423f7949d494b6cd9" ), "Category": ("third_party"), "Comments": [ "Note that deleting STAGE0-PS.txt from the staging folder will break existing launchers" ], } self.options = { "Name": { "Description": "Name for the listener.", "Required": True, "Value": "onedrive", }, "ClientID": { "Description": "Application ID of the OAuth App.", "Required": True, "Value": "", }, "ClientSecret": { "Description": "Client secret of the OAuth App.", "Required": True, "Value": "", }, "AuthCode": { "Description": "Auth code given after authenticating OAuth App.", "Required": True, "Value": "", }, "BaseFolder": { "Description": "The base Onedrive folder to use for comms.", "Required": True, "Value": "empire", }, "StagingFolder": { "Description": "The nested Onedrive staging folder.", "Required": True, "Value": "staging", }, "TaskingsFolder": { "Description": "The nested Onedrive taskings folder.", "Required": True, "Value": "taskings", }, "ResultsFolder": { "Description": "The nested Onedrive results folder.", "Required": True, "Value": "results", }, "Launcher": { "Description": "Launcher string.", "Required": True, "Value": "powershell -noP -sta -w 1 -enc ", }, "StagingKey": { "Description": "Staging key for intial agent negotiation.", "Required": True, "Value": "asdf", }, "PollInterval": { "Description": "Polling interval (in seconds) to communicate with Onedrive.", "Required": True, "Value": "5", }, "DefaultDelay": { "Description": "Agent delay/reach back interval (in seconds).", "Required": True, "Value": 10, }, "DefaultJitter": { "Description": "Jitter in agent reachback interval (0.0-1.0).", "Required": True, "Value": 0.0, }, "DefaultLostLimit": { "Description": "Number of missed checkins before exiting", "Required": True, "Value": 10, }, "DefaultProfile": { "Description": "Default communication profile for the agent.", "Required": True, "Value": "N/A|Microsoft SkyDriveSync 17.005.0107.0008 ship; Windows NT 10.0 (16299)", }, "KillDate": { "Description": "Date for the listener to exit (MM/dd/yyyy).", "Required": False, "Value": "", }, "WorkingHours": { "Description": "Hours for the agent to operate (09:00-17:00).", "Required": False, "Value": "", }, "RefreshToken": { "Description": "Refresh token used to refresh the auth token", "Required": False, "Value": "", }, "RedirectURI": { "Description": "Redirect URI of the registered application", "Required": True, "Value": "https://login.live.com/oauth20_desktop.srf", }, "SlackURL": { "Description": "Your Slack Incoming Webhook URL to communicate with your Slack instance.", "Required": False, "Value": "", }, } self.mainMenu = mainMenu self.threads = {} self.options["StagingKey"]["Value"] = str( data_util.get_config("staging_key")[0] )