Esempio n. 1
0
    async def get_running_info(self):
        """
        获取当前扫描任务信息

        Returns:
            dict, 结构:
            {
                "0":{
                    "pid": 64067, // 扫描进程pid
                    "host": "127.0.0.1", // 扫描的目标主机
                    "port": 8005, // 扫描的目标端口
                    "rasp_result_timeout": 0, // 获取rasp-agent结果超时数量
                    "waiting_rasp_request": 0, // 等待中的rasp-agent结果数量
                    "dropped_rasp_result": 0, // 收到的无效rasp-agent结果数量
                    "send_request": 0,  // 已发送测试请求
                    "failed_request": 0, // 发生错误的测试请求
                    "cpu": "0.0%", // cpu占用
                    "mem": "10.51 M", // 内存占用
                    "total": 5, // 当前url总数
                    "scanned": 2, // 扫描的url数量
                    "concurrent_request": 10, // 当前并发数
                    "request_interval": 0, // 当前请求间隔
                },
                "1":{
                    ...
                },
            }

        Raises:
            exceptions.DatabaseError - 数据库错误引发此异常
        """
        self._check_alive()
        result = {}
        for scanner_id in range(self.max_scanner):
            if self.scanner_list[scanner_id] is not None:
                result[scanner_id] = copy.deepcopy(self.scanner_list[scanner_id])

        for module_id in result:
            module_name = "Scanner_" + str(module_id)
            runtime_info = RuntimeInfo().get_latest_info()[module_name]
            for key in runtime_info:
                result[module_id][key] = runtime_info[key]

            try:
                scheduler = self.scanner_schedulers[module_name]
            except KeyError:
                raise exceptions.InvalidScannerId

            table_prefix = result[module_id]["host"] + "_" + str(result[module_id]["port"])
            total, scanned, failed = await NewRequestModel(table_prefix, multiplexing_conn=True).get_scan_count()
            result[module_id]["total"] = total
            result[module_id]["scanned"] = scanned
            result[module_id]["failed"] = failed

            if "pause" in result[module_id]:
                del result[module_id]["pause"]
            if "cancel" in result[module_id]:
                del result[module_id]["cancel"]

        return result
Esempio n. 2
0
    def _get_runtime_value(self, key):
        """
        获取scanner运行时的状态信息

        Parameters:
            key - 要获取的变量名

        Returns:
            变量对应的值
        """
        return RuntimeInfo().get_value(self.module_name, key)
Esempio n. 3
0
    def _is_cpu_overused(self):
        """
        判断cpu是否负载过高

        Returns:
            boolean, boolean - cpu是否负载过高,cpu是否空闲
        """
        system_info = RuntimeInfo().get_system_info()
        if system_info["cpu"] > Config().get_config("monitor.max_cpu"):
            Logger().info("CPU percent is higher than limit ({})".format(
                system_info["cpu"]))
            return True, False
        elif system_info["cpu"] < Config().get_config("monitor.min_cpu"):
            return False, True
        else:
            return False, False
Esempio n. 4
0
    def run(self):
        """
        Monitor 主函数
        """

        # 多线程开始前初始化
        RuntimeInfo()

        if Config().get_config("cloud_api.enable"):
            self.cloud_thread = threading.Thread(target=self._upload_report,
                                                 name="upload_report_thread",
                                                 daemon=True)
            self.cloud_thread.start()

        # 初始化调度类
        scanner_schedulers = {}
        for module_name in RuntimeInfo().get_latest_info().keys():
            if module_name.startswith("Scanner"):
                scanner_schedulers[module_name] = ScannerScheduler(module_name)
        ScannerManager().init_manager(scanner_schedulers)

        # 启动后台http server
        # web_console = WebConsole()
        # self.web_console_thread = threading.Thread(
        #     target=web_console.run,
        #     name="web_console_thread",
        #     daemon=True
        # )
        # self.web_console_thread.start()

        # 向云控后台发送心跳,用于建立ws连接

        transaction = Transaction()
        self.transaction_thread = threading.Thread(target=transaction.run,
                                                   name="transaction_thread",
                                                   daemon=True)
        self.transaction_thread.start()

        time.sleep(1)
        if self._check_alive():
            print("[-] OpenRASP-IAST init success!")
            print("[-] Visit web console in cloud server: {}".format(
                Config().get_config("cloud_api.backend_url")))
            print(
                "[-] Before start scan task, set OpenRASP agent plugin algorithmConfig option 'fuzz_server' (edit iast.js or use cloud server web console)  with url: 'http://{}:{}{}'"
                .format(self._get_self_ip(),
                        Config().get_config("preprocessor.http_port"),
                        Config().get_config("preprocessor.api_path")))

            Logger().info("Monitor init success!")
        else:
            self._terminate_modules()
            sys.exit(1)

        while True:
            try:
                # 执行调度
                RuntimeInfo().refresh_info()
                for module_name in scanner_schedulers:
                    scanner_schedulers[module_name].do_schedule()
                time.sleep(Config().get_config("monitor.schedule_interval"))

                # 检测模块存活
                if not self._check_alive():
                    self._terminate_modules()
                    if self.crash_module == "main":
                        Logger().info("OpenRASP-IAST exit!")
                        print("[!] OpenRASP-IAST exit!")
                        self._clean_mei()
                        sys.exit(0)
                    else:
                        Logger().critical(
                            "Detect Module {} down, exit!".format(
                                self.crash_module))
                        self._clean_mei()
                        sys.exit(1)

            except Exception as e:
                Logger().critical("Monitor module crash with unknow error!",
                                  exc_info=e)
                self._terminate_modules()
                self._clean_mei()
                sys.exit(2)
