当前位置: 首页 > article >正文

wazuh-modules-sca

wazuh中安全配置评估模块主线程执行wm_sca_main最后在wm_sca_start中循环执行,不会返回

// Module main function. It won't return
#ifdef WIN32
DWORD WINAPI wm_sca_main(void *arg) {
    wm_sca_t *data = (wm_sca_t *)arg;
#else
void * wm_sca_main(wm_sca_t * data) {
#endif
    // If module is disabled, exit
    if (data->enabled) {
        minfo("Module started.");
    } else {
        minfo("Module disabled. Exiting.");
        pthread_exit(NULL);
    }

    if (!data->policies || data->policies[0] == NULL) {
        minfo("No policies defined. Exiting.");
        pthread_exit(NULL);
    }

    data->msg_delay = 1000000 / wm_max_eps;
    data->summary_delay = 3; /* Seconds to wait for summary sending */
    data_win = data;

    /* Reading the internal options */

    // Default values
    data->request_db_interval = 300;
    data->remote_commands = 0;
    data->commands_timeout = 30;

    data->request_db_interval = getDefine_Int("sca","request_db_interval", 1, 60) * 60;
    data->commands_timeout = getDefine_Int("sca", "commands_timeout", 1, 300);
#ifdef CLIENT
    data->remote_commands = getDefine_Int("sca", "remote_commands", 0, 1);
#else
    data->remote_commands = 1;  // Only for agents
#endif

    /* Maximum request interval is the scan interval */
    if(data->request_db_interval > data->scan_config.interval) {
       data->request_db_interval = data->scan_config.interval;
       minfo("The request_db_interval option cannot be higher than the scan interval. It will be redefined to that value.");
    }

    int i;
    for(i = 0; data->policies[i]; i++) {
        if(data->policies[i]->enabled){
            minfo("Loaded policy '%s'", data->policies[i]->policy_path);
        } else {
            minfo("Policy '%s' disabled by configuration.", data->policies[i]->policy_path);
        }
    }

    /* Create Hash for each policy file */
    for(i = 0; data->policies[i]; i++) {
        os_realloc(cis_db, (i + 2) * sizeof(OSHash *), cis_db);
        cis_db[i] = OSHash_Create();
        if (!cis_db[i]) {
            merror(LIST_ERROR);
            pthread_exit(NULL);
        }
        OSHash_SetFreeDataPointer(cis_db[i], (void (*)(void *))wm_sca_free_hash_data);

        /* DB for calculating hash only */
        os_realloc(cis_db_for_hash, (i + 2) * sizeof(cis_db_hash_info_t), cis_db_for_hash);

        /* Last summary for each policy */
        os_realloc(last_summary_json, (i + 2) * sizeof(cJSON *), last_summary_json);
        last_summary_json[i] = NULL;

        /* Prepare first ID for each policy file */
        os_calloc(1,sizeof(cis_db_info_t *),cis_db_for_hash[i].elem);
        cis_db_for_hash[i].elem[0] = NULL;
    }

    /* Create summary hash for each policy file */
    for(i = 0; data->policies[i]; i++) {
        os_realloc(last_sha256, (i + 2) * sizeof(char *), last_sha256);
        os_calloc(1,sizeof(os_sha256),last_sha256[i]);
    }


#ifndef WIN32

    data->queue = StartMQ(DEFAULTQUEUE, WRITE, INFINITE_OPENQ_ATTEMPTS);

    if (data->queue < 0) {
        merror("Can't connect to queue.");
    }

#endif

    request_queue = queue_init(1024);

    w_rwlock_init(&dump_rwlock, NULL);

#ifndef WIN32
    w_create_thread(wm_sca_request_thread, data);
    w_create_thread(wm_sca_dump_db_thread, data);
#else
    w_create_thread(NULL,
                    0,
                    (void *)wm_sca_dump_db_thread,
                    data,
                    0,
                    NULL);
#endif

    wm_sca_start(data);

#ifdef WIN32
    return 0;
#else
    return NULL;
#endif
}

1. 检查模块是否开启,否则退出模块主线程

2. 对于agents模式,remote_commands = 1

3. 配置最大扫描间隔 data->request_db_interval = data->scan_config.interval;

4. 加载每一个policy文件(.yml或者yaml),为每一个policy文件创建一个hash,到data结构指针中cis_db_for_hash[i],与data[i]通过下标对应起来

5. 创建一个写类型的队列data->queue = StartMQ(DEFAULTQUEUE, WRITE, INFINITE_OPENQ_ATTEMPTS);

6. w_create_thread(wm_sca_request_thread, data); 接收扫描请求,检查处理发送到队列中

7. w_create_thread(wm_sca_dump_db_thread, data); 从队列中消费请求,

8. wm_sca_start(data) -> wm_sca_read_files()按照每一个policy进行扫描  -> rules扫描核心函数wm_sca_do_scan() -> wm_sca_read_command()

         8.1 wm_sca_read_files()函数读policy监控文件到buffer,将buffer中yaml结构转换为json结构

         8.2 检查policy是否满足要求

         8.3 设置一个唯一的id为每个扫描

         8.4 检查文件完整性是否改变,改变则清理

         8.5 调用wm_sca_do_scan()做扫描

         8.6 发送扫描汇总信息wm_sca_send_summary()

9. wm_sca_do_scan()

    char *value = wm_sca_get_value(rule_cp_ref, &type);得到不同的type 例如:WM_SCA_TYPE_FILE,WM_SCA_TYPE_COMMAND,WM_SCA_TYPE_DIR等做不同的处理

已, 以WM_SCA_TYPE_COMMAND类型为例将调用wm_sca_read_command()处理

10. wm_sca_read_command()

static int wm_sca_read_command(char * command,
                               char * pattern,
                               wm_sca_t * data,
                               char ** reason,
                               w_expression_t * regex_engine)
{
    if (command == NULL) {
        mdebug1("No Command specified Returning.");
        return RETURN_NOT_FOUND;
    }

    if (!pattern) {
        mdebug1("No pattern given. Returning FOUND.");
        return RETURN_FOUND;
    }

    mdebug1("Executing command '%s', and testing output with pattern '%s'", command, pattern);
    char *cmd_output = NULL;
    int result_code;

    switch (wm_exec(command, &cmd_output, &result_code, data->commands_timeout, NULL)) {
    case 0:
        mdebug1("Command '%s' returned code %d", command, result_code);
        break;
    case WM_ERROR_TIMEOUT:
        os_free(cmd_output);
        mdebug1("Timeout overtaken running command '%s'", command);
        if (*reason == NULL) {
            os_malloc(snprintf(NULL, 0, "Timeout overtaken running command '%s'", command) + 1, *reason);
            sprintf(*reason, "Timeout overtaken running command '%s'", command);
        }
        os_free(cmd_output);
        return RETURN_INVALID;
    default:
        if (result_code == EXECVE_ERROR) {
            mdebug1("Invalid path or wrong permissions to run command '%s'", command);
            if (*reason == NULL) {
                os_malloc(snprintf(NULL, 0, "Invalid path or wrong permissions to run command '%s'", command) + 1, *reason);
                sprintf(*reason, "Invalid path or wrong permissions to run command '%s'", command);
            }
        } else {
            mdebug1("Failed to run command '%s'. Returned code %d", command, result_code);
            if (*reason == NULL) {
                os_malloc(snprintf(NULL, 0, "Failed to run command '%s'. Returned code %d", command, result_code) + 1, *reason);
                sprintf(*reason, "Failed to run command '%s'. Returned code %d", command, result_code);
            }
        }
        return RETURN_INVALID;
    }

    if(!cmd_output) {
        mdebug2("Command yielded no output. Returning.");
        return RETURN_NOT_FOUND;
    }

    char **output_line;
    output_line = OS_StrBreak('\n', cmd_output, 256);

    if(!output_line) {
        mdebug1("Command output could not be processed. Output dump:\n%s", cmd_output);
        os_free(cmd_output);
        return RETURN_NOT_FOUND;
    }

    os_free(cmd_output);

    int i;
    int result = RETURN_NOT_FOUND;
    for (i=0; output_line[i] != NULL; i++) {
        char *buf = output_line[i];
        os_trimcrlf(buf);
        result = wm_sca_pattern_matches(buf, pattern, reason, regex_engine);
        if (result == RETURN_FOUND){
            break;
        }
    }

    free_strarray(output_line);
    mdebug2("Result for (%s)(%s) -> %d", pattern, command, result);
    return result;
}

10. wm_sca_send_policies_scanned(data);发送管理端数据库中被清理的policy


http://www.kler.cn/a/428893.html

相关文章:

  • Mousetrap:打造高效键盘快捷键体验的JavaScript库
  • Vue 3 自定义 Hook:实现页面数据刷新与滚动位置还原
  • 【深度学习】Huber Loss详解
  • Flink开发中的优化方案
  • 简历_基于 Cache Aside 模式解决数据库与缓存一致性问题。
  • 【Azure 架构师学习笔记】- Azure Function (2) --实操1
  • 麒麟 V10 系统(arm64/aarch64)离线安装 docker 和 docker-compose
  • 使用trace-cmd跟踪Linux内核函数:一次愉快的内核探险
  • BurpSuite-7(自动化漏扫)
  • Redis的五种数据类型(Set、Zset)
  • K8s面试系列:K8s常用 API 资源总结速记
  • Redis过期删除(淘汰)策略概念和理解,以及key已过期内存未释放的处理方式
  • Unity控制物体材质球的改变
  • 解决流网络中不存在s~u~t路径的节点的最大流问题
  • 分享一个开源的网络加速器
  • Vue Web开发(三)
  • 前端路径“@/“的使用和配置
  • 【第一篇】逆向实战,exe游戏 逆向实战之某网络游戏---本文仅供学习-仅供学习-----逆向程序-优雅草央千澈-逆向端游实战---逆向某很火很火的游戏实战。
  • 【Linux】WSL:Win运行Linux
  • 【深度学习】利用Java DL4J 构建和训练医疗影像分析模型
  • 【C语言--趣味游戏系列】--电脑关机整蛊小游戏
  • Brain.js(八):RNNTimeStep 实战教程 - 股票价格预测 - 实操需警慎
  • React v19 正式发布
  • Github 2024-12-04 C开源项目日报 Top9
  • 项目集成篇:springboot集成rabbitmq实现消息发送,消费
  • devops-Dockerfile+Jenkinsfile方式部署Java前后端应用