
CVE-2022-27499
これは、私たちが発見した予期しないスナップショット攻撃(Unanticipated Snapshot Attack)のオリジナルデモです。セキュリティアドバイザリを公開してくれたIntelに感謝します。
まず、デモを実行したい人は誰でも Intel SGX SDK と Occlum をインストールする必要があります(変更を加えた SGX SDK を使用することもできます)。Occlum/SDK を手早くインストールするための Dockerfile を用意しています。変更を加えた SGX SDK は、攻撃者がタイミングを判断するのに役立ちます。
Occlum をホストマシンにインストールすることもできます(詳細は https://github.com/occlum/occlum を参照してください)。どちらの場合でも、先にホストに Intel SGX ドライバ をインストールするか、カーネル内蔵の SGX ドライバを使用する必要があります。
(sudo) docker build -t $Your_Image_Name .
イメージのビルドが完了したら、次を実行します。
(sudo) docker run -it --privileged -p $Redis_Server_Port:6379 -v $Host_SGX_Driver_Path:/dev/sgx --name "snapshot-demo" $Your_Image_Name
ここで、$Redis_Server_Port はコンテナ内の Redis サーバーに公開したいホストのポート番号で、$Host_SGX_Driver_Path は前述の、インストール済み SGX ドライバのデバイスパスです。
ターゲットプログラムは bash_redis フォルダーにあります。
被害者プログラムは bash シェルスクリプト(occlum_bash.sh)を実行しています。このスクリプトはまず、プロビジョニングされたパスワードを取得して、"requirepass" エントリが入力されたカスタマイズ済み Redis 設定ファイルを生成します。その後、カスタマイズされた設定ファイルに従って Redis サーバーを起動します。
設定生成プログラムをビルドするには、make を実行します。Redis サーバーをビルドするには、次のコマンドを実行します。
cd bash_redis
./download_and_build_redis_glibc.sh
被害者用のターミナルを開きます。run_redis.sh を実行して、Redis サーバーが正常に動作するか確認します。
コマンド redis-cli -h $Redis_Server_IP -p $Redis_Server_Port -a admin123456 を使用して、設定ファイルにパスワード(admin123456)が設定されているかどうかを確認します。
ctrl + C を押して Redis サーバーを終了します。
被害者用と攻撃者用の 2 つのターミナルを用意します。被害者用に 1 つのターミナルをすでに開いている場合は、もう 1 つ(攻撃者用)だけ開くことができます。
被害者ターミナルで再度 run_redis.sh を実行します。このスクリプトはターゲットプログラムを起動します。
攻撃者は、スナップショットがフラッシュされていると判断できるタイミングで(./take_snapshot_step-1.sh を使用して)スナップショットを取得する必要があります。デモでは、攻撃者は被害者のターミナルから次のような明確な通知を受け取ることができます。
...
Run ./take_snapshot_step-1.sh NOW!
line 4522: # passwords, then flags, or key patterns. However note that the additive
line 4523: # and subtractive rules will CHANGE MEANING depending on the ordering.
line 4524: # For instance see the following example:
...
攻撃者のターミナルで ./take_snapshot_step-1.sh スクリプトを起動します。
変更を加えた SGX SDK で Occlum をビルドすると、より多くのヒントメッセージが表示されます。これは、Intel SGX SDK の非信頼部分を変更し、攻撃者がタイミングを判断しやすいようにヘルパーメッセージを出力しているためです。攻撃者の便宜のため、攻撃者が ./take_snapshot_step-1.sh を実行できるように タイムスロット を確保しています。実際、ホストの root 権限を持つ攻撃者は、SGX SDK の非信頼部分を変更することでエンクレーブの実行を傍受し、任意のスナップショットを取得できます。
Redis サーバーが起動して実行されたら、./take_snapshot_step-2.sh を実行してスナップショットの収集を完了します。
攻撃者は replay_redis.sh を実行して、収集したスナップショットを使用してエンクレーブをリプレイします。任意のクライアントが認証なしで Redis サーバーにログオンできます。
Redis クライアントのコマンド例:
redis-cli -h $Redis_Server_IP -p $Redis_Server_Port
keys *
(error) NOAUTH Authentication required. というメッセージが表示された場合は、Redis サーバーにアクセスするためにパスワードが必要であることを意味します。auth $Your_Password と入力して認証を通過します。このデモでは auth admin123456 を使用します。
(empty array) というメッセージが表示された場合は、Redis サーバーにアクセスするためにパスワードが不要であることを意味します。
Occlum の整合性チェックが原因でデモが失敗することがあります。おそらく次のようなメッセージが表示されます。
Replaying ...
~/snapshot-demo/bash_redis_replay/occlum_instance ~/snapshot-demo/bash_redis_replay
In: writing meta-data in write_all_changes_to_disk
In: writing meta-data in write_all_changes_to_disk
Error: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }
[ERROR] occlum-pal: The init process exit with code: 1 (line 59, file src/pal_api.c)
[ERROR] occlum-pal: Failed to run the init process: EINVAL (line 129, file src/pal_api.c)
デモを(記録フェーズから)もう一度実行するだけで、エラーは完全に解消されます。
健闘を祈り、楽しんでください!