ossec / ossec-hids

OSSEC is an Open Source Host-based Intrusion Detection System that performs log analysis, file integrity checking, policy monitoring, rootkit detection, real-time alerting and active response.
http://www.ossec.net
Other
4.42k stars 1.03k forks source link

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

Open cpu opened 4 years ago

cpu commented 4 years ago

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:

https://github.com/ossec/ossec-hids/blob/60cf8d2e941bcded8a05810d87cb906ff771df92/src/analysisd/decoders/syscheck.c#L572-L576

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

https://github.com/ossec/ossec-hids/blob/60cf8d2e941bcded8a05810d87cb906ff771df92/src/analysisd/decoders/syscheck.c#L601-L604

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:

https://github.com/ossec/ossec-hids/blob/60cf8d2e941bcded8a05810d87cb906ff771df92/src/analysisd/analysisd.c#L762-L765

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 8672fa0d5acd1087c285e664804bfa455e9cfd07 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 commented 4 years ago

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: https://github.com/ossec/ossec-hids/issues/1817#issuecomment-575355241

cpu commented 4 years ago

This was assigned CVE-2020-8447