wazuh-modules-sca

发布于:2024-12-06 ⋅ 阅读:(103) ⋅ 点赞:(0)

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


网站公告

今日签到

点亮在社区的每一天
去签到