def editOne(self, scenario_json): """ Edits a current scenario with a JSON file :param scenario_json: JSON file with the new scenario :return: Response object containing the status of the request """ response = Response() print(scenario_json) scenario_name = scenario_json["scenario_name"] if scenario_name in self.scenarios_dict: if "machines" in scenario_json: for machine in scenario_json["machines"]: if scenario_json["machines"][machine]["uuid"] == "": new_uuid = uuid.uuid4() new_uuid = str(new_uuid).replace('-', '') print("Unique id: ", new_uuid) scenario_json['machines'][machine]['uuid'] = new_uuid scenario_json = Scenario(scenario_name).objectFromDictionary( scenario_json) self.scenarios_dict[scenario_name] = scenario_json #self._saveScenarioAsJSON(new_scenario) self.db_manager.editScenario(scenario_json.dictionary().copy()) response.setResponse(True) response.setBody(self.scenarios_dict[scenario_name].dictionary()) else: response.setReason('Scenario doesn\'t exist') response.setResponse(False) response.setBody(dict()) return response.dictionary()
def sendCommand(self, scenario_name, machine_name, command, default_timeout=5, show_output=True): """ Sends a command to a virtual machine. :param scenario_name: Scenario's name string :param machine_name: Machine's name string :param command: Command to be executed :param default_timeout: Timeout for executing the command :param show_output: Boolean to show an output :return: Response object containing the status of the request """ response = Response() scenario = db_manager.getScenario(scenario_name) return_code = '' if scenario: scenario_json = scenario[0] #First we need to move to the directory of the given machine machine_uuid = scenario_json["machines"][machine_name]["uuid"] machine_path = file_manager.getScenariosPath( ) / scenario_name / "Machines" / machine_uuid #using "vagrant ssh -c 'command' <machine>" will only try to execute that command and return, CHANGE THIS connect_command = "vagrant ssh -c '{}' {}".format( command, machine_uuid) sshProcess = subprocess.Popen(connect_command, cwd=machine_path, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, shell=True, bufsize=0) #wait for the execution to finish, process running on different shell sshProcess.wait() sshProcess.stdin.close() return_code = sshProcess.returncode if show_output: for line in sshProcess.stdout: if line == "END\n": break print(line, end="") for line in sshProcess.stdout: if line == "END\n": break print(line, end="") else: response.setResponse(False) response.setReason('Scenario doesn\'t exist') return return_code
def getAll(self): """ Gets the available exploits :return: Response object containing the status of the request """ # Variables exploits_dict = { "exploits": [self.exploits_dict[e].name for e in self.exploits_dict] } response = Response() response.setResponse(True) response.setBody(exploits_dict) return response.dictionary()
def getOne(self, exploit_name): """ Gets the scenario as a JSON file :param exploit_name: Exploit's name string :return: Response object containing the status of the request """ response = Response() if exploit_name in self.exploits_dict: response.setResponse(True) response.setBody(self.exploits_dict[exploit_name].dictionary()) else: response.setResponse(False) response.setReason('Exploit doesn\'t exist') response.setBody(dict()) return response.dictionary()
def getOne(self, scenario_name): """ Gets the scenario as a JSON file :param scenario_name: String with the scenario name :return: Response object containing the status of the request """ response = Response() if scenario_name in self.scenarios_dict: response.setResponse(True) response.setBody(self.scenarios_dict[scenario_name].dictionary()) else: response.setResponse(False) response.setReason('Scenario doesn\'t exist') response.setBody(dict()) return response.dictionary()
def testNetworkPing(self, scenario_name, machine_name, destination_machine_name, count=1): """ Tests connection between the host and a virtual machine. :param scenario_name: Scenario's name string :param machine_name: Machine's name string :param destination_machine_name: Machine's to be pinged :param count: Counter used in the ping command :return: Response object containing the status of the request """ response = Response() scenario = db_manager.getOne(scenario_name) if scenario: scenario_data = scenario[0] try: machines = scenario_data['machines'] machine_to_ping = machines[destination_machine_name] machine_to_ping_network_settings = machine_to_ping[ 'network_settings'] destination_ip = machine_to_ping_network_settings['ip_address'] ping_command = "ping -c {} {}".format(count, destination_ip) return_code = self.sendCommand(scenario_name, machine_name, ping_command) if return_code == 0: print("Ping Successfully") response.setResponse(True) response.setReason("Ping Successfully") elif return_code == 1: print("No answer from %s" % destination_machine_name) response.setResponse(False) response.setReason("No answer from %s" % destination_machine_name) else: print("Another error has occurred") response.setResponse(False) response.setReason("Another error has occurred") except KeyError: print("Machines not defined for this Scenario") response.setResponse(False) response.setReason("Machines not defined for this Scenario") else: print("Scenario %s not found" % scenario_name) response.setResponse(False) response.setReason("Scenario %s not found" % scenario_name) return response.dictionary()
def getAll(self): """ Gets the available scenarios :return: Response object containing the status of the request """ # Variables scenarios_dict = { "scenarios": [ self.scenarios_dict[s].scenario_name for s in self.scenarios_dict ] } response = Response() response.setResponse(True) response.setBody(scenarios_dict) return response.dictionary()
def getOne(self, vulnerability_name): """ Gets the scenario as a JSON file :param vulnerability_name: VUlnerability's name string :return: Response object containing the status of the request """ response = Response() if vulnerability_name in self.vulnerabilities_dict: response.setResponse(True) response.setBody( self.vulnerabilities_dict[vulnerability_name].dictionary()) else: response.setResponse(False) response.setReason('Vulnerability doesn\'t exist') response.setBody(dict()) return response.dictionary()
def getAll(self): """ Gets the available exploits :return: Response object containing the status of the request """ # Variables vulnerabilities_dict = { "vulnerabilities": [ self.vulnerabilities_dict[v].name for v in self.vulnerabilities_dict ] } response = Response() response.setResponse(True) response.setBody(vulnerabilities_dict) return response.dictionary()
def deleteOne(self, exploit_name): """ Deletes an exploit from the database. :param exploit_name: Exploit's name string :return: Response object containing the status of the request """ response = Response() if exploit_name in self.exploits_dict: deleted_exploit = self.exploits_dict.pop(exploit_name) self.db_manager.deleteExploit(exploit_name) response.setResponse(True) response.setBody(deleted_exploit.dictionary()) else: response.setResponse(False) response.setReason('Exploit doesn\'t exist') response.setBody(dict()) return response.dictionary()
def deleteOne(self, scenario_name): """ Deletes one scenario from the database. :param scenario_name: Scenario's name string :return: Response object containing the status of the request """ response = Response() if scenario_name in self.scenarios_dict: deleted_scenario = self.scenarios_dict.pop(scenario_name) #self.file_manager.deleteScenariosFolder(scenario_name) self.db_manager.deleteScenario(scenario_name) response.setResponse(True) response.setBody(deleted_scenario.dictionary()) else: response.setResponse(False) response.setReason('Scenario doesn\'t exist') response.setBody(dict()) return response.dictionary()
def newEmpty(self, exploit_name): """ Creates a new exploit which includes the folders and the exploit JSON file :param exploit_name: String with the exploit name :return: Response object containing the status of the request """ response = Response() if exploit_name not in self.exploits_dict: exploit = Exploit(exploit_name) self.exploits_dict[exploit_name] = exploit self.db_manager.insertExploit(exploit.dictionary().copy()) response.setResponse(True) response.setBody(exploit.dictionary()) else: response.setResponse(False) response.setReason('Exploit already exist') response.setBody(dict()) return response.dictionary()
def deleteOne(self, vulnerability_name): """ Deletes a vulnerability from the database. :param vulnerability_name: Vulnerability's name string :return: Response object containing the status of the request """ response = Response() if vulnerability_name in self.vulnerabilities_dict: deleted_vulnerability = self.vulnerabilities_dict.pop( vulnerability_name) self.db_manager.deleteVulnerability(vulnerability_name) response.setResponse(True) response.setBody(deleted_vulnerability.dictionary()) else: response.setResponse(False) response.setReason('Vulnerability doesn\'t exist') response.setBody(dict()) return response.dictionary()
def newEmpty(self, vulnerability_name): """ Creates a new vulnerability which includes the folders and the vulnerability JSON file :param vulnerability_name: String with the vulnerability name :return: Response object containing the status of the request """ response = Response() if vulnerability_name not in self.vulnerabilities_dict: vulnerability = Vulnerability(vulnerability_name) self.vulnerabilities_dict[vulnerability_name] = vulnerability self.db_manager.insertVulnerability( vulnerability.dictionary().copy()) response.setResponse(True) response.setBody(vulnerability.dictionary()) else: response.setResponse(False) response.setReason('Vulnerability already exist') response.setBody(dict()) return response.dictionary()
def editOne(self, exploit_json): """ Edits a current scenario with a JSON file :param exploit_json: JSON file with the exploit's data :return: Response object containing the status of the request """ response = Response() print(exploit_json) exploit_name = exploit_json["name"] if exploit_name in self.exploits_dict: exploit_json = Exploit().objectFromDictionary(exploit_json) self.exploits_dict[exploit_name] = exploit_json self.db_manager.editExploit(exploit_json.dictionary().copy()) response.setResponse(True) response.setBody(self.exploits_dict[exploit_name].dictionary()) else: response.setReason('Exploit doesn\'t exist') response.setResponse(False) response.setBody(dict()) return response.dictionary()
def getSystemInfo(self): """ Gets the system info. :return: Response object containing request info """ cpu_count_logical = psutil.cpu_count(logical=True) cpu_count = psutil.cpu_count(logical=False) memory = psutil.virtual_memory() mem = getattr(memory, 'total') memory_bytes = int(mem) gigabytes = float(1024**3) total_ram = ceil(memory_bytes / gigabytes) info = { 'cpu_count_logical': cpu_count, 'cpu_count': cpu_count, 'total_ram': total_ram } response = Response() response.setResponse(True) response.setBody(info) return response.dictionary()
def createSharedFolders(self, scenario_json): """ Creates the shared folder within a scenario. :param scenario_json: JSON containing the scenario data :return: Response object containing request info """ response = Response() self.console_manager.printRed('Creating shared folders: ') try: machines = scenario_json['machines'] scenario_name = scenario_json['scenario_name'] machine_names = machines.keys() machines_path = self.getScenariosPath( ) / scenario_name / "Machines" for machine_name in machine_names: machine_uuid = scenario_json["machines"][machine_name]["uuid"] shared_folder_path = machines_path / machine_uuid / "host_shared_folder" if os.path.isdir(shared_folder_path): self.console_manager.printGreen("Folder already exists") else: os.makedirs(shared_folder_path) except KeyError as key_not_found: self.console_manager.printGreen(''.join( [key_not_found, " has not been defined"])) response.setResponse(False) response.setReason(key_not_found, " has not been defined") except OSError: self.console_manager.printGreen("OS Error") response.setResponse(False) response.setReason("OS Error") except: self.console_manager.printGreen(''.join( ["Unexpected error:", sys.exc_info()[0]])) response.setResponse(True) return response.dictionary()
def newEmpty(self, scenario_name): """ Creates a new scenario which includes the folders and the scenario JSON file :param scenario_name: String with the scenario name :return: Response object containing the status of the request """ #Folder creation moved to FileManager response = Response() if scenario_name not in self.scenarios_dict: #self.file_manager.createScenarioFolders(scenario_name) scenario = Scenario(scenario_name) self.scenarios_dict[scenario_name] = scenario #self._saveScenarioAsJSON(scenario) self.db_manager.insertScenario(scenario.dictionary().copy()) response.setResponse(True) response.setBody(scenario.dictionary()) else: response.setResponse(False) response.setReason('Scenario already exist') response.setBody(dict()) return response.dictionary()
def vagrantMachineCommand(self, scenario_name, machine_name, command): """ Runs the given vagrant command on the desired machine, if allowed. :param scenario_name: Name of scenario containing the machine :param machine_name: String with the machine name :return: Response object containing the status of the request """ response = Response() scenario = db_manager.getScenario(scenario_name) if scenario: scenario_json = scenario[0] machine_uuid = scenario_json["machines"][machine_name]["uuid"] allowed_commands = ['suspend', 'halt', 'resume', 'status'] if command not in allowed_commands: response = Response(False, "Given command not allowed") return response.dictionary() else: try: machine_path = file_manager.getScenariosPath( ) / scenario_name / "Machines" / machine_uuid if command != 'status': os.chdir(machine_path) subprocess.run(['vagrant', command]) machine_state = VagrantManager.vagrantStatus( machine_uuid, machine_path) response = Response(True, body={machine_name: machine_state}) return response.dictionary() except OSError: error_message = "OS ERROR while running %s command on %s machine " % command, machine_name print(error_message) response = Response(False, error_message) return response.dictionary() else: response.setResponse(False) response.setReason('Scenario doesn\'t exist') return response.dictionary()
def createVagrantFiles(self, scenario_json): """ Creates a vagrant file per machine in a scenario. :param scenario_json: JSON containing the scenario data :return: Response object containing request info """ response = Response() self.console_manager.printRed('Creating vagrant file') for machine_name in scenario_json["machines"]: #Names scenario_name = scenario_json['scenario_name'] machine_uuid = scenario_json["machines"][machine_name]["uuid"] #Paths machine_path = self.getScenariosPath( ) / scenario_name / "Machines" / machine_uuid #Machine JSON machine = scenario_json["machines"][machine_name] #Generate vagrant files self.console_manager.printBlue( self.vagrant_file.generateVagrantFile(machine, machine_path, machine_uuid)) response.setResponse(True) return response.dictionary()
def editOne(self, vulnerability_json): """ Edits a current scenario with a JSON file :param vulnerability_json: JSON file new vulnerability :return: Response object containing the status of the request """ response = Response() print(vulnerability_json) vulnerability_name = vulnerability_json["name"] if vulnerability_name in self.vulnerabilities_dict: vulnerability_json = Vulnerability().objectFromDictionary( vulnerability_json) self.vulnerabilities_dict[vulnerability_name] = vulnerability_json self.db_manager.editVulnerability( vulnerability_json.dictionary().copy()) response.setResponse(True) response.setBody( self.vulnerabilities_dict[vulnerability_name].dictionary()) else: response.setReason('Vulnerability doesn\'t exist') response.setResponse(False) response.setBody(dict()) return response.dictionary()
def createSaltFiles(self, scenario_json): """ Creates the salt files per each machine in a scenario. :param scenario_json: JSON containing the scenario data :return: Response object containing request info """ response = Response() self.console_manager.printRed('Creating saltstack files') for machine_name in scenario_json["machines"]: # Names scenario_name = scenario_json['scenario_name'] machine_uuid = scenario_json["machines"][machine_name]["uuid"] #Paths machine_path = self.getScenariosPath( ) / scenario_name / "Machines" / machine_uuid keys_path = machine_path / 'salt' / 'keys' conf_path = machine_path / 'salt' / 'conf' #Generate salt files self.salt_manager.generateKeys(keys_path, machine_uuid) self.console_manager.printBlue( self.salt_manager.generateMinionConfigFile( conf_path, machine_uuid)) response.setResponse(True) return response.dictionary()
def getAvailableBoxes(self): """ Gets the available boxes in the Vagrant context :return: A list of string with the available boxes """ # Variables response = Response() boxes = {} boxNum = 0 boxlist = subprocess.check_output("vagrant box list", shell=True) boxlist = str(boxlist) boxlist = re.sub(r"(^[b']|'|\s(.*?)\\n)", " ", boxlist) boxlist = boxlist.split(" ") boxlist = filter(None, boxlist) print("Loading available Vanilla VMs") for boxName in boxlist: boxNum = boxNum + 1 boxes[boxNum] = boxName print("[ " + str(boxNum) + " ]" + boxName) response.setResponse(True) response.setBody(boxes) return response.dictionary()
def createSaltStackFolder(self, scenario_json): """ Creates a folder for each machine in the scenario :param scenario_json: String with the scenario name :return: True if machine folders are created successfully """ # Response message for the requester response = Response() self.console_manager.printRed('Creating saltstack folders: ') try: machines = scenario_json['machines'] scenario_name = scenario_json['scenario_name'] machine_names = machines.keys() machines_path = self.getScenariosPath( ) / scenario_name / "Machines" for machine_name in machine_names: machine_uuid = scenario_json["machines"][machine_name]["uuid"] saltstack_path = machines_path / machine_uuid / 'salt' keys_path = saltstack_path / 'keys' etc_path = saltstack_path / 'conf' paths = [saltstack_path, keys_path, etc_path] for path in paths: if os.path.isdir(path): self.console_manager.printGreen( "Folder already exists") else: os.makedirs(path) except KeyError as key_not_found: self.console_manager.printGreen(''.join( [key_not_found, " has not been defined"])) response.setResponse(False) response.setReason(key_not_found, " has not been defined") except OSError: self.console_manager.printGreen("OS Error") response.setResponse(False) response.setReason("OS Error") except: self.console_manager.printGreen(''.join( ["Unexpected error:", sys.exc_info()[0]])) response.setResponse(True) return response.dictionary()