
CVE-2020-0796によるバッファオーバーフローのPoC
./CVE-2020-0796.py servername
このスクリプトは対象ホストに接続し、変換ヘッダーに不正なオフセットフィールドを設定した認証要求を圧縮することで、デコンプレッサーがバッファオーバーフローを起こし、対象をクラッシュさせます。
これは優れた smbprotocol を改良したもので、SMB 3.1.1 の圧縮/解凍(LZNT1 のみ)サポートが追加されています。追加の大部分は smbprotocol/connection.py にあります。lznt1 のバージョンが含まれており、Python 3 をサポートするように修正されています。
圧縮変換ヘッダーは SMB2CompressionTransformHeader クラスにあります。_compress 関数が呼び出されてツリー要求を圧縮します。ここでオフセットフィールドがすべて高い値に設定され、クラッシュが発生します。
def _compress(self, b_data, session):
header = SMB2CompressionTransformHeader()
header['original_size'] = len(b_data)
header['offset'] = 4294967295
header['data'] = smbprotocol.lznt1.compress(b_data)
CVE-2020-0796 は、Windows 10 1903/1909 の新しい SMB3 圧縮機能におけるバグです。SMB プロトコルバージョン 3.1.1 では、クライアントまたはサーバーが圧縮機能をアドバタイズし、必要に応じて SMB3 メッセージを選択的に圧縮する機能が導入されています。これを実現するために、SMB セッションのネゴシエーション時に、クライアントとサーバーの両方が MS-SMB2 2.2.3.1.3 に記載された SMB2_COMPRESSION_CAPABILITIES を含める必要があります。
この機能でセッションがネゴシエートされると、クライアントまたはサーバーは特定の SMB メッセージを選択的に圧縮できます。その場合、SMB パケット全体が圧縮され、MS-SMB2 2.2.42 に記載されているように変換ヘッダーが先頭に追加されます。このヘッダーは小さな(16 バイト)構造体で、マジック値、非圧縮データサイズ、使用される圧縮アルゴリズム、およびオフセット値を持ちます。
CVE-2020-0796 は、そのオフセットサイズに対する境界チェックの欠如によって引き起こされ、この値がそのままいくつかのサブルーチンに渡されます。大きな値を渡すとバッファオーバーフローが発生し、カーネルがクラッシュします。さらなる研究により、これは RCE エクスプロイトに発展する可能性があります。