少し前のニュースで、ASPLOS19でRISC-Vをベースとした新しいセキュアプロセッサの発表が行われたというニュースを見た。
Morpheus: A Vulnerability-Tolerant Secure Architecture Based on Ensembles of Moving Target Defenses with Churn
セキュリティ界隈には全く詳しくないのだが、面白そうなので読んでみることにした。
結論から言うと「RISC-Vベース」というのは単なる釣りで、特にRISC-Vは関係ない。別に何のアーキテクチャでも良いのだが、サンプルとしてRISC-Vを使用した、というだけだった。
しかし、普段あまり関わりのない領域の論文を読むのは面白い。プロセッサのセキュリティ対策としてどのようなものがあるのか、勉強になった。
長いので、読むのが面倒な人向け。
- 様々なランダム化機構を埋め込む。あと、「意味的におかしな」コードがあればそれの実行を行わない。
- このため、「本当に意味的におかしな」プログラムがあればその性能は低下する。ランダムパタン等かな?
- チャーンという定期的に再ランダム化させる機構により、攻撃者が時間をかけてシステムの攻撃目標を見つける(これをProbeと呼ぶ)のを防ぐ。
- このあたり、引用文献が非常に多いので、ある程度既存な技術が混じっていることは間違いないと思う。それを上手く組み合わせ、チャーンを組み込むのがポイント。
- RTLを実装したのかと思ったら違った。いろんなニュースでは、「マイクロアーキテクチャの発表」だとか、「チップのデモ」などと書いてあるが、論文にはその言及はなかった。
- だいたい、ダイ写真やプロセスの情報も出てこない。
- プログラムにセマンティクスを入れる必要があるため、コンパイラに手を入れる必要がある。
- これはマイナスポイント。よっぽど特殊な、軍事向けなどの特殊なチップとしてなら使えそう。
- 性能低下は、どの程度暗号化を行うかに依存する。
Morpheusは、システムの攻撃を防ぐための機能を搭載したプロセッサ。ここでは、大きく分けて以下の3つの機能を解説する。
- Domain Tagging : セマンティックと命令を元にデータの意味をタグ付けする。
- Pointer Displacement : 命令とデータの場所をランダムに分離し、攻撃を防ぐ。
- Domain Encryption : Tag付けしたDomainを暗号化する。
- Churn (チャーン、と読む) : 語源は「かくはん」。定期的にランダム値を切替、攻撃者のシステム解析を遅らせる。
1. Introduction
これまでにあるCPUによる悪意のあるコードを実行されることを防ぐ仕組みは以下の通り。
- NX-bit : 特定のメモリ領域(に置かれたデータ)に付与する実行不可属性、またはその属性付与機能
- ASLR : Address Space Layout Randomization
今回は、プロセッサにチャーンと呼ばれる機構を導入してセキュリティの強化を行う。 チャーン(churn)とは、システムが動作している最中に透過的に移動するターゲットプログラムの値を再ランダム化するメカニズムのこと。 基本的な考え方は、システム中にランダムな値を動的に組み込んで攻撃者がターゲットの場所を読み取りにくくするのだが、チャーンと呼ばれる定期的にランダム値を再ランダム化する機構により、よりターゲットを探索しにくくするという機構である。
Morpheusでは、セキュリティの機構として大きく分けて以下の2つを理解する必要がある。
上記の2つを組み合わせて、 - ensembles of moving target defenses(EMTDs) を導入する。これは、上記のセキュリティ機構を組み合わせて、未確定な要素をランダム化する機構。 - Morpheusアーキテクチャを導入する。RISC-Vベースのプロセッサであり、制御フロー攻撃をEMTDとチャーンを使って防御するアーキテクチャである。
Morpheusを使うと、504ビットのエントロピーと50msのチャーン期間によって平均1%の性能低下(最大7%)がSPEC06およびMiBenchベンチマークで観測された。 Morpheusにより制御フロー攻撃に対する強力な防御が可能であることを示した。これには、ROPおよびBack-Call-Site攻撃も含まれる。 これらの分析により、Morpheusアーキテクチャは潜在的な制御フロー攻撃に対して効率的な防御が行えることを示した。
2. 脆弱性の例と、それに対抗するセキュアアーキテクチャ
以下ののコードは、ROP(Return Oriented Programming)を使用した攻撃コードだ。
strcpy
により配列の境界を越えた場所にデータを書き込み、vulnerable()
の戻り値を上書きすることでtarget()
にジャンプできるようにする。
void target() { printf("You overflowed successfully, gg"); exit(0); } void vulnerable(char* str1) { char buf[5]; strcpy(buf, str1); } int main() { vulnerable("ffffffffffffffff\xf0\x03\x02\x01"); printf("This only prints in normal control flow"); }
この時の特徴は、攻撃対象のコードはセマンティック的に意味を持たないコードで構成されている。 つまり、普通はデータフロー的に意味のあるフローで流れているはずが、突如としてデータフロー的に意味のない命令が挿入され、データが改ざんされる。これをとらえれば、攻撃を検知することができる、という訳だ。
例えば、上記のプログラムにおける未定義な部分は、
- 境界を越えた配列アクセス
buf[]
- 戻りアドレスの場所 : コードオブジェクトのアドレス
そこで、防御の方法としてMoving Target Defense(攻撃対象となる領域を移動させる)。つまり、未定義なセマンティクスに対してランダムな領域に移動を行う。これにより、攻撃者が攻撃の際に前提に置く動作を防ぐことができる。
図2. Moving Target Defenseにより、攻撃者がシステムの未定義の値を事前調査する必要が生じることを示している。通常であれば、「システムの事前調査(Probe)」→「攻撃の用意(Wepononize)」→「攻撃(Attack)」→「漏洩(Exploited)」となるところを、
- EMTDsを導入 : 「システムの事前調査(Probe)」に非常に時間がかかる→「攻撃の用意(Wepononize)」→「攻撃(Attack)」→「漏洩(Exploited)」となり攻撃に時間がかかる。
- EMTDs + チャーン : システムの事前調査をしてもチャーンにより定期的に再ランダム化されるため、いつまでたってもProbeが完了しない。
例えば、上記のROPの攻撃であれば、
- 攻撃者は、システム内で
target()
が存在するアドレスをスキャンする。 strcpy()
を行うための所望のアドレスと文字列を算出し挿入する。
というステップが必要になる。これはASLRによりヒープ・スタックの場所をランダム化することができるが、ASLRでは一時的な障壁に過ぎない。 例えば、AnC攻撃は150秒で完全な48ビットx86_64仮想アドレスを検知することができる。 エントロピーが大きければ、システムの事前調査(Probe)に必要な時間が増加すると言う事を示している。 つまり、エントロピーを増大させることによりProbe時間を増大させ、攻撃が成功することを防ぐ、という防御手段が成り立つ。
3. 脅威モデル
本論文での脅威モデルはDoSおよびサイドチャネルアタックは対象としない。
4. Morpheus セキュアアーキテクチャ
64ビットRISC-V命令セットをベースとする。防御対象としては、1. 命令コード、2. コードポインタ、3. データポインタとする。
MorpheusのMoving Target Defensesの機構には、大きく分けて以下の3つが存在する。
さらに、チャーンユニット(churn unit : 4.4章) をコアに追加する。4.1章では、攻撃検知器(attack detector)を搭載する。
CPUの動作を4つのドメインに分類する。
- Code (C)
- Code Pointer(CP)
- Data Pointer(DP)
- Other Data(D)
パイプラインはデータとともにタグを流す。最初のタグはコンパイラから生成する。このため、改造したLLVMのコンパイラが必要になる。 つまり、パイプラインにデータとともにその意味(これは命令か?データか?ポインタか?)を流すわけである。 一方でマイクロアーキテクチャはタグを格納するためのストレージを持っている。
MorpheusはLLVMベースのコンパイラ拡張を使用し、実行時に正確なドメインを記録する。 コンパイラはCのソースファイルをコンパイルし、LLVM中間表現に変換し、バックエンドは各命令についてラベルを生成してメモリオブジェクトを初期化する。 この時、メモリオブジェクトの最初のタグを生成する。
そして命令が実行されるたびにタグを継承する。 例えば、ポインタへの算術演算命令はポインタを生成する。Attack Detectorにより、怪しいポインタの計算や型の異なる演算を検出し、チャーンのサイクル毎に例外を発生させる。 ただし、攻撃目的のプログラムでなくてもまれにこのような動作をすることがあり、その時に性能は低下する。
アイデアその2. ポインタディスプレースメント防御
全ての制御フロー攻撃は、メモリオブジェクトがどこに配置されているのかという情報を必要とする。 これらの値がどこに配置されているのかをより不明確にするために、MorpheusはPointer displacementという機構を持っている。 これは、2つのランダムな分離したアドレス空間(と)を、仮想アドレス空間上に配置している。 図4に示すように、コードは上の[tex:d{CODE}]および、上の[tex:D{DATA}]に別々に配置される。
プログラムは、そのライフタイム中にコードを実行するとき、 [tex:d{CODE}] と [tex:d{DATA}] がランダムに決定されるのでそのアドレスを読み取られる可能性が低くなる?
Domain encryptionでは、メモリ中のコード・コードポインタ・データポインタを強力に暗号化する。 これらの要素は固有のドメイン鍵で強力に暗号化されれる。そして、コード・データ・ポインタのタグにより、どの鍵を使って暗号化されるのかが異なる。 私たちのMorpheusの実装では協力なブロック暗号化を導入した。これをQARMAと呼ぶ。
ドメイン暗号化に使用される鍵($K_C, K{CP}, K{DP}$)はマイクロアーキテクチャ上のレジスタに格納され、ソフトウェアから見ることはできない。 各プロセスは固有の鍵を持っている。最後に、カーネルが2種類の鍵を持っている。1つが特権メモリのための鍵で、もう一つはユーザ空間のための鍵である。
アイデアその4. Moving Target Defensesのチャーン
Morpheusでは、上記で説明したドメイン暗号化とポインタディスプレースメントによる防御はCPUの実行時に再ランダム化される。 チャーンユニットはこの再ランダム化の役割を行う。 さらに、チャーンユニットはアドレス空間の安全なコンテキストスイッチングをサポートする。
チャーンの再生成が行われるときに、パイプラインはストールしフラッシュされる。
5. Morpheus アーキテクチャについて
まず、Gem5シミュレータを使ってMorpheusのプロトタイプを作成した。アーキテクチャはGem5 MinorCPU 4-stage インオーダコアとした。
Morpheusの暗号化レイヤはQARMA : 3.25ns (9-cycle latency at 2.5GHz)。さらに、チャーン操作をモデル化するためにDRAMSim2を使用する。 チャーンユニットはGem5とDRAMSim2とのやり取りを行い、タグのスキャンとポインタとコードのアップテートを行う。
5.2 セキュリティ分析
ペネトレーションテストの結果 : RIPEとよばれる制御フロー攻撃のテストスイートを実行した。さらに、自作の攻撃スイートを作成してテストした。 この結果、Morpheusアーキテクチャはすべての攻撃を停止させることができた。
- Morpheusの攻撃分析
Morpheusに実装した防御機構の効果を調査するために、以下の4種類でProbeに必要な時間を計測した。
- : Encryption無効、Pointer Displacement無効
- : Encryption有効、Pointer Displacement無効
- : Encryption無効、Pointer Displacement有効
- : Encryption有効、Pointer Displacement有効
この時の結果が以下のグラフのようになる。の時は一瞬でProbeが完了するが、 になると完了するのに時間がかかるベンチが多い。そしてベンチの特性によって、効果のある防御手法が異なっている。
- チャーン実装によるオーバヘッド
チャーンを定期的に実装することで攻撃者がシステム内部を解析することを防ぐが、このチャーンの定期実行時間を変化させてCPUの性能にどう影響するかを計測する。チャーンの期間が短いと、高い頻度でキャッシュのフラッシュやパイプラインのクリアが行われるためオーバヘッドが大きい。その結果が次のグラフ。
やはりチャーンの期間が短いと性能に対するオーバヘッドが大きい。