def createContainer(self, args): ''' Create a VeraCrypt container with vairous parameters :param args: contains the parameters for creating the container :return: ''' # implementation self.logger.info("creating veracrypt container") ad = ph.base64unpickle(args) ################ path = ad["path"] size = ad["size"] password = ad["password"] hash = ad["hash"] encryption = ad["encryption"] filesystem = ad["filesystem"] executable = ad["executable"] ################# #cmd = '"C:\\Program Files\\VeraCrypt\\VeraCrypt Format.exe" /create ' + path + ' /password ' + password + ' /hash ' + hash + ' /encryption ' + encryption + ' /filesystem ' + filesystem + ' /size ' + size + ' /force /quit preferences /silent"' cmd = executable + ' /create ' + path + ' /password ' + password + ' /hash ' + hash + ' /encryption ' + encryption + ' /filesystem ' + filesystem + ' /size ' + size + ' /force /quit preferences /silent"' try: f = open("C:\\Users\\Bill\\Documents\\container.txt", "w+") f.write("%s\r\n" % password) f.close() #run command line #caution, shell=True can be an issue if input is untrusted subprocess.call(cmd, shell=True) self.logger.info("container successfully created") except Exception as e: self.logger.error("creating container failed: " + lineno() + ' ' + str(e))
def smbCopy(self, guest_source_path, smb_target_path, user, passw): """ Copies file from guest to smb share. :param guest_source_path: source path on guest :param smb_target_path: target path on smb :param user: smb user :param passw: pass """ try: #msg = base64.b64encode(guest_source_path) + " " + base64.b64encode(smb_target_path) + " " + base64.b64encode(user) + " " + base64.b64encode(passw) msg = { "guest_source_path": guest_source_path, "smb_target_path": smb_target_path, "user": user, "passw": passw } pcl_msg = ph.base64pickle(msg) self.window_id = self.guest_obj.current_window_id self.guest_obj.send("application " + "fileTransfer " + str(self.window_id) + " smbCopy " + pcl_msg) self.guest_obj.current_window_id += 1 except Exception as e: raise Exception(lineno() + " Error: fileTransferVmmSide::__init__ " + self.guest_obj.guestname + " " + str(e))
def onRegister(self, com, socket): # - Extract network information from command-message ip_internet = com[1] ip_local = com[2] mac = com[3] iface_internet = com[4] iface_local = com[5] guest = self.findGuestForMAC(mac) # - hand over socket control to guest try: self.logger.debug("start recv thread for guest:" + guest.guestname) guest.socket = socket guest.ip_local = ip_local guest.ip_internet = ip_internet guest.iface_internet = iface_internet guest.iface_local = iface_local guest.thread = threading.Thread(target=guest.recv_thread) guest.thread.setDaemon(True) guest.thread.start() guest.state = "connected" except Exception as e: # print "Error: unable to start thread" + str(e) raise Exception( str(lineno()) + " " + "Vmm::listener for " + mac + " failed:", str(e))
def __init__(self, guest_obj, args): """Set default attribute values only. @param guest_obj: The guest on which this application is running. (will be inserted from guest::application()) @param args: containing logger: Logger name for logging. """ try: super(VeraCryptWrapperVmmSide, self).__init__(guest_obj, args) self.logger.info("function: VeraCryptWrapperVmmSide::__init__") self.window_id = None except Exception as e: raise Exception(lineno() + " Error: VeraCryptWrapperHostSide::__init__ " + self.guest_obj.guestname + " " + str(e))
def onReceive(self, socket): """ This tread will be opened for the guest life time. If a message is received, doRecvCommand will process it. """ try: msg = "" # try long as there are unfinished received commands isRegistered = False while not isRegistered: chunk = socket.recv(1024) if chunk == '': raise RuntimeError("socket connection broken") # get length of the message msg = msg + chunk # if msg do not contain the message length if len(msg) < 8: print "half command" continue messagesize = int(msg[0:8], 16) if len(msg) < (messagesize + 8): print "half command with messagesize" continue # get the commands out of the message while len(msg) >= (messagesize + 8): # if the command fit into message, return the command list commands if len(msg) == messagesize + 8: isRegistered = self.onRecvCommand( msg[8:(messagesize + 8)], socket) msg = "" break # there are multiple commands in message else: command = msg[8:(messagesize + 8)] msg = msg[(messagesize + 8):] if len(msg) < (messagesize + 8): continue messagesize = int(msg[0:8], 16) isRegistered = self.onRecvCommand(command, socket) except Exception as e: raise Exception(lineno() + " " + "guest::startrecv ->" + " failed:" + str(e))
def listener(self): """Starts a listen socket for the lifetime of the vmm object. This socket gets all first requests from the guests. Based on the ip, the socket will be hand over to the guests recvThread. """ self.logger.debug("Vmm::listener ") try: while 1: # accept connections from outside client_socket, (ip_address, port) = self.server_socket.accept() # find the connected machine and update the state self.onReceive(client_socket) except Exception as e: raise Exception(lineno() + " " + "Vmm::listener failed:" + str(e))
def dismountContainer(self, args): ''' Dismounting a container to finish the operations of VeraCrypt :param args: executable = path to veracrypt.exe; mount_point = drive letter of container to be dismounted. :return: ''' self.logger.info("unmount container") ad = ph.base64unpickle(args) ################ executable = ad["executable"] mount_point = ad["mount_point"] ################ cmd = executable + ' /q /d ' + mount_point try: subprocess.call(cmd, shell=True) self.logger.info("container successfully dismounted") except Exception as e: self.logger.error("dismounting container failed: " + lineno() + ' ' + str(e))
def copyToContainer(self, args): ''' Copy a file from a specific path to a specific path :param args: holding src as source path of file to be copied and dst as destination where file should be saved. :return: ''' self.logger.info("copy to container") ad = ph.base64unpickle(args) ################ src = ad["src"] dst = ad["dst"] ################ try: copyfile(src, dst) os.remove(src) self.logger.info("File successfully copied to encrypted container") except Exception as e: self.logger.error("copying to container failed: " + lineno() + ' ' + str(e))
def __init__(self, guest_obj, args): """Set default attribute values only. @param guest_obj: The guest on which this browser is running. (will be inserted from guest::application()) @param args: containing web_browser : Type of the webBrowser (currently firefox is tested). logger: Logger name for logging. """ try: super(WebBrowserVmmSide, self).__init__(guest_obj, args) self.logger.info("function: WebBrowserVmmSide::__init__") # surf the url through the socket. self.webBrowser = args['webBrowser'] # the current link which was surfed self.url = None self.window_id = None except Exception as e: raise Exception( lineno() + " Error: webBrowserHostSide::__init__ " + self.guest_obj.guestname + " " + str(e))
def set_config(self, jabber_id, password): """set_config will create the jabber profile. @param jabber_id: jabber id, like [email protected]. @param password: password to xmpp account. @return: No return value. """ try: self.logger.info("function: InstantMessengerVmmSide::set_config") # create for every parameter a length value, which will be transmitted self.window_id = self.guest_obj.current_window_id self.guest_obj.current_window_id += 1 set_config_command = "application instantMessenger " + str(self.window_id) + " set_config " + \ "%.8x" % len(jabber_id) + jabber_id + \ "%.8x" % len(password) + password self.guest_obj.send(set_config_command) except Exception as e: raise Exception(lineno() + " error InstantMessengerVmmSide:set_config()" + str(e))
def addUser(self, args): """add User to guest""" self.logger.info(self.__class__.__name__ + "::addUser ") ad = ph.base64unpickle(args) ################ user = ad["usr_name"] password = ad["password"] ################# if platform.system() == "Windows": cmd = base64.b64encode('net user ' + user + ' ' + password + ' /ADD') try: self.agent_object.do_command("runElevated " + cmd) except Exception as e: self.logger.error("adding user failed: " + lineno() + ' ' + str(e)) else: self.logger.error( "Unknown System Platform, only Windows is supported at the moment" )
def deploy(self, args): """ Starts the deployment process by executing the setup.py from the cd drive. return: Send to the host in the known to be good state: 'application <Deployer> window_id open'. 'application <Deployer> window_id ready'. in the error state: 'application <Deployer> window_id error'. """ try: arguments = args.split(" ") # installationPath = arguments[0] self.logger.info("function: Deployer::open") self.logger.debug( "Deployment process starts now -> execute setup.py") if self.agent_object.operatingSystem == "windows": subprocess.call(['python', 'D:\\\\setup.py']) elif self.agent_object.operatingSystem == "linux": subprocess.call(['python', '/media/hystck/CDROM/setup.py']) else: raise Exception( lineno() + " Error: DeployerGuestSide::__deploy__ unkown operating system: " + self.agent_object.operatingSystem) self.agent_object.send("application " + self.module_name + " ready") except Exception as e: self.agent_object.send("application " + self.module_name + " error") self.logger.error("Deployer::open: " + str(e)) return
def download_from(self, args): """ This function will download something from url where selector will be the selector of the download button At the moment it will only work if the file type is set to automatic download in firefox on the base image. Added by Thomas Schaefer in 2019 :param url: website where we want to download from :param selector: css selector of the download button :return: """ try: arguments = args.split(" ") url = arguments[0] selector = arguments[1] self.last_driven_url = url self.logger.info("downloading from: " + url + "; With the selector: " + selector) self.helper.navigate_to_url(url) self.helper.click_element_by_id(selector) self.window_is_crushed = False except Exception as e: self.window_is_crushed = True self.logger.error("Error: " + lineno() + " " + str(e))
def mountContainer(self, args): ''' Mounting a VeraCrypt container to a given moint point. :param args: containing the parameters for mounting the container like the path to the container, password, veracrypt executable and mount point :return: ''' self.logger.info("mounting veracrypt container") ad = ph.base64unpickle(args) ################ path = ad["path"] password = ad["password"] executable = ad["executable"] mount_point = ad["mount_point"] ################ #veracrypt /v myvolume.tc /l x /a /p MyPassword /e /b #cmd = '"C:\\Program Files\\VeraCrypt\\VeraCrypt.exe" /v ' + path + ' /l x /a /p ' + password + ' /e /q' cmd = executable + ' /v ' + path + ' /l ' + mount_point + ' /a /p ' + password + ' /e /q' try: subprocess.call(cmd, shell=True) self.logger.info("container successfully mounted") except Exception as e: self.logger.error("mounting container failed: " + lineno() + ' ' + str(e))
def receive_commands(self): """Starts a listen socket for the lifetime of the pidgin object. This socket gets all requests from the pidgin plugin. Receive messages in form of: --------------------------------------------------------------------------------------------- | full | amount | offset c | offset p1 | .. | offset pn | command | param 1 | .. | param n | | length | offsets| | | .. | | | | .. | | --------------------------------------------------------------------------------------------- Currently each length field is encoded as interger32 full length: Describe the full length of the command amount offsets: Here are the amount of all offsets. offset x: Every begin of command or param can be accesses using an offset. command: the command to execute (get_contact_list, send_msg_to...). param x: parameter for the command. """ try: self.logger.info("function: InstantMessengerGuestSide::receive_commands") while 1: self.logger.debug("check recv on plugin_socket!") full_length_binary = recvall(self.plugin_socket, 4) if full_length_binary is None: self.logger.error("pidgin plugin socket Error!") continue self.logger.debug("GOT command from plugin") print ":".join("{:02x}".format(ord(c)) for c in full_length_binary) full_length = struct.unpack('>I', full_length_binary)[0] self.logger.debug("full length: " + str(full_length)) # counter for rest in socket rest_in_socket = int(full_length) - 4 self.logger.debug("get amount offsets") amount_offsets_binary = recvall(self.plugin_socket, 4) rest_in_socket -= 4 amount_offsets = struct.unpack('>I', amount_offsets_binary)[0] self.logger.debug("amount offsets: " + str(amount_offsets)) # create data with keeps complete socket message data = full_length_binary + amount_offsets_binary offset_binary_list = [] offset_list = [] for i in range(amount_offsets): self.logger.debug("InstantMessengerGuestSide::receive_commands: rest_in_socket: " + str(rest_in_socket)) self.logger.debug("InstantMessengerGuestSide::receive_commands: sock recv 4 bytes") offset_binary = recvall(self.plugin_socket, 4) rest_in_socket -= 4 self.logger.debug("InstantMessengerGuestSide::receive_commands: reduced rest_in_socket by 4: " + str(rest_in_socket)) offset = struct.unpack('>I', offset_binary)[0] data += offset_binary # add offsets to list offset_binary_list.append(offset_binary) offset_list.append(offset) self.logger.debug("InstantMessengerGuestSide::receive_commands: rest in socket: " + str(rest_in_socket)) # get commands from socket command_params = recvall(self.plugin_socket, rest_in_socket) # create command with knowledge of all offsets data += command_params self.logger.debug("InstantMessengerGuestSide::receive_commands: offset extraction finished") self.logger.debug("InstantMessengerGuestSide::receive_commands: complete string from socket: " + data) command = "" param_list = [] for i in range(amount_offsets): if i == 0: command = data[offset_list[i]:offset_list[i + 1] - 1] # get command without '\0' elif i == amount_offsets - 1: param_list.append(data[offset_list[i]:len(data) - 1]) # get last param without '\0' else: param_list.append(data[offset_list[i]:offset_list[i + 1] - 1]) # get param without '\0' self.logger.debug("InstantMessengerGuestSide::receive_commands: extracted command: " + str(command)) for param in param_list: self.logger.debug("extraced param: " + str(param)) self.logger.debug("parsing information from socket is finished.") # # receive_msg status buddy msg # example: receive event [email protected] "Hi this is guest1" if command == "receive_msg": self.logger.debug("command receive_msg received:") for i in range(len(param_list)): self.logger.debug("receive_msg with param:" + param_list[i]) self.agent_object.send("application " + self.module_name + " " + str(self.imParent.window_id) + " receive_msg " + param_list[0] + " " + param_list[1]) elif command == "get_info": self.logger.debug("command get_info received:") for i in range(len(param_list)): self.logger.debug("get_info with param:" + param_list[i]) self.agent_object.send("application " + self.module_name + " " + str(self.imParent.window_id) + " get_info " + param_list[0]) elif command == "send_msg_to": self.logger.debug("command send_msg_to received:") for i in range(len(param_list)): self.logger.debug("send_msg_to with param:" + param_list[i]) self.agent_object.send("application " + self.module_name + " " + str(self.imParent.window_id) + " send_msg_to " + param_list[0]) elif command == "get_contact_list": self.logger.debug("command get_contact_list received:") for i in range(len(param_list)): self.logger.debug("get_contact_list with param:" + param_list[i]) self.agent_object.send("application " + self.module_name + " " + str(self.imParent.window_id) + " get_contact_list " + " ".join(param_list)) else: raise Exception(lineno() + " command " + command + " not found!") except Exception as e: raise Exception(lineno() + " " + "InstantMessengerGuestSide::receive_commands failed:" + str(e))