You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The ossec-analysisd rootcheck decoder (src/analysisd/decoders/rootcheck.c) allocates two fixed size heap buffers via global static vars. One, rk_agent_ips is an array of *char size MAX_AGENTS. The other rk_agent_fps is an array of *FILE, also size MAX_AGENTS. In a default build MAX_AGENTS is 2048.
When processing rootcheck messages the RK_File function is called to find a file pointer for the given agent name.
In RK_File a while loop with a index counter i is used to try and find an index of rk_agent_ips that matches the provided agent name.
No check of i is made to ensure that it stays within the bound of MAX_AGENT, resulting in a straight-forward heap buffer overflow when more than MAX_AGENT syscheck update messages for distinct agent names are processed.
This code was introduced in the original rootcheck functionality with 5546ed6 on Oct 9, 2005. I believe it affects OSSEC v2.7+.
This is triggerable via an authenticated client through the ossec-remoted. The client needs only write MAX_AGENT rootcheck update messages with distinct message agent names.
While ossec-remoted always sets the agent name portion of messages passed on to ossec-analysisd with a prefix out of the attackers control based on the agent key and src IP (($NAME) $SRCPIP->) the portion after this prefix is attacker controlled and thus can be mutated to make more than MAX_AGENT unique names that will be decoded by the ossec-analysisd.
Notably this bug has fairly high potential for exploitation. The attacker is able to overwrite a *FILE pointer with a pointer to the agent name, which is mostly attacker controlled (minus a short prefix), and can be up to 255 - strlen(prefix) bytes long. I'm definitely able to reliably segfault the ossec-analysisd process with this bug though I was personally unable to achieve control of execution.
Overwriting a *FILE pointer with a pointer to attacker controlled data is a common way to achieve reliable code execution. There are many pointers in the FILE struct to be abused and while libc has added some hardening it isn't applicable for versions 2.24 or lower (e.g. Ubuntu 16.04) and bypass techniques are well known.
In this case there are two additional challenges to exploiting the bug that stumped me but may not stump someone who is actually good at writing exploits :-)
Since the protocol is all string based you can't use a null byte in payload that overwrites the *FILE contents which makes specifying valid pointers on x86_64 very challenging. (You get one terminating \0 at the end of your payload which can be used for the high order byte of a pointer, but it's still a challenge to find useful targets in high mem).
Getting your overwritten rk_agent_fps entry used with fseek requires being able to specify the rk_agent_ips name at the matching i value. Usually this is the first bytes of a valid FILE and so I think the attacker needs full control of the agent name to be able to specify a match (usually \200,\255\373 or similar. The value is predictable based on rootcheck's open flags). If I'm correct this might mean the segfault is remotely triggerable but exploiting the FILE overwrite may not be.
To fix this the while conditions in DB_File and DB_SetCompleted should be rewritten to short circuit if i >= MAX_AGENTS:
E.g. instead of:
while (i < MAX_AGENTS) {
Use:
while (i < MAX_AGENTS && rk_agent_ips[i] != NULL) {
I think it's worth noting that this bug is nearly identical to the one reported by Paul Southerington in the syscheck decoder, patched in Feb 2012: 91aa29a
This seems like a place where process improvement could help. Receiving vulnerability reports should trigger a search through the codebase for equivalent problems.
The text was updated successfully, but these errors were encountered:
cpu
changed the title
analysisd rootcheck decoder: heap overflow in DB_File.
CVE-2020-8442: analysisd rootcheck decoder: heap overflow in DB_File.
Jan 30, 2020
The
ossec-analysisd
rootcheck decoder (src/analysisd/decoders/rootcheck.c
) allocates two fixed size heap buffers via global static vars. One,rk_agent_ips
is an array of*char
sizeMAX_AGENTS
. The otherrk_agent_fps
is an array of*FILE
, also sizeMAX_AGENTS
. In a default build MAX_AGENTS is 2048.ossec-hids/src/analysisd/decoders/rootcheck.c
Lines 21 to 22 in abb36d4
When processing rootcheck messages the
RK_File
function is called to find a file pointer for the given agent name.In
RK_File
awhile
loop with a index counteri
is used to try and find an index ofrk_agent_ips
that matches the providedagent
name.No check of
i
is made to ensure that it stays within the bound ofMAX_AGENT
, resulting in a straight-forward heap buffer overflow when more thanMAX_AGENT
syscheck update messages for distinct agent names are processed.This code was introduced in the original
rootcheck
functionality with 5546ed6 on Oct 9, 2005. I believe it affects OSSEC v2.7+.This is triggerable via an authenticated client through the
ossec-remoted
. The client needs only write MAX_AGENT rootcheck update messages with distinct message agent names.While
ossec-remoted
always sets the agent name portion of messages passed on toossec-analysisd
with a prefix out of the attackers control based on the agent key and src IP (($NAME) $SRCPIP->
) the portion after this prefix is attacker controlled and thus can be mutated to make more than MAX_AGENT unique names that will be decoded by theossec-analysisd
.Notably this bug has fairly high potential for exploitation. The attacker is able to overwrite a *FILE pointer with a pointer to the agent name, which is mostly attacker controlled (minus a short prefix), and can be up to 255 - strlen(prefix) bytes long. I'm definitely able to reliably segfault the
ossec-analysisd
process with this bug though I was personally unable to achieve control of execution.Overwriting a *FILE pointer with a pointer to attacker controlled data is a common way to achieve reliable code execution. There are many pointers in the FILE struct to be abused and while libc has added some hardening it isn't applicable for versions 2.24 or lower (e.g. Ubuntu 16.04) and bypass techniques are well known.
https://outflux.net/blog/archives/2011/12/22/abusing-the-file-structure/
https://dhavalkapil.com/blogs/FILE-Structure-Exploitation/
https://www.slideshare.net/AngelBoy1/play-with-file-structure-yet-another-binary-exploit-technique
In this case there are two additional challenges to exploiting the bug that stumped me but may not stump someone who is actually good at writing exploits :-)
rk_agent_fps
entry used withfseek
requires being able to specify therk_agent_ips
name at the matchingi
value. Usually this is the first bytes of a validFILE
and so I think the attacker needs full control of the agent name to be able to specify a match (usually\200,\255\373
or similar. The value is predictable based on rootcheck'sopen
flags). If I'm correct this might mean the segfault is remotely triggerable but exploiting the FILE overwrite may not be.To fix this the
while
conditions inDB_File
andDB_SetCompleted
should be rewritten to short circuit ifi >= MAX_AGENTS
:E.g. instead of:
Use:
I think it's worth noting that this bug is nearly identical to the one reported by Paul Southerington in the syscheck decoder, patched in Feb 2012: 91aa29a
It looks like this was fixed in Wazuh's OSSEC fork at some point, though potentially without realizing it fixed a vulnerability: https://github.com/wazuh/wazuh/blob/413b72b17070350b62b2176c2bdc310cc66d30f6/src/analysisd/decoders/rootcheck.c#L77
This seems like a place where process improvement could help. Receiving vulnerability reports should trigger a search through the codebase for equivalent problems.
The text was updated successfully, but these errors were encountered: