マイクロプロセッサの脆弱性のこれらの危険な悪用と、なぜそこにそれらの多くがあるかもしれない
私たちは、コンピュータプロセッサを、ある単純な命令から次の命令へと完全な規則性をもって進む整然とした機械と考えるのに慣れています。 しかし、真実は、何十年もの間、彼らは順不同で自分の仕事をしてきたし、次に何が来るべきかを推測しているということです。 彼らはもちろん、それで非常に良いです。 実際、投機的実行と呼ばれるこの能力は、過去25年ほどの間にコンピューティング能力の向上の多くを支えてきました。 しかし、3January2018では、現代のコンピューティングのために多くのことを行っていたこのトリックが、今では最大の脆弱性の一つであることを世界
2017年を通じて、Cyberus Technology、Google Project Zero、Graz工科大学、Rambus、Adelaide大学、Pennsylvania大学の研究者と、暗号学者Paul Kocherなどの独立した研究者が、投機的実行を利用した攻撃を別々に解決しました。 私たち自身のグループは、2016年にこれらの攻撃の背後にある元の脆弱性を発見しましたが、すべての部分をまとめたわけではありませんでした。
MeltdownとSpectreと呼ばれるこれらのタイプの攻撃は、普通のバグではありませんでした。 発見された時点で、MeltdownはすべてのIntel x86マイクロプロセッサとIBM Powerプロセッサ、およびいくつかのARMベースのプロセッサをハックすることができました。 Spectreとその多くのバリエーションは、そのリストにAdvanced Micro Devices(AMD)プロセッサを追加しました。 言い換えれば、コンピューティングのほぼ全世界が脆弱でした。
投機的な実行は主にプロセッサハードウェアに焼き付けられているため、これらの脆弱性を修正することは容易な仕事ではありませんでした。 計算速度が低いギアに粉砕されることなくそうすることは、それをさらに困難にしました。 実際には、上の年、仕事は終わってから遠いです。 セキュリティパッチは、プロセッサメーカーだけでなく、Apple、Dell、Linux、Microsoftなどのサプライチェーンのさらに下のものからも必要でした。 これらの脆弱性のいくつかにも耐性があるように意図的に設計されたチップを搭載した最初のコンピュータは、ごく最近になって到着しました。
SpectreとMeltdownは、ソフトウェアが何をすべきかとプロセッサのマイクロアーキテクチャとの違い、つまり実際にどのようにそれらのことを行うかの詳細の これらの2つのクラスのハッキングは、その違いによって情報が漏れる方法を明らかにしました。 そして、より多くの方法が発見されると信じるあらゆる理由があります。 私たちは昨年、BranchscopeとSpectreRSBの二つを見つけるのを助けました。
セキュリティを犠牲にせずにコンピューティングの改善のペースを維持するつもりなら、これらのハードウェアの脆弱性がどのように起こるかを理解 そして、それは幽霊とメルトダウンを理解することから始まります。
現代の計算機システムでは、C++などの人間が理解できる言語で書かれたソフトウェアプログラムは、コンピュータプロセッサが実行できるアセンブリ言語の命令にコンパイルされる。 実行を高速化するために、最新のプロセッサはパイプラインと呼ばれるアプローチを使用します。 組立ラインと同様に、パイプラインは一連の段階であり、それぞれが命令を完了するために必要なステップです。 Intel x86プロセッサの典型的なステージには、メモリから命令を取り込み、命令が何を意味するのかを理解するためにデコードするステージがあります。 ある命令がステージを使用して実行されると、次の命令はそれを自由に使用することができます。
1990年代以降、マイクロプロセッサはパイプラインプロセスを高速化するために、アウトオブオーダー実行と投機の二つのトリックに依存してきました。 2つの命令が互いに独立している場合、つまり1つの命令の出力が別の命令の入力に影響を与えない場合、順序を変更することができ、その結果は正 これは、命令がパイプラインで停止した場合にプロセッサが動作し続けることを可能にするので、便利です。 たとえば、命令がCPU自体にあるキャッシュメモリではなくDRAMメインメモリに出力されるデータを必要とする場合、そのデータを取得するには数百クロックサ 待機する代わりに、プロセッサはパイプラインを介して別の命令を移動することができます。
第二のトリックは憶測です。 それを理解するには、いくつかの指示が必然的に指示が次に来る変更につながるという事実から始めます。 条件をチェックし、条件が真であれば、プロセッサはプログラム内の別の場所にジャンプします。 これは条件分岐命令の例ですが、命令の流れの変化につながる他の命令もあります。
このような分岐命令がパイプラインに入ったときに何が起こるかを考えてみましょう。 それは難問につながる状況です。 命令がパイプラインの先頭に到着すると、パイプラインのかなり深く進行するまで、その結果はわかりません。 そして、この結果を知らずに、私たちは次の命令を取得することはできません。 単純だが素朴な解決策は、分岐命令が次の命令がどこから来るかを知っているポイントに達するまで、新しい命令がパイプラインに入るのを防ぐこ パイプラインには通常15~25段階があるため、このプロセスでは多くのクロックサイクルが無駄になります。 さらに悪いことに、分岐命令はかなり頻繁に出てきて、多くのプログラムのすべての命令の20%以上を占めています。
パイプラインを失速させるという高いパフォーマンスコストを避けるために、現代のプロセッサは分岐予測子と呼ばれるアーキテクチャ単位を使用して、分岐の後の次の命令がどこから来るのかを推測する。 この予測子の目的は、いくつかの重要な点について推測することです。 まず、条件分岐が取られ、プログラムがプログラムの別のセクションに振り向くのを引き起こしますか、それとも既存のパス上で続行されますか? そして第二に、ブランチが取られれば、プログラムはどこに行くのでしょうか—次の命令は何でしょうか? これらの予測で武装して、プロセッサパイプラインを完全に保つことができます。
命令の実行は予測に基づいているため、”投機的に”実行されています。 しかし、予測が間違っていることが判明した場合、プロセッサは推測的に実行された命令の効果を比較的迅速に元に戻すことができなければな
分岐予測子の設計は、長年にわたりコンピュータ-アーキテクチャ-コミュニティで堅牢に研究されてきました。 現代の予測子は、結果の基礎としてプログラム内の実行履歴を使用します。 この方式は、多くの異なる種類のプログラムで95%を超える精度を達成し、推測しないマイクロプロセッサと比較して劇的な性能向上につながります。 しかし、Misspeculationは可能です。 そして残念なことに、それは幽霊の攻撃が悪用するmisspeculationです。
問題を引き起こしたもう一つの形の投機は、パイプライン内の単一の命令内の投機である。 それはかなり難解な概念なので、それを解凍しましょう。 命令を実行するには権限が必要であるとします。 たとえば、命令は、オペレーティングシステムのコア用に予約されているメモリの部分にデータの塊を書き込むようにコンピュータに指示することがで あなたはそれがオペレーティングシステム自体によって認可されていない限り、それが起こることを望んでいない、またはあなたがコンピ MeltdownとSpectreが発見される前は、プロセッサが命令がその作業を行う許可を持っているかどうかをチェックするポイントに達する前であっても、命令の
最後に、許可が満たされていない場合—この例では、オペレーティングシステムがこのメモリをいじる試みを認可していません—結果はスローされ、プログ 一般に、プロセッサは、条件が最終的に解決され、悪い推測からの結果が効果的に取り消される限り、命令の任意の部分を待機させる可能性がある命令の任意の部分を推測することができる。 間違いなくより危険なバージョンを含む、Meltdownバグのすべての変種の背後にあるのは、このタイプの命令内の推測です。
投機攻撃を可能にする洞察はこれです:ミススペキュレーションの間、プログラムが直接観察できる変化は発生しません。 言い換えれば、投機的実行中に生成されたデータを単純に表示するプログラムはありません。 しかし、投機が発生しているという事実は、命令の実行にかかる時間に影響を与えることによって痕跡を残します。 そして、残念ながら、それは我々がこれらのタイミング信号を検出し、それらから秘密のデータを抽出することができることが明らかになりました。
このタイミング情報は何ですか、ハッカーはどのようにそれを把握しますか? それを理解するには、サイドチャネルの概念を把握する必要があります。 サイドチャネルは、通常、ハードドライブやメモリなどの共有リソースを介して、あるエンティティから別のエンティティに情報を漏らす意図しない経路です(通常は両方ともソフトウェアプログラムです)。
サイドチャネル攻撃の例として、プリンタから発せられる音を聞き、その音を使って印刷されているものを推測するようにプログラムされたデバ この場合、音はサイドチャンネルです。
マイクロプロセッサでは、任意の共有ハードウェアリソースを、原則として、被害者プログラムから攻撃者プログラムに情報を漏らすサイドチャネルとし 一般的に使用されるサイドチャネル攻撃では、共有リソースはCPUのキャッシュです。 キャッシュは、プログラムによって最も頻繁に必要とされるデータを格納するために使用されるプロセッサチップ上の比較的小さな高速アクセ プログラムがメモリにアクセスすると、プロセッサはまずキャッシュをチェックし、データが存在する場合(キャッシュヒット)、迅速に回復されます。 データがキャッシュにない場合(ミス)、プロセッサはメインメモリからフェッチされるまで待たなければならず、数百のクロックサイクルを取ることが しかし、データがメインメモリから到着すると、それはキャッシュに追加され、スペースを確保するために他のデータを捨てる必要があるかもしれません。 キャッシュはキャッシュセットと呼ばれるセグメントに分割され、メインメモリ内の各場所にはキャッシュ内に対応するセッ この組織は、何かが全体を検索することなく、キャッシュ内にあるかどうかを確認することが容易になります。
キャッシュベースの攻撃は、SpectreとMeltdownが現場に登場する前から広範囲に研究されていました。 攻撃者は被害者のデータを直接読み取ることはできませんが、そのデータがキャッシュのような共有リソースに格納されている場合でも、被害者がアクセ これらのアドレスは機密データに依存する可能性があり、巧妙な攻撃者がこの秘密データを回復することができます。
攻撃者はこれをどのように行いますか? いくつかの可能な方法があります。 FlushとReloadと呼ばれるバリエーションの1つは、攻撃者が”flush”命令を使用してキャッシュから共有データを削除することから始まります。 その後、攻撃者は被害者がそのデータにアクセスするのを待ちます。 キャッシュ内にないため、被害者が要求するデータはすべてメインメモリから取り込む必要があります。 その後、攻撃者はこれにかかる時間のタイミングを合わせながら共有データにアクセスします。 キャッシュヒット(データがキャッシュに戻ったことを意味します)は、被害者がデータにアクセスしたことを示します。 キャッシュミスは、データがアクセスされていないことを示します。 そのため、データにアクセスするのにかかった時間を測定するだけで、攻撃者は被害者がどのキャッシュセットにアクセスしたかを判断できます。 これは、アルゴリズムの魔法のビットを取りますが、キャッシュセットにアクセスされたとされていなかったのこの知識は、暗号化キーやその他の秘密の発見につながることができます。
Meltdown、Spectre、およびそれらの変種はすべて同じパターンに従います。 まず、攻撃者が望むコードを実行するための推測をトリガーします。 このコードは、許可なしに秘密のデータを読み取ります。 その後、攻撃はFlushとReloadまたは同様のサイドチャネルを使用して秘密を通信します。 その最後の部分はよく理解されており、すべての攻撃のバリエーションで似ています。 したがって、攻撃は、投機を誘発して悪用する方法である最初の要素のみが異なります。
メルトダウン攻撃
メルトダウン攻撃は、単一の命令内で投機を悪用します。 アセンブリ言語の命令は一般的に単純ですが、単一の命令は、多くの場合、互いに依存することができる複数の操作で構成されています。 たとえば、メモリ読み取り操作は、多くの場合、読み取り中のメモリアドレスに関連付けられた権限を満たす命令に依存します。 アプリケーションには、通常、オペレーティングシステムや他のユーザーのプログラムに割り当てられたメモリからではなく、割り当てられたメモリから 論理的には、読み取りを続行する前にアクセス許可を確認する必要があります。 しかし、最終的な結果が正しければ、CPU設計者は、これらの操作を順不同で推測的に実行することは自由であると仮定しました。 したがって、インテルのマイクロプロセッサは、権限をチェックする前にメモリ位置を読み取りますが、権限が満たされたときには、命令を”コミット”し、結果をプログラムに表示させます。 しかし、秘密のデータは推測的に取得されているため、サイドチャネルを使用して発見することができ、Intelプロセッサはこの攻撃に対して脆弱です。
伏線攻撃はメルトダウンの脆弱性のバリエーションです。 この攻撃は、IntelがL1Terminal Fault(L1TF)と呼ぶ弱点のためにIntelマイクロプロセッサに影響を与えます。 元のメルトダウン攻撃は、アクセス許可のチェックの遅延に依存していましたが、Foreshadowはアドレス変換と呼ばれるパイプラインの段階で発生する推測に依存しています。
ソフトウェアは、コンピュータのメモリとストレージ資産を、単一の連続した仮想メモリとして認識します。 しかし、物理的には、これらの資産は分割され、異なるプログラムやプロセス間で共有されます。 アドレス変換は、仮想メモリアドレスを物理メモリアドレスに変換します。
マイクロプロセッサ上の特殊な回路は、仮想メモリアドレスから物理メモリアドレスへの変換に役立ちますが、速度が遅くなり、複数のメモリルックア 処理を高速化するために、インテルのマイクロプロセッサは、変換プロセス中に投機を可能にし、プログラムがそのデータを所有している人に関係なく、L1と呼ばれるキャッシュの一部の内容を投機的に読み取ることを可能にします。 攻撃者はこれを行い、既に説明したサイドチャネルアプローチを使用してデータを開示することができます。
いくつかの点で、伏線はメルトダウンよりも危険であり、他の点ではそれほど危険ではありません。 Meltdownとは異なり、ForeshadowはIntelのプロセッサアーキテクチャの実装の詳細のために、L1キャッシュの内容のみを読み取ることができます。 ただし、Foreshadowは、プログラムによってアドレス指定可能なデータだけでなく、L1内の任意の内容を読み取ることができます。
Spectre Attacks
spectre attacksは分岐予測システムを操作します。 このシステムには、分岐方向予測子、分岐ターゲット予測子、および戻りスタックバッファの三つの部分があります。
分岐方向予測子は、プログラミング言語で”if”文を実装するために使用されるような条件分岐が取られるかどうかを予測します。 これを行うために、類似したブランチの以前の動作を追跡します。 たとえば、ブランチが連続して2回取られた場合、将来の予測では、それが取られるべきであると言うことを意味するかもしれません。
分岐ターゲット予測子は、間接分岐と呼ばれるもののターゲットメモリアドレスを予測します。 条件分岐では、次の命令のアドレスがスペルアウトされますが、間接分岐ではそのアドレスが最初に計算されなければなりません。 これらの結果を予測するシステムは、branch-target bufferと呼ばれるキャッシュ構造です。 基本的には、間接分岐の最後に計算されたターゲットを追跡し、これらを使用して次の間接分岐がどこにつながるかを予測します。
リターンスタックバッファーは、”return”命令のターゲットを予測するために使用されます。 プログラム中にサブルーチンが”呼び出された”とき、return命令は、サブルーチンが呼び出された時点でプログラムを再開させます。 同じ関数がコード内のさまざまな場所から呼び出される可能性があるため、以前の戻りアドレスのみに基づいて戻る正しい点を予測しようとすると、 代わりに、システムは、関数が呼び出されたときに関数のリターンアドレスを保持するリターンスタックバッファー、プロセッサ上のメモリの一部を使用し 次に、サブルーチンのコードで戻り値が検出されたときに、これらのアドレスを使用します。
これら3つの構造のそれぞれは、2つの異なる方法で利用することができます。 まず、予測子を意図的にミストレーニングすることができます。 この場合、攻撃者はシステムを混乱させるように設計された一見無実のコードを実行します。 その後、攻撃者は意図的にミススペキュレートするブランチを実行し、攻撃者が選択したガジェットと呼ばれるコードにプログラムをジャンプさせます。 ガジェットは、データを盗むことについて設定します。
幽霊攻撃の第二の方法は、直接注入と呼ばれています。 いくつかの条件下では、3つの予測子が異なるプログラム間で共有されていることが判明しました。 これが意味することは、攻撃側のプログラムが実行中に慎重に選択された不良データで予測子構造を埋めることができるということです。 無意識の被害者が攻撃者と同時に、またはその後にプログラムを実行すると、被害者は攻撃者によって入力された予測子状態を使用して、無意識のうちにガジェットをオフに設定します。 この第二の攻撃は、被害者プログラムが別のプログラムから攻撃されることを可能にするため、特に心配です。 このような脅威は、クライアントのデータが保護されていることを保証できないため、クラウドサービスプロバイダーに特に損害を与えます。
SpectreとMeltdownの脆弱性は、ハードウェアに起因する脆弱性であるため、コンピューティング業界に難問を提示しました。 場合によっては、インストールされているサーバーやPcの大部分を構成する既存のシステムに対してできる最善のことは、ソフトウェアを書き直して被害を制限しようとすることです。 しかし、これらのソリューションは、アドホック、不完全であり、多くの場合、コンピュータのパフォーマ 同時に、研究者やCPU設計者は、セキュリティを損なうことなく推測を維持する将来のCpuを設計する方法について考え始めています。
kernel page-table isolation(KPTI)と呼ばれる一つの防御は、Linuxや他のオペレーティングシステムに組み込まれています。 各アプリケーションは、コンピュータのメモリと記憶域資産を、単一の連続した仮想メモリとしてすべて独自に表示することを思い出してくださ しかし、物理的には、これらの資産は分割され、異なるプログラムやプロセス間で共有されます。 ページテーブルは基本的にオペレーティングシステムのマップであり、仮想メモリアドレスのどの部分がどの物理メモリアドレスに対応するかを カーネル-ページ-テーブルは、オペレーティングシステムのコアに対してこれを行う責任があります。 KPTIおよび同様のシステムは、ユーザーのプログラム(および潜在的に攻撃者のプログラム)が実行されているときに、OSなどのメモリ内の秘密データにアクセ これは、禁止されている部分をページテーブルから削除することによって行います。 そうすれば、投機的に実行されたコードでさえ、データにアクセスできません。 ただし、この解決策は、オペレーティングシステムが実行時にこれらのページをマップし、後でマップを解除するための余分な作業を意味します。
別のクラスの防御は、プログラマに危険な投機を制限するためのツールのセットを与えます。 たとえば、GoogleのRetpolineパッチは、Spectre Variant2に脆弱なブランチの種類を書き換えて、投機に良性の空のガジェットをターゲットにさせるようにします。 プログラマは、条件分岐に続く投機的メモリ読み取りを制限することによって、Spectre v1を制限するアセンブリ言語命令を追加することもできます。 便利なことに、この命令はプロセッサアーキテクチャに既に存在しており、異なるプロセッサコアで発生するメモリ操作間で正しい順序を強制するために使用されます。
プロセッサ設計者として、IntelとAMDは通常のソフトウェアパッチよりも深く行かなければならなかった。 彼らの修正は、プロセッサのマイクロコードを更新します。 マイクロコードは、通常のソフトウェアのアセンブリ言語とプロセッサの実際の回路の間に収まる命令の層です。 マイクロコードは、プロセッサが実行できる一連の命令に柔軟性を追加します。 また、マイクロコードを使用すると、複雑な命令がパイプラインで実行しやすい複数の単純な命令に変換されるため、CPUの設計が簡単になります。
基本的に、IntelとAMDは、投機を制限する方法でいくつかのアセンブリ言語命令の動作を変更するようにマイクロコードを調整しました。 たとえば、インテルのエンジニアは、オペレーティングシステムが特定の状況で分岐予測子構造を空にできるようにすることで、攻撃の一部を妨害す
別のクラスの解決策は、サイドチャネルを使用してデータを送信する攻撃者の能力を妨害しようとします。 たとえば、MITのDAWG技術は、プロセッサキャッシュを安全に分割して、異なるプログラムがリソースを共有しないようにします。 最も野心的には、投機専用であり、プロセッサのキャッシュや他のハードウェアから分離されたCPU上の構造を導入する新しいプロセッサアーキテクチャの提案がある。 このようにして、投機的に実行されるが、最終的にコミットされない操作は決して表示されません。 投機結果が確認されると、投機データはプロセッサの主な構造に送信されます。
投機的な脆弱性は、20年以上にわたってプロセッサに休止状態にあり、誰もが知っている限り、未開発のままでした。 彼らの発見は、大幅に業界を揺るがし、サイバーセキュリティは、ソフトウェアシステムのためだけでなく、ハードウェアのためだけでなく、どのように問題であるかを強調しています。 最初の発見以来、幽霊とメルトダウンのダースの変種の周りに明らかにされており、それはより多くがある可能性があります。 SpectreとMeltdownは、結局のところ、私たちがコンピュータのパフォーマンスを向上させるために依存してきたコア設計原則の副作用であり、現在のシステム設計ではそのような脆弱性を排除することを困難にしています。 新しいCPU設計は、これらの攻撃を可能にするサイドチャネルリークのタイプを防止しながら、憶測を保持するように進化する可能性があります。 それにもかかわらず、プロセッサチップを設計するものを含む将来のコンピュータシステム設計者は、彼らの決定のセキュリティへの影響を認識し、もはやパフォーマンス、サイズ、および電力のみを最適化する必要があります。
著者について
Nael Abu-Ghazalehはカリフォルニア大学リバーサイド校のコンピュータ工学プログラムの議長です。 Dmitry Evtyushkinは、バージニア州ウィリアムズバーグのウィリアム-アンド-メアリー大学のコンピュータサイエンスの助教授です。 Dmitry Ponomarevは、ビンガムトンのニューヨーク州立大学のコンピュータサイエンス教授です。
さらに調べるために
Paul KocherとSpectreをまとめて開示した他の研究者は最初にここでそれを説明しました。 Moritz LippはUsenix Security’18でのこの講演でMeltdownを説明しました。 伏線は、同じ会議で詳述されました。
著者の一人を含む研究者のグループは、追加の潜在的な攻撃を明らかにするSpectreおよびMeltdown攻撃の体系的な評価を考え出しました。 IBMのエンジニアは同様のことをしましたが、Googleのエンジニアは最近、サイドチャネルと投機的実行攻撃がここにとどまるという結論に達しました。