Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVE-2020-8447: analysisd: OS_ReadMSG heap use-after-free decoding syscheck msgs. #1818

Open
cpu opened this issue Jan 15, 2020 · 2 comments
Open

Comments

@cpu
Copy link
Contributor

cpu commented Jan 15, 2020

The ossec-analysisd's OS_ReadMSG function calls OS_CleanMSG at the start of processing a message read 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 syscheck messages are given to the syscheck decoder for further processing.

After processing a syscheck msg from a client the syscheck decoder will free the lf->full_log pointer in two places. One place is if the message indicated a change in an existing tracked file:

/* Create a new log message */
free(lf->full_log);
os_strdup(sdb.comment, lf->full_log);
lf->log = lf->full_log;
lf->data = NULL;

Another place is if the message indicated a new file to track:

/* Create a new log message */
free(lf->full_log);
os_strdup(sdb.comment, lf->full_log);
lf->log = lf->full_log;

In both cases the syscheck decoder replaces the existing lf->log and lf->full_log pointers with pointers to new messages after first freeing the old lf->full_log. Afterwards the DB_Search, and DecodeSyscheck functions return 1 to OS_ReadMSG.

Since the decoder returned 1, the OS_ReadMSG function will continue processing the event, it will not jump to CLMEM:

if (!DecodeSyscheck(lf)) {
/* We don't process syscheck events further */
goto CLMEM;
}

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

I believe the bug was introduced in 8672fa0 on Nov 18, 2006 and affects OSSEC v2.7+.

This code path is triggerable via an authenticated client through the ossec-remoted. The client needs only write a valid syscheck 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 syscheck decoder to os_strdup the lf->hostname and lf->program_name before freeing full_log.

@cpu
Copy link
Contributor Author

cpu commented Jan 16, 2020

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

See my comment on the related bug. I believe this fix would cause a memory leak and shouldn't be implemented as described: #1817 (comment)

@cpu cpu changed the title analysisd: OS_ReadMSG heap use-after-free decoding syscheck msgs. CVE-2020-8447: analysisd: OS_ReadMSG heap use-after-free decoding syscheck msgs. Jan 30, 2020
@cpu
Copy link
Contributor Author

cpu commented Jan 30, 2020

This was assigned CVE-2020-8447

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant