microsoft / microsoft/SysmonForLinux

Lack of error checking on calls to UTF8toUTF16, rule filter bypass

オープン
#83 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

investigate
主要言語
C
スター
2.2k
フォーク
220
平均マージ
11日 22時間
マージ済み PR(30日)
2

説明

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:

#if defined __linux__
		// on Linux, convert data to UTF16, on heap
		size_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

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:

  1. The first call to UTF8toUTF16 results in error, with returns zero. https://github.com/Sysinternals/SysmonForLinux/blob/f5d6219ec099acf61c1d3b3eecdabaed69faefe4/linuxWideChar.c#L38
  2. malloc is then called with argument 0 (fieldValueLen * sizeof(WCHAR)), which can return a valid pointer on the heap.
  3. UTF8toUTF16 is called again to perform the conversion on this newly allocated heap space, but no data will be written because the argument to len is zero https://github.com/Sysinternals/SysmonForLinux/blob/f5d6219ec099acf61c1d3b3eecdabaed69faefe4/linuxWideChar.c#L58
  4. 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:

...
    <ProcessCreate onmatch="include">
        <Image condition="begin with">/tmp</Image>
    </ProcessCreate>
...
On Fixing

The invalid heap access could be resolved by checking for errors from UTF8toUTF16. For example: https://github.com/inickles/SysmonCommon/commit/01a772320d385146cd91a71b186e9eaa7c912963

However, 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.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

rules.c の2つの UTF8toUTF16 呼び出しの周辺から始め、linuxWideChar.c の変換実装を確認し、その後 xml.cpp の関連する解析パスを調べてください。無効な UTF-8 入力を再現し、フィルタリングによって無効なヒープデータにアクセスしたり、意図されたルールを回避したりしないことを検証してください。変換に失敗した場合の動作を、焦点を絞ったテストまたは最小限の再現で確認してください。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
c
領域
security
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。