class Commands: def __init__(self, server): self.commands = {"exploit": self.start_module, "message": self.register_module_message, "status": self.module_status, "kill_process": self.kill_process, "options": self.get_module_options, "get_args_for_module": self.get_module_args, "restore_tabs": self.restore_tabs, "get_all_server_data": self.get_all_server_data, "listener_message": self.on_listener_message, "listener_get_options": self.get_listener_options, "gui_command_to_listener": self.gui_command_to_listener, "get_source": self.get_source, "save_source": self.save_source } self.server = server self.using_module = "" self.available_modules = self.get_all_modules_paths() self.modules_handler = ModulesHandler(server) self.listener_handler = ListenerHandler(server) self.logger = logging.getLogger() self.options_parser = OptionsParser() self.port_scanner = PortScannerMT.Scanner(4000, 5000) def get_all_modules_paths(self): """Get common modules and modules from packs if available""" exploits = Modules.get_modules_names_dict(EXPLOITS_PATH) if not os.path.exists(PACKS_PATH): os.makedirs(PACKS_PATH) files = os.listdir(PACKS_PATH) packs = [] for f in files: path_to_pack = os.path.join(PACKS_PATH, f) if os.path.isdir(path_to_pack): pack_dirs = [fname.lower() for fname in os.listdir(path_to_pack)] if "exploits" in pack_dirs: full_path_to_pack_exploits = os.path.join(path_to_pack, "exploits") exploits.update(Modules.get_modules_names_dict(full_path_to_pack_exploits)) return exploits def execute(self, message, request): """ Execution of command from websocket-client @param (JSON)message: Object, containing keys "command" and "args" @param request: Websocket client request. Used to send response from server to this client """ if message == "": return data = parse_json(message) if not data or type(data) is not dict or "command" not in data.keys() or "args" not in data.keys(): resp = dict(command="message", args="This is not command") request.send_message(json.dumps(resp)) return command = data["command"] args = data["args"] if command in self.commands.keys(): self.commands[command](args, request) def start_module(self, args, request): """Run a module @param (dict)args: key 'module_name' => (string) Name of module key 'listener' => (bool) Use listener key 'listener_options' => (dict) Listener options """ if args["module_name"] not in self.available_modules.keys(): return module_name = self.available_modules[args["module_name"]] use_listener = args["use_listener"] options = args["options"] new_module_name = self.modules_handler.make_unique_name(args["module_name"]) if use_listener: free_socket_data = self.port_scanner.scan(search_for='closed', first_match=True, nthreads=10) if free_socket_data: listener_options = dict(PORT=free_socket_data[0][1]) print listener_options listener_process = subprocess.Popen([sys.executable, LISTENER], shell=False, env=os.environ.copy()) self.listener_handler.addListener(new_module_name, listener_process, listener_options) self.server.add_process(listener_process) process = subprocess.Popen([sys.executable, module_name], shell=False, env=os.environ.copy()) options = self.options_parser.parse_data(options) self.modules_handler.register_process(new_module_name, process, options) self.server.add_process(process) # We need to register first log message of module log_args = {"pid": process.pid, "module_name": new_module_name, "message": "Module %s has been started" % new_module_name, "listener": use_listener, "state": None } self.register_module_message(log_args, request) # Send command to GUI to start logging self.send_all(log_args, request, "start_log") def get_all_server_data(self, args, request): """ Send server data to gui(version, available modules) """ data = [] for name in self.available_modules.keys(): data.append([self.available_modules[name], name]) available_modules = self.modules_handler.get_modules_info(data) # Get framework version module = self.modules_handler.import_from_uri("start.py") version = "?" if module and hasattr(module, "VERSION"): version = module.VERSION args = dict(modules=available_modules, version=version) resp = dict(command="set_all_data", args=args) request.send_message(json.dumps(resp)) def restore_tabs(self, args, request): """ Send data of working modules to restore tabs in gui """ log = self.modules_handler.get_full_log() listeners_messages = self.listener_handler.getListenersMessages() for module_name in log.keys(): if module_name in listeners_messages.keys(): log[module_name]["listener"]=listeners_messages[module_name] resp = dict(command="restore_tabs", args=log) request.send_message(json.dumps(resp)) def module_status(self, args, request): """Get last log message of module :param args: (dict): key "module_name":(string) Name of module; key "pid": (int) PID of this module """ modules = self.modules_handler.get_full_log() listeners_messages = self.listener_handler.getListenersMessages() for module_name in modules.keys(): if module_name in listeners_messages.keys(): modules[module_name]["listener"] = listeners_messages[module_name] resp = dict(command="status", args=modules) request.send_message(json.dumps(resp)) return def kill_process(self, args, request): """Kills running process :param args: (dict): key "module_name":(string) Name of module; key "pid": (int) PID of this module """ module_name = args["module_name"] if module_name not in self.modules_handler.processes.keys(): return remove = "remove" in args self.modules_handler.kill_process(module_name, remove) self.listener_handler.killListener(module_name) def register_module_message(self, args, request): """Add log message from module @param (dict)args: (string)'message'=>Message from module; (bool)'state'=>State of module(success, fail or nothing); (int)'pid'=>Process ID of module (bool)'inline'=>Write on last line if True (bool)'replace'=>Replace last line if True """ inline = args.get("inline", False) replace = args.get("replace", False) if "message" in args.keys() and "state" in args.keys() and "pid" in args.keys(): self.modules_handler.add(args["pid"], args["message"], args["state"], inline, replace) def get_module_options(self, args, request): """Send options of module to gui @param (dict)args: (string)'module_name'=>Name of module """ if args["module_name"] in self.available_modules.keys(): opts = self.modules_handler.get_available_options_for_module(self.available_modules[args["module_name"]]) opts = self.options_parser.prepare_options(opts) json_resp = [] for key in opts.keys(): json_resp.append(dict(option=key, value=opts[key])) self.send_all(json_resp, request, "options") def get_module_args(self, args, request): """ Send modules options to running module """ resp = self.modules_handler.get_module_options(args["pid"]) module_name = self.modules_handler.get_module_name_by_pid(args["pid"]) listener_options = self.listener_handler.getListenerOptionsByName(module_name) resp["listener"] = listener_options request.send_message(json.dumps(resp)) def on_listener_message(self, args, request): """ Add message from listener to gui or get last command from gui to listener """ pid = args['pid'] message = args['message'] action = args['action'] state = args['state'] if action == 'get': message = self.listener_handler.getMessageFromGui(pid) request.send_message(json.dumps(dict(message=message))) return if action == 'add': self.listener_handler.addMessageToGui(pid, message) if state is not None: self.listener_handler.setShellConnected(pid, state) def get_listener_options(self, args, request): """ Send options sets by gui to listener """ pid = args['pid'] options = self.listener_handler.getListenerOptions(pid) request.send_message(json.dumps(options)) def gui_command_to_listener(self, args, request): """ Add gui command to listener to queue """ module_name = args['module_name'] message = args['message'] self.listener_handler.addMessageFromGui(module_name, message) def get_source(self, args, request): """ Get source code of module """ module_name = args['module_name'] with open(self.available_modules[args['module_name']]) as file: lines = file.read().splitlines() source = "\n".join(lines) resp = dict(command="get_source", args=dict(message=source, module_name=module_name)) request.send_message(json.dumps(resp)) def save_source(self, args, request): """ Save edited source code of module """ code = args['message'].encode('utf-8') f = open(self.available_modules[args['module_name']],'w') f.write(code) f.close() def send_all(self, message, request=None, command=""): self.logger.debug(message) if request: resp = {} if command: resp["command"] = command else: resp["command"] = "message" resp["args"] = message request.send_message(json.dumps(resp))
class Commands: def __init__(self, server): self.commands = {"exploit": self.start_module, "message": self.register_module_message, "on_modules_log": self.get_modules_log, "kill_process": self.kill_process, "options": self.get_module_options, "get_args_for_module": self.get_module_args, "get_all_server_data": self.get_all_server_data, "listener_message": self.on_listener_message, "listener_get_options": self.get_listener_options, "gui_command_to_listener": self.gui_command_to_listener, "get_source": self.get_source, "save_source": self.save_source, "generate_report": self.generate_report } self.server = server self.using_module = "" self.available_modules = self.get_all_modules_paths() self.modules_handler = ModulesHandler(server) self.listener_handler = ListenerHandler(server) self.logger = logging.getLogger() self.options_parser = OptionsParser() self.port_scanner = PortScannerMT.Scanner(4000, 5000) self.report_generator = ReportGenerator() def get_all_modules_paths(self): """Get common modules and modules from packs if available""" exploits = Modules.get_modules_names_dict(EXPLOITS_PATH) if not os.path.exists(PACKS_PATH): os.makedirs(PACKS_PATH) files = os.listdir(PACKS_PATH) for f in files: path_to_pack = os.path.join(PACKS_PATH, f) if os.path.isdir(path_to_pack): pack_dirs = [fname.lower() for fname in os.listdir(path_to_pack)] if "exploits" in pack_dirs: full_path_to_pack_exploits = os.path.join(path_to_pack, "exploits") exploits.update(Modules.get_modules_names_dict(full_path_to_pack_exploits)) return exploits def execute(self, message, client): """ Execution of command from websocket-client @param message:(Dict) Object, containing keys "command" and "args" @param client:(WebSocketHandler) Websocket client handler. Used to send response from server to this client """ if not message or type(message) is not dict or "command" not in message.keys() or "args" not in message.keys(): resp = dict(command="message", args="This is not command") client.send_message(json.dumps(resp)) return command = message["command"] args = message["args"] if command in self.commands.keys(): self.commands[command](args, client) def start_module(self, args, client): """Run a module @param (dict)args: key 'module_name' => (string) Name of module key 'listener' => (bool) Use listener key 'listener_options' => (dict) Listener options """ if args["module_name"] not in self.available_modules.keys(): return module_name = self.available_modules[args["module_name"]] use_listener = args["use_listener"] options = args["options"] new_module_name = self.modules_handler.make_unique_name(args["module_name"]) # After getting unique module name send it to gui data = dict(command="start_module", args=dict(module_name=new_module_name, listener=use_listener)) client.send_message(json.dumps(data)) if use_listener: exclude_ports = self.listener_handler.get_busy_ports_list() free_socket_data = self.port_scanner.scan(search_for='closed', first_match=True, nthreads=10, exclude=exclude_ports) if free_socket_data: listener_options = dict(PORT=free_socket_data[0][1]) listener_process = subprocess.Popen([sys.executable, LISTENER], shell=False, env=os.environ.copy()) self.listener_handler.addListener(new_module_name, listener_process, listener_options) self.server.add_process(listener_process) process = subprocess.Popen([sys.executable, module_name], shell=False, env=os.environ.copy()) options = self.options_parser.parse_data(options) self.modules_handler.register_process(new_module_name, args["module_name"], process, options) self.server.add_process(process) # We need to register first log message of module log_args = {"pid": process.pid, "module_name": new_module_name, "message": "Module %s has been started" % new_module_name, "listener": use_listener, "state": None } self.register_module_message(log_args, client) def get_all_server_data(self, args, client): """ Send server data to gui(version, available modules) """ data = [] for name in self.available_modules.keys(): data.append([self.available_modules[name], name]) available_modules = self.modules_handler.get_modules_info(data) # Get framework version module = self.modules_handler.import_from_uri("start.py") version = "?" if module and hasattr(module, "VERSION"): version = module.VERSION args = dict(modules=available_modules, version=version) resp = dict(command="set_all_data", args=args) client.send_message(json.dumps(resp)) def get_modules_log(self, args, client): """Get last log message of module :param args: (dict): key "module_name":(string) Name of module; key "pid": (int) PID of this module """ modules = self.modules_handler.get_full_log() listeners_messages = self.listener_handler.getListenersMessages() for module_name in modules.keys(): if module_name in listeners_messages.keys(): modules[module_name]["listener"] = listeners_messages[module_name] resp = dict(command="on_modules_log", args=modules) client.send_message(json.dumps(resp)) def kill_process(self, args, request): """Kills running process :param args: (dict): key "module_name":(string) Name of module; key "pid": (int) PID of this module """ module_name = args["module_name"] if module_name not in self.modules_handler.processes.keys(): return remove = "remove" in args self.modules_handler.kill_process(module_name, remove) self.listener_handler.killListener(module_name) def register_module_message(self, args, client): """Add log message from module @param (dict)args: (string)'message'=>Message from module; (bool)'state'=>State of module(success, fail or nothing); (int)'pid'=>Process ID of module (bool)'inline'=>Write on last line if True (bool)'replace'=>Replace last line if True """ inline = args.get("inline", False) replace = args.get("replace", False) if "message" in args.keys() and "state" in args.keys() and "pid" in args.keys(): module = self.modules_handler.add(args["pid"], args["message"], args["state"], inline, replace) message = {"command": "on_module_message", "args": { "module_name": module.module_name, "message": module.log[-1].formatted(), "state": args["state"] }} if args["state"] is not None: self.generate_report(args["pid"]) self.send_message_to_ui(json.dumps(message)) client.send_message(json.dumps({"message": "ok"})) def get_module_options(self, args, client): """Send options of module to gui @param (dict)args: (string)'module_name'=>Name of module """ if args["module_name"] in self.available_modules.keys(): opts = self.modules_handler.get_available_options_for_module(self.available_modules[args["module_name"]]) opts = self.options_parser.prepare_options(opts) json_resp = [] for key in opts.keys(): json_resp.append(dict(option=key, value=opts[key])) client.send_message(json.dumps(dict(command="options", args=json_resp))) def get_module_args(self, args, client): """ Send modules options to running module """ resp = self.modules_handler.get_module_options(args["pid"]) module_name = self.modules_handler.get_module_name_by_pid(args["pid"]) listener_options = self.listener_handler.getListenerOptionsByName(module_name) resp["listener"] = listener_options client.send_message(json.dumps(resp)) def gui_command_to_listener(self, args, client): """ Add gui command to listener to queue """ module_name = args['module_name'] message = args['message'] self.listener_handler.addMessage(module_name, ">> "+message) pid = self.listener_handler.getPidByModuleName(module_name) self.send_message_to_client_by_name(pid.__str__(), json.dumps(args)) def on_listener_message(self, args, client): """ Add message from listener to gui or get last command from gui to listener """ pid = args['pid'] message = args['message'] state = args['state'] module_name = self.listener_handler.getModuleNameByPid(pid) self.listener_handler.addMessage(module_name, message) data = dict(command="on_listener_message", args=dict(module_name=module_name, state=state, message=message)) self.send_message_to_ui(json.dumps(data)) if state is not None: self.listener_handler.setShellConnected(pid, state) def get_listener_options(self, args, client): """ Send options sets by gui to listener """ pid = args['pid'] options = self.listener_handler.getListenerOptions(pid) client.send_message(json.dumps(options)) def get_source(self, args, client): """ Get source code of module """ module_name = args['module_name'] with open(self.available_modules[args['module_name']]) as file: lines = file.read().splitlines() source = "\n".join(lines) resp = dict(command="get_source", args=dict(message=source, module_name=module_name)) client.send_message(json.dumps(resp)) def save_source(self, args, client): """ Save edited source code of module """ host, port = client.socket.getsockname() if "localhost" not in host and "127.0.0.1" not in host: message = "Only localhost user can save sources" resp = dict(command="show_message_box", args=dict(message=message)) client.send_message(json.dumps(resp)) return code = args['message'].encode('utf-8') f = open(self.available_modules[args['module_name']],'w') f.write(code) f.close() def generate_report(self, pid): module_name = self.modules_handler.get_module_name_by_pid(pid) if not module_name: return module_inst = self.modules_handler.get_module_inst_by_name(module_name) listener_inst = self.listener_handler.get_listener_inst_by_name(module_name) info = self.modules_handler.get_module_info((self.available_modules[module_inst.original_name], module_name)) module_vars = { "LOG": module_inst.log, "RESULT": module_inst.state, "OPTIONS": module_inst.options } listener_vars = { "IS_SHELL_CONNECTED": 0, "LISTENER_OPTIONS": 0, "LISTENER_LOG": 0 } if listener_inst: listener_vars = { "IS_SHELL_CONNECTED": listener_inst.isShellConnected, "LISTENER_OPTIONS": listener_inst.options, "LISTENER_LOG": listener_inst.getMessagesFormatted() } module_vars.update(info) module_vars.update(listener_vars) module_vars["CVE"] = module_vars["CVE Name"] self.report_generator.append_module(module_vars) def send_message_to_ui(self, message): self.server.send_message_to_all_uis(message) def send_message_to_client_by_name(self, client_name, message): self.server.send_message_to_client(client_name, message)
class Commands(API): def __init__(self, server): API.__init__(self) self.commands = self.get_api_functions() self.server = server self.available_modules = self.get_all_modules_paths() self.modules_handler = ModulesHandler(self) self.logger = logging.getLogger() self.options_parser = OptionsParser() self.port_scanner = PortScannerMT.Scanner(4000, 5000) self.report_generator = ReportGenerator() self.service_messages_handler = ServiceMessagesHandler() def get_api_functions(self): """ Find all api_wrapped methods in class Commands Returns (dict): method name => method """ api_methods = { k: v for k, v in vars(self.__class__).items() if inspect.isfunction(v) and v.__name__ == 'api_wrapped' } return api_methods def get_all_modules_paths(self): """Get common modules and modules from packs if available""" exploits = Modules.get_modules_names_dict(EXPLOITS_PATH) if not os.path.exists(PACKS_PATH): os.makedirs(PACKS_PATH) files = os.listdir(PACKS_PATH) for f in files: path_to_pack = os.path.join(PACKS_PATH, f) if os.path.isdir(path_to_pack): pack_dirs = [ fname.lower() for fname in os.listdir(path_to_pack) ] if "exploits" in pack_dirs: full_path_to_pack_exploits = os.path.join( path_to_pack, 'exploits') exploits.update( Modules.get_modules_names_dict( full_path_to_pack_exploits)) return exploits def _get_wrapped_function_required_args(self, func): if not hasattr(func, '__wrapped__'): return None args_spec = inspect.getargspec(func.__wrapped__) # Now slice 2 first arguments(self, client) and kw_args required_args = args_spec.args[2:-len(args_spec.defaults or [])] return args_spec.args, required_args def execute(self, message, client): """ Execution of command from websocket-client @param message:(Dict) Object, containing keys "command" and "args" @param client:(WebSocketHandler) Websocket client handler. Used to send response from server to this client """ if not message or type( message ) is not dict or "command" not in message or "args" not in message: self.send_error(client, 'Error while handling request') return command = message["command"] args = message["args"] uuid = message.get('uuid') args = args if args else {} if command not in self.commands: self.send_error(client, 'Wrong command') return func = self.commands[command] func_args, func_req_args = self._get_wrapped_function_required_args( func) # find missing or excess args func_args_set = set(func_args) func_req_args_set = set(func_req_args) input_args_set = set(args) intersection = func_req_args_set.intersection(input_args_set) # missing if len(intersection) != len(func_req_args_set): diff = func_req_args_set.difference(input_args_set) msg = 'Following required parameters are missing: %s' % ', '.join( diff) print(command, 'Error: %s' % msg) self.send_error(client, msg) return diff = input_args_set.difference(func_args_set) if diff: msg = 'Following parameters are excess: %s' % ', '.join(diff) print(command, 'Error: %s' % msg) self.send_error(client, msg) return # if no errors call func resp = func(self, client, **args) if uuid: client.send_message( dict(command='on_callback', args=resp, uuid=uuid)) @API.callable def start_module(self, client, module_name, use_listener, use_custom_port=False, custom_port=0, listener_type=1, options={}): """ Runs a module Args: module_name: (string) Name of module use_listener: (bool) If True - enable listener for module use_custom_port: (bool) Use custom listener port custom_port: (int) Custom listener port listener_type: (int) 1 - reverse, 2 - bind options: (dict) Option of module set up in GUI Returns: (dict): 'module_name': (string) Unique name of running module 'listener': (bool) Is listener enabled """ if module_name not in self.available_modules: print('There is no module with name %s' % module_name) return module_path = self.available_modules[module_name] new_module_name = self.modules_handler.make_unique_name(module_name) options = self.options_parser.parse_data(options) running_module = self.modules_handler.register_process( new_module_name, module_name, options) if use_listener and listener_type == 1: exclude_ports = self.modules_handler.get_busy_ports_list() if use_custom_port and custom_port: if custom_port in exclude_ports or self.port_scanner.check_port_state( custom_port): message = 'Lister port %d is busy. Try another port for listener' % custom_port return self.make_error(message) listener_options = dict(PORT=custom_port) else: free_socket_data = self.port_scanner.scan( search_for='closed', first_match=True, nthreads=10, exclude=exclude_ports) listener_options = dict(PORT=free_socket_data[0][1]) running_module.listener_options = listener_options listener_process = subprocess.Popen( [sys.executable, LISTENER_PATH, new_module_name], shell=False, env=os.environ.copy()) self.modules_handler.add_listener_pid(new_module_name, listener_process.pid) process = subprocess.Popen( [sys.executable, module_path, new_module_name], shell=False, env=os.environ.copy()) self.modules_handler.add_module_pid(new_module_name, process.pid) return dict(module_name=new_module_name, listener=use_listener) @API.callable def install_via_pip(self, client, library_name): """ Install python module via pip Args: library_name: Name of module to install """ import subprocess try: proc = subprocess.Popen(['pip', 'install', library_name]) except Exception as e: print e return self.make_error('Can\'t install module %s' % library_name) else: proc.communicate() if proc.returncode == 0: self.service_messages_handler.remove_import_error(library_name) return dict(module_to_import=library_name) return self.make_error('Can\'t install module %s' % library_name) @API.callable def get_all_server_data(self, client): """ Returns dict of modules, version, service messages """ data = [] self.service_messages_handler.reset() for name in self.available_modules: data.append([self.available_modules[name], name]) available_modules = self.modules_handler.get_modules_info(data) service_messages = self.service_messages_handler.get_grouped() # Get framework version module = self.modules_handler.import_from_uri("start.py", False) version = "?" if module and hasattr(module, "VERSION"): version = module.VERSION return dict(modules=available_modules, version=version, serviceMessages=service_messages) @API.callable def get_modules_log(self, client): """ Get all modules and listeners log """ modules = self.modules_handler.get_full_log() return modules @API.callable def kill_process(self, client, module_name): """ Kills running processes of module and listener if exists Args: module_name: (string) Name of module """ if module_name not in self.modules_handler.running_modules: return self.modules_handler.kill_process(module_name) @API.callable def register_module_message(self, client, message, state, module_name, type='text', inline=False, replace=False): """ Add log message from module Args: message: (string) Message from module state: (bool or None) State of module(success, fail or nothing) module_name: (string) Name og running module type: (string) text or image inline: (bool) Write on last line if True replace: (bool) Replace last line if True """ module = self.modules_handler.add_message(module_name, message, state, inline, replace, type) message = { "command": "on_module_message", "args": { "module_name": module.module_name, "message": module.log[-1].formatted(), "state": state } } # TODO REPORTS # if state is not None: # self.generate_report(pid) self.send_message_to_ui(message) return dict(message="ok") @API.callable def get_module_options(self, client, module_name): """ Send options of module to gui Args: module_name: real module name without '.py' extension Returns: (list) List of options from module's dict OPTIONS """ if module_name in self.available_modules: opts = self.modules_handler.get_available_options_for_module( self.available_modules[module_name]) opts = self.options_parser.prepare_options(opts) json_resp = [] for key in opts: json_resp.append(dict(option=key, value=opts[key])) return json_resp @API.callable def get_module_args(self, client, module_name): """ Get module options changed by GUI Args: module_name: (string) Name of running module Returns: (dict) Dict of options """ resp = self.modules_handler.get_changed_options(module_name) return resp @API.callable def gui_command_to_listener(self, client, module_name, message): """ Sends command from GUI to listener Args: module_name: (string) Name of running module message: (string) Message for listener from gui(os command) """ self.modules_handler.add_listener_message(module_name, ">> " + message) args = dict(module_name=module_name, message=message) self.send_message_to_listener(module_name, args) @API.callable def on_listener_message(self, client, module_name, message, state): """ Add message from listener to gui or get last command from gui to listener Args: module_name: (string) Name of running module message: (string) Message from listener state: (int) 0 - shell is not connected 1 - shell connected 2 - shell disconnected """ self.modules_handler.add_listener_message(module_name, message, state) data = dict(command="on_listener_message", args=dict(module_name=module_name, state=state, message=message)) self.send_message_to_ui(data) @API.callable def get_listener_options(self, client, module_name): """ Get listener options by listener PID or module PID Args: module_name: (string) Name of running module """ if not module_name: return self.make_error('PIDs are not specified') options = self.modules_handler.get_module_inst_by_name( module_name).listener_options return options @API.callable def add_listener_options(self, client, module_name, options): """ Adds/Changes options of listener Args: module_name: (string) Name of running module options: (dict) listener options """ module = self.modules_handler.get_module_inst_by_name(module_name) module.listener_options = options return {"re"} @API.callable def add_listener_pid(self, client, module_name, pid): """ Adds listener PID to running module instance Args: module_name: (string) Name of running module pid: (int) Listener PID """ self.modules_handler.add_listener_pid(module_name, pid) @API.callable def get_source(self, client, module_name): """ Get source code of module Args: module_name: (string) real module name, without '.py' extension """ with open(self.available_modules[module_name]) as f: lines = f.read().splitlines() source = "\n".join(lines) return dict(message=source, module_name=module_name) @API.callable def save_source(self, client, module_name, message): """ Save edited source code of module Args: module_name: (string) real module name, without '.py' extension message: (string) Edited source code of module """ host, port = client.socket.getsockname() if "localhost" not in host and "127.0.0.1" not in host: message = "Only localhost user can save sources" self.send_error(client, message) return code = message.encode('utf-8') with open(self.available_modules[module_name], 'wb') as f: f.write(code) self.send_info(client, 'Module %s successfully changed' % module_name) @API.callable def is_listener_connected(self, client, module_name): """ Get info about state of listener Args: module_name: (string) Name of running module """ state = None module = self.modules_handler.get_module_inst_by_name(module_name) if module: state = module.is_shell_connected if state == 0: state = False elif state == 1: state = True resp = dict(state=state) return resp def make_error(self, error_msg): return dict(error=True, message=error_msg) def send_error(self, client, error_msg): client.send_message( dict(command='on_error', args=dict(message=error_msg))) def send_info(self, client, info_msg): client.send_message( dict(command='on_info', args=dict(message=info_msg))) def generate_report(self, module_name): module_inst = self.modules_handler.get_module_inst_by_name(module_name) info = self.modules_handler.get_module_info( (self.available_modules[module_inst.original_name], module_name)) module_vars = { "LOG": module_inst.log, "RESULT": module_inst.state, "OPTIONS": module_inst.options } listener_vars = { "IS_SHELL_CONNECTED": module_inst.is_shell_connected, "LISTENER_OPTIONS": module_inst.listener_options, "LISTENER_LOG": '\n'.join(module_inst.listener_messages) } module_vars.update(info) module_vars.update(listener_vars) module_vars["CVE"] = module_vars["CVE Name"] self.report_generator.append_module(module_vars) def send_message_to_ui(self, message): self.server.send_message_to_all_uis(message) def send_message_to_listener(self, module_name, message): self.server.send_message_to_listener(module_name, message)