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
Event filtering in Sysmon For Linux incorrectly assumes event data, such as executable image paths, will be valid UTF-8 and that conversion to UTF-16 will always succeed. This can result in incorrect filtering results and event logging bypass.
Details
Event filtering on Linux makes two calls to UTF8toUTF16 before comparing event data against filter rules:
#if defined __linux__
// on Linux, convert data to UTF16, on heapsize_t fieldValueLen = UTF8toUTF16( NULL, (PCHAR)fieldValue, 0 );
WCHAR *fieldValueUTF16 = (WCHAR *)malloc(fieldValueLen * sizeof(WCHAR));
if (fieldValueUTF16 == NULL) {
printf("Out of memory\n");
return Failed;
}
UTF8toUTF16( fieldValueUTF16, (PCHAR)fieldValue, fieldValueLen );
fieldValue = fieldValueUTF16;
#endif
The first call to it is done in such a way that it just computes the length of the would-be converted string, the value of which is then used in a call to malloc, where the second call performs actual conversion on the newly allocated heap space.
The issue is that Linux paths are not required to be UTF-8 and calls to UTF8toUTF16 can fail, which is not accounted for:
The code continues to call MatchFilterOnSpecificRule with our pointer on the heap, which will result in either comparing against invalid heap data or a NULL pointer dereference.
This could be used to bypass filter rules where a match should be found for an event. For example, an executable at path /tmp/� (where the “�” is hex FF) with the following filter rule:
It seems the conversion to UTF-16 is done to be able to code shared with the Windows version, but in do so Sysmon For Linux apparently assumes these conversions will always succeed, which won’t always be the case.
Summary
Event filtering in Sysmon For Linux incorrectly assumes event data, such as executable image paths, will be valid UTF-8 and that conversion to UTF-16 will always succeed. This can result in incorrect filtering results and event logging bypass.
Details
Event filtering on Linux makes two calls to
UTF8toUTF16
before comparing event data against filter rules:https://github.com/Sysinternals/SysmonCommon/blob/1ca3832963dfce9f0e4a3d08fdcbd6de1df0cf94/rules.c#L1805-L1815
The first call to it is done in such a way that it just computes the length of the would-be converted string, the value of which is then used in a call to
malloc
, where the second call performs actual conversion on the newly allocated heap space.The issue is that Linux paths are not required to be UTF-8 and calls to
UTF8toUTF16
can fail, which is not accounted for:UTF8toUTF16
results in error, with returns zero. https://github.com/Sysinternals/SysmonForLinux/blob/f5d6219ec099acf61c1d3b3eecdabaed69faefe4/linuxWideChar.c#L38malloc
is then called with argument0
(fieldValueLen * sizeof(WCHAR)
), which can return a valid pointer on the heap.UTF8toUTF16
is called again to perform the conversion on this newly allocated heap space, but no data will be written because the argument tolen
is zero https://github.com/Sysinternals/SysmonForLinux/blob/f5d6219ec099acf61c1d3b3eecdabaed69faefe4/linuxWideChar.c#L58MatchFilterOnSpecificRule
with our pointer on the heap, which will result in either comparing against invalid heap data or aNULL
pointer dereference.This could be used to bypass filter rules where a match should be found for an event. For example, an executable at path
/tmp/�
(where the “�” is hexFF
) with the following filter rule:On Fixing
The invalid heap access could be resolved by checking for errors from
UTF8toUTF16
. For example: inickles/SysmonCommon@01a7723However, this does not fully mitigate the issue of being a potential event filter bypass.
FilterEventRules
will default to excluding events if no matches were found and there are multiple rules defined:https://github.com/Sysinternals/SysmonCommon/blob/73ae2ac398dcba2ae01c2e40664f662c9fc270c8/rules.c#L1968
It seems the conversion to UTF-16 is done to be able to code shared with the Windows version, but in do so Sysmon For Linux apparently assumes these conversions will always succeed, which won’t always be the case.
Other issues in assuming
UTF8toUTF16
will succeed can be found in Sysmon For Linux config parsing in https://github.com/Sysinternals/SysmonCommon/blob/73ae2ac398dcba2ae01c2e40664f662c9fc270c8/xml.cpp, though these are seemingly less serious, where a filter value might be terminated earlier than expected.The text was updated successfully, but these errors were encountered: