Skip to content

CVE-2020-8444: analysisd: OS_ReadMSG heap use-after-free with ossec-alert msgs. #1817

@cpu

Description

@cpu

The ossec-analysisd's OS_ReadMSG function calls OS_CleanMSG at the start of processing a received message from the ossec queue UNIX domain socket.

In src/analysisd/cleanevent.c the OS_CleanMSG function populates the lf struct, setting fields like log, hostname and program_name to substrings of the lf->full_log buffer.

After cleaning any messages that meet the ossec-alert decoder's criteria are given to that decoder for further processing.

After processing an ossec alert msg from a client the ossec alert decoder will free the lf->full_log pointer at the end of its processing, replacing it with a new pointer and populating lf->generated_rule:

free(lf->full_log);
lf->full_log = NULL;
os_strdup(tmpstr_buffer, lf->full_log);
lf->log = lf->full_log;
/* Rule that generated. */
lf->generated_rule = rule_pointer;

Though the OSSECAlert_Decoder_Exec function returns NULL and not 1 further rule processing of the lf struct occurs during OS_ReadMSG because of the lf->generated_rule set by the decoder before freeing lf->full_log.

if (lf->decoder_info->type == OSSEC_ALERT) {
if (!lf->generated_rule) {
goto CLMEM;
}
/* Process the alert */
currently_rule = lf->generated_rule;
}

If any subsequent processing associated with the generated rule accesses the lf->hostname or lf->program_name fields set by OS_CleanMSG they will be accessing memory of a freed heap chunk previously containing the lf->full_log.

I believe the bug was introduced in fcca013 on July 23, 2008 and affects OSSEC v2.7+.

This is triggerable via an authenticated client through the ossec-remoted. The client needs only write a ossecalert message that will have the program_name or hostname set during OS_CleanMSG.

I don't have a strong sense for the possibility of exploitation. I suspect this may be turned into an out of bounds read of heap memory accessing program_name or hostname during rule processing if the area pointed to after the syscheck decoder free isn't null terminated.

One possible fix would be for the ossecalert decoder to os_strdup the lf->hostname and lf->program_name before freeing full_log.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions