
CVE-2024-21980 向けのエクスプロイト。AMD SEV ファームウェアを標的とし、コマンドバッファ強制バイパスを介して退役した SEV-SNP ゲストの任意のメモリを復号する。
このリポジトリには、SEV ファームウェアの脆弱性を悪用するエクスプロイトが含まれています。このエクスプロイトにより、廃止された SEV-SNP ゲストの任意のメモリを復号化できます。
バージョン 1.55.16 (執筆時点での最新) でテスト済み。
SEV ファームウェアには、master_handler_table と呼ばれるテーブルがあり、すべてのコマンドの関数ポインタと、コマンドに関連するいくつかの追加プロパティが含まれています。これらの追加プロパティのうち2つは、cmd_buf_type と snp_cmd_buf_enforcement です。cmd_buf_type は、コマンドバッファをホストメモリにコピーするか、ホストメモリからコピーするかを決定します。snp_cmd_buf_enforcement は、これらのコピー操作が、コマンドバッファをバックアップするメモリが FIRMWARE 状態または DEFAULT 状態であることを検証するチェックの対象となるべきかどうかを決定します。cmd_buf_type が CMD_BUF_OUTPUT_ONLY、CMD_BUF_INPUT_AND_OUTPUT、または CMD_BUF_INPUT_AND_OUTPUT_ERROR のいずれかであるコマンドは、すべて snp_cmd_buf_enforcement を true に設定する必要があります。そうしないと、コマンド出力の書き戻しにより、RMP でカバーされた領域内でメモリ破損が発生する可能性があります。snp_cmd_buf_enforcement は、1つの例外を除いて、そのようなすべてのコマンドで true です - SEV_MCMD_ID_ATTESTATION: このコマンドは cmd_buf_type が CMD_BUF_INPUT_AND_OUTPUT_ERROR に設定されていますが、snp_cmd_buf_enforcement は false に設定されています。その結果、RMP でカバーされたメモリを指すコマンドバッファで SEV_MCMD_ID_ATTESTATION を実行し、出力が書き戻されるとそのメモリが破損する可能性があります。
なぜ SEV_MCMD_ID_ATTESTATION が例外である必要があるのかはわかりません。これはタイプミスやコピーペーストの誤りである可能性が高いと思われます。
SEV_MCMD_ID_ATTESTATION は、コマンドバッファ内の単一のフィールド length (4 バイト) のみに書き込むため、メモリ破損に使用できるのはこれらのバイトのみです。SEV_MCMD_ID_ATTESTATION は常に同じ値 0x000000d0 を書き込みます。幸いなことに、コマンドバッファにはアライメント要件がないため、コマンドバッファを繰り返しシフトして、より広い範囲の連続したメモリを破損できます。これを使用して、ゲストコンテキストページの最初の 16 バイトを静的なパターンで破損します。これらの最初の 16 バイトには UMC キーシードが含まれているため、それを静的な値に強制することで、ゲストの暗号化キーを静的な値に強制できます。
ここで提供されるエクスプロイトは、SWPSIRT-2684/CVE-2023-31355 用に提供したものに大きく基づいています。
脆弱性を悪用するには、次の手順を実行できます。
SEV_MCMD_ID_ATTESTATION に必要です。このゲストを実行したままにします。0x2000 にゲストコンテキストページを作成します。RMP でカバーされた領域内の他のアドレスでも構いませんが、固定アドレスはデバッグに便利です。0x2000 にゲストコンテキストページを作成します。これは手順 1 で使用したアドレスと同じである必要があります。SNP_DBG_ENCRYPT コマンドを使用して、攻撃者ゲストのコンテキストページを使用して被害者ゲストのメモリを復号化します。被害者ゲストと攻撃者ゲストが UMC キーシードを共有しているため、これは成功します。ここでの影響は、少なくとも SWPSIRT-2684 と同じであるはずです。現時点では、このバグを使用して、廃止される前の実行中のゲストのメモリを復号化できるかどうかは不明です。
SEV_MCMD_ID_ATTESTATION に対して snp_cmd_buf_enforcement を true に設定する必要があります。
興味深いことに、Linux KVM ホストサポートパッチは更新の必要がありません。なぜなら、それらは既に SEV_CMD_ATTESTATION_REPORT を、そのコマンドバッファが FIRMWARE 状態であることを必要とするコマンドとして sev_cmd_buf_writable にリストしているからです。他のハイパーバイザーでは変更が必要な場合と不要な場合があります。