Esempio n. 5
0
    async def get_all_target(self, page=1):
        """
        获取数据库中存在的所有目标主机的列表

        Parameters:
            page - int, 获取的页码,每页10个主机

        Returns:
            list - 获取到的数据, int - 数据总数

            其中数据item为dict,格式为:
            正在扫描的item:
            {
                "id": 1, // 扫描任务id
                "pid": 64067, // 扫描进程pid
                "host": "127.0.0.1", // 扫描的目标主机
                "port": 8005, // 扫描的目标端口
                "cpu": "0.0%", // cpu占用
                "mem": "10.51 M", // 内存占用
                "rasp_result_timeout": 0, // 获取rasp-agent结果超时数量
                "waiting_rasp_request": 0, // 等待中的rasp-agent结果数量
                "dropped_rasp_result": 0, // 收到的无效rasp-agent结果数量
                "send_request": 0,  // 已发送测试请求
                "failed_request": 0, // 发生错误的测试请求
                "total": 5, // 当前url总数
                "failed": 1, // 扫描失败的url数量
                "scanned": 2, // 扫描的url数量
                "concurrent_request": 10, // 当前并发数
                "request_interval": 0, // 当前请求间隔
                "config": {...}, // 配置信息
                "last_time": 1563182956 // 最近一次获取到新url的时间
            }

            未在扫描的item:
            {
                "host": "127.0.0.1", // 扫描的目标主机
                "port": 8005, // 扫描的目标端口
                "total": 5, // 当前url总数
                "scanned": 2, // 扫描的url数量
                "failed": 1, // 扫描失败的url数量
                "config": {...}, // 配置信息
                "last_time": 1563182956 // 最近一次获取到新url的时间
            }

        Raises:
            exceptions.DatabaseError - 数据库错误引发此异常
        """
        result_tables = self._target_status.get_tables()
        Logger().debug("Got current tables: {}".format(
            ", ".join(result_tables)))

        total_target = len(result_tables)
        if page <= 0 or (page - 1) * 10 > total_target:
            page = 1
        result_tables = result_tables[(page - 1) * 10:page * 10]

        result = {}
        for host_port in result_tables:
            host, port = common.split_host(host_port)

            # 如果是运行中的扫描,获取运行状态的信息
            scanner_id = self._scanner_info.get_scanner_id(host_port)
            info = {"host": host, "port": port}

            if scanner_id is not None:
                info["id"] = scanner_id
                module_name = "Scanner_" + str(scanner_id)
                runtime_info = RuntimeInfo().get_latest_info()[module_name]
                info.update(runtime_info)
            result[host_port] = info

        # 获取扫描目标进度信息
        scan_count_info = BaseModel.get_scan_count(result.keys())
        for host_port in scan_count_info:
            result[host_port].update(scan_count_info[host_port])

        # 获取扫描信息上次更新时间
        scan_time_info = BaseModel.get_last_time(result.keys())
        for host_port in scan_time_info:
            result[host_port].update(scan_time_info[host_port])

        # 转换为列表
        result_list = list(result.values())

        return result_list, total_target
Esempio n. 6
0
    def run(self):
        """
        Monitor 主函数
        """

        # 多线程开始前初始化
        RuntimeInfo()

        # 启动后台http server
        web_console = WebConsole()
        self.web_console_thread = threading.Thread(target=web_console.run,
                                                   name="web_console_thread",
                                                   daemon=True)
        self.web_console_thread.start()

        if Config().get_config("cloud_api.enable"):
            self.cloud_thread = threading.Thread(target=self._upload_report,
                                                 name="upload_report_thread",
                                                 daemon=True)
            self.cloud_thread.start()

        # 初始化调度类
        scanner_schedulers = {}
        for module_name in RuntimeInfo().get_latest_info().keys():
            if module_name.startswith("Scanner"):
                scanner_schedulers[module_name] = ScannerScheduler(module_name)
        ScannerManager().init_manager(scanner_schedulers)

        time.sleep(1)
        if self._check_alive():
            print("[-] OpenRASP-IAST init success!")
            print("[-] Visit web console with url: http://{}:{}/".format(
                self._get_self_ip(),
                Config().get_config("monitor.console_port")))
            print(
                "[-] Set OpenRASP agent plugin option 'fuzz_server' with url: http://{}:{}{}"
                .format(self._get_self_ip(),
                        Config().get_config("preprocessor.http_port"),
                        Config().get_config("preprocessor.api_path")))

            Logger().info("Monitor init success!")
        else:
            self._terminate_modules()
            exit(1)

        while True:
            try:
                # 执行调度
                RuntimeInfo().refresh_info()
                for module_name in scanner_schedulers:
                    scanner_schedulers[module_name].do_schedule()
                time.sleep(Config().get_config("monitor.schedule_interval"))

                # 检测模块存活
                if not self._check_alive():
                    self._terminate_modules()
                    if self.crash_module == "main":
                        Logger().info("OpenRASP-IAST exit!")
                        print("[!] OpenRASP-IAST exit!")
                        os._exit(0)
                    else:
                        Logger().critical(
                            "Detect Module {} down, exit!".format(
                                self.crash_module))
                        os._exit(1)

            except Exception as e:
                Logger().critical("Monitor module crash with unknow error!",
                                  exc_info=e)
                self._terminate_modules()
                os._exit(2)