
AMD SEV-SNPファームウェアの脆弱性(CVE-2023-31355)を悪用し、初期化されていないRMPエントリ書き込みをアドレス0に行うことでUMCキーシードを破損させ、廃止されたゲストの任意のメモリを復号するエクスプロイト。
このリポジトリには、SEVファームウェアの脆弱性を利用したエクスプロイトが含まれています。このエクスプロイトにより、SEV-SNPゲストのメモリを、ゲストがデコミッションされた後に任意に復号できます。
バージョン1.55.16(執筆時点での最新版)でテスト済みです。
snp_reclaim_buffer は、アドレスがRMPでカバーされていない場合でも、無条件にRMP変更を書き戻そうとします。address がRMPでカバーされていない場合、RMPエントリ page_rmp_paddr のアドレスは正しく初期化されず、初期値 0 のままになります。その結果、ファームウェアはRMPエントリの変更をアドレス 0 に書き戻そうとします。これは問題です。なぜなら、アドレス 0 はRMPでカバーされており、追加のチェックなしに書き込むべきではないからです。address がRMPカバー領域外の場合、page_rmp_entry は正しく初期化されず、スタックからのガベージメモリを含みます。このガベージメモリは実際には一定です。
このコードパターンについて正確に警告するコメントがあります。そのため、私がこの問題を最初に報告したのではないとしても驚かないでしょう。
snp_reclaim_buffer は、ハイパーバイザーがリングバッファモードの終了を要求したときに、SEVリングバッファのステータスページのアドレスを引数として呼び出されます。このアドレスは攻撃者が制御可能です。このアドレスにはいくつかのチェックがありますが、デフォルトページ(つまりRMPカバー領域外のページ)は明示的に許可されています。
アドレス 0 へのこの書き込みを悪用するには、そこにゲストコンテキストページを配置します。便利なことに、ゲストコンテキストページの最初のフィールドはUMCキーシードであり、RMPエントリとまったく同じサイズ(両方とも16バイト)です。ファームウェアを騙してアドレス 0 に変更を書き戻させることで、UMCキーシードを破壊できます。書き込まれる未初期化のRMPエントリは常に同じであるため、破壊されたUMCキーシードも常にほぼ同じになります。RMPエントリのサブページカウント(9ビット)は書き込まれませんが、他のすべてのフィールドは書き込まれます。新しいゲストコンテキストページを繰り返し作成することで、毎回異なるランダムな初期サブページカウントが得られるため、最終的に同じUMCキーシードを持つ複数のゲストを作成できます。
脆弱性を悪用するには、以下の手順を実行します:
0 にゲストコンテキストページを作成します。0 にゲストコンテキストページを作成します。SNP_DBG_ENCRYPT コマンドを使用して、攻撃者ゲストのコンテキストページを使って被害者ゲストのメモリを復号します。これは、被害者ゲストと攻撃者ゲストがUMCキーシードを共有しているため成功します。ゲストがデコミッションされた後でしかメモリを復号できないため、ゲストの秘密にアクセスできるにもかかわらず、偽のアテステーションレポートを作成することはできません。偽のアテステーションレポートを作成できるのは、ゲストがデコミッションされる前に別のホストにマイグレーションされた場合のみです。この場合、デコミッションされたゲストの秘密(VMPCKなど)は、新しくマイグレーションされたインスタンスでも機能します。
しかし実際には、多くのアプリケーションがこのエクスプロイトを使用して漏洩する可能性のある他の機密情報(秘密鍵、ディスク暗号化キーなど)を保存しています。
RMPエントリは、ページがデフォルト状態でない場合にのみ書き戻されるべきです。