def hardening_exec(data): """Execute the hardening module and send its output to web""" try: logger.info("Executing the hardening command of " + current_namespace + "/" + data) hrd = module_dict[current_namespace][data] out = hrd.execute_command() print(out) emit(data + "_log", {"msg": out, "state": "output"}) success_msg = "Hardening command executed successfully." emit('log_message', {'tag': 'success', 'content': success_msg}) emit(data + "_log", {"state": "success"}) logger.info(success_msg) except PermissionError: err_msg = "Insufficient permissions for hardening." if check_os(): err_msg += " Get admin rights and rerun the grapheneX." else: err_msg += " Try running the grapheneX with sudo." emit('log_message', { 'tag': 'warning', 'content': err_msg, 'duration': 2000 }) emit(data + "_log", {"state": "error"}) logger.error(err_msg) except Exception as e: fail_msg = "Failed to execute hardening command." emit('log_message', { 'tag': 'danger', 'content': fail_msg, 'duration': 2000 }) emit(data + "_log", {"msg": str(e), "state": "error"}) logger.error(fail_msg + " " + str(e))
def add_module(mod): """Add new module to the framework""" try: mod_name = mod['name'] mod_ns = mod['ns'] logger.info("Adding new module: '" + mod_ns + "/" + mod_name + "'") # Check namespace if not mod_ns: ns_error_msg = "Invalid namespace." logger.error(ns_error_msg) emit('log_message', {'tag': 'danger', 'content': ns_error_msg}) return # Check module name if not re.match(r'^\w+$', mod_name): mod_error_msg = "Invalid module name." logger.error(mod_error_msg) emit('log_message', {'tag': 'danger', 'content': mod_error_msg}) return # Get modules.json with open(mod_json_file, 'r') as f: data = json.load(f) # Prepare module dict mod_dict = { "name": mod_name, "desc": mod['desc'], "command": mod['cmd'], "require_superuser": str(mod['su']).capitalize(), "target_os": "win" if check_os() else "linux" } # Append to json data try: data[mod_ns].append(mod_dict) except: data.update({mod_ns: [mod_dict]}) # Update the modules.json with open(mod_json_file, 'w') as f: json.dump(data, f, indent=4) success_msg = "Module added successfully." emit('log_message', {'tag': 'success', 'content': success_msg}) logger.info(success_msg) global module_dict module_dict = get_modules() # Success event with module count emit('new_module_added', get_mod_count(module_dict)) except Exception as e: exception_msg = "Error occurred while adding new module. " + str(e) emit('log_message', { 'tag': 'warning', 'content': exception_msg, 'duration': 2000 }) logger.warn(exception_msg)
def do_harden(self, arg): """Execute the hardening command""" if not (self.module and self.namespace): logger.error('Select a module/namespace.') else: try: hrd = self.modules[self.namespace][self.module] out = hrd.execute_command() print(out) logger.info("Hardening command executed successfully.") except PermissionError: err_msg = "Insufficient permissions for hardening." if check_os(): err_msg += " Get admin rights and rerun the grapheneX." else: err_msg += " Try running the grapheneX with sudo." logger.error(err_msg) except Exception as e: logger.error("Failed to execute hardening command. " + str(e))
def do_clear(self, arg): """Clear the terminal""" os.system("cls" if check_os() else "clear")
def do_manage(self, arg): """Add, edit or delete module""" def save_mod_json(data): with open(mod_json_file, 'w') as f: json.dump(data, f, indent=4) # Read modules.json data = get_mod_json() try: edit_prompt = [{ 'type': 'list', 'name': 'option', 'message': 'What do you want to do?', 'choices': ["Add module", "Edit module", "Remove module"], }] choice = prompt(edit_prompt) # ADD if choice['option'] == "Add module": # Namespace selection ns_prompt = [{ 'type': 'list', 'name': 'namespace', 'message': 'Select a namespace for your module', 'choices': list(self.modules.keys()) + ["new"], }] # Module details mod_ns = prompt(ns_prompt)['namespace'] mod_questions = [{ 'type': 'input', 'name': 'mod_name', 'message': 'Name of your module', 'validate': ModuleNameValidation, }, { 'type': 'input', 'name': 'mod_desc', 'message': 'Module description', }, { 'type': 'input', 'name': 'mod_cmd', 'message': 'Command', }, { 'type': 'confirm', 'name': 'mod_su', 'message': 'Does this command requires superuser?', }] if mod_ns == "new": mod_question = [{ 'type': 'input', 'name': 'mod_ns', 'message': 'Name of your namespace', 'validate': NamespaceValidation }] mod_namespace = prompt(mod_question) try: mod_ns = mod_namespace['mod_ns'] except: pass # Assigning property to the ModuleNameValidation class to # access modules within the selected namespace. ModuleNameValidation.modules = self.modules[mod_ns].keys() \ if mod_ns in self.modules.keys() else [] mod_details = prompt(mod_questions) mod_dict = { "name": mod_details['mod_name'].title(), "desc": mod_details['mod_desc'], "command": mod_details['mod_cmd'], "require_superuser": mod_details['mod_su'], "target_os": "win" if check_os() else "linux" } try: data[mod_ns.lower()].append(mod_dict) except: data.update({mod_ns.lower(): [mod_dict]}) # Write the updated modules.json save_mod_json(data) logger.info("Module added successfully. Use 'list' " + \ "command to see available modules.") # EDIT & REMOVE elif choice['option'] == "Edit module" or choice[ 'option'] == "Remove module": mod_option = choice['option'].split(" ")[0].lower() # Namespace selection ns_prompt = [{ 'type': 'list', 'name': 'namespace', 'message': "Select the namespace of module to " + mod_option, 'choices': list(self.modules.keys()) }] selected_ns = prompt(ns_prompt)['namespace'] # Module selection mod_prompt = [{ 'type': 'list', 'name': 'module', 'message': "Select a module to " + mod_option, 'choices': self.modules[selected_ns] }] selected_mod = prompt(mod_prompt)['module'] mod_list = [mod['name'] for mod in list(data[selected_ns])] mod_index = mod_list.index(selected_mod) # EDIT if mod_option == "edit": # Create a list for properties prop_list = list( self.modules[selected_ns][selected_mod].kwargs.keys()) prop_list.remove('namespace') prop_list.remove('target_os') # Module property selection prop_prompt = [{ 'type': 'list', 'name': 'property', 'message': "Select a property for editing " + selected_mod, 'choices': prop_list }] selected_prop = prompt(prop_prompt)['property'] # New value for property new_val = prompt([{ 'type': 'input', 'name': 'val', 'message': "New value for " + selected_prop }])['val'] new_val = new_val.title( ) if selected_prop == "name" else new_val # Update the selected property of module data[selected_ns][mod_index][selected_prop] = new_val # Write the updated modules.json save_mod_json(data) logger.info("Module updated successfully. (" + selected_ns + "/" + selected_mod + ":" + selected_prop + ")") # REMOVE else: data[selected_ns].pop(mod_index) save_mod_json(data) logger.info("Module removed successfully. (" + selected_mod + ")") else: pass except Exception as e: logger.error(str(e)) self.namespace = "" self.module = "" self.modules = get_modules()