RISC-Vプロセッサのセキュリティ課題—アーキテクチャの脆弱性と攻撃リスクの分析

背景

2010 年の夏、カリフォルニア大学バークレー校で新しいオープンソース命令セット RISC-V が誕生し、チップ分野に火花を散らしました。

次の 10 年間で、RISC-V アーキテクチャ設計は、大草原の火を起こすような勢いで学界で開花しました。

たとえば、RISC-V アーキテクチャに基づくさまざまな CPU および DSA チップ設計: Alibaba の Xuantie シリーズ プロセッサ、Berkeley の SonicBoom/Rocket チップ プロセッサ、MIT の riscy-OOO シリーズ プロセッサなど。

RISC-V アーキテクチャは、x86、Arm、Power、その他のアーキテクチャの独占を打破し、より高度な概念要件を備えた次世代の情報技術開発の機会を生み出していると言えます。最近の Embedded World expo で、RISC-V Foundation の CEO である Calista Redmond 氏は、「市場には推定 100 億個の RISC-V コアがある」と述べました。

木は静止しても風は止まらない RISC-Vがビッグデータ、5G、モノのインターネット、VR、エッジコンピューティングなどの多くの先端技術分野に根付くと、命令セット、仮想化設計の完成度が高まる、RAS 拡張機能、セキュリティ アーキテクチャなど。さまざまなアプリケーションの実装で問題が発生し始めます。特にセキュリティ分野の発展に伴い、RISC-V アーキテクチャに基づく SoC のセキュリティをどのように確保するかが、RISC-V アーキテクチャ開発者の焦点となっています。

この記事では、RISC-V プロセッサのセキュリティ構造を簡単に分析し、キャッシュ サイド チャネル攻撃やメモリ攻撃などによる現在のシステム構造の脆弱性を紹介し、 RISC-V コアSonicBoomで POC オンボード テストを実施し、RISC -V プロセッサのセキュリティを検証します。特徴。

キャッシュサイドチャネル攻撃

サイド チャネルは情報窃取の手段として広く使用されており、攻撃者はアルゴリズムの理論上の欠陥を直接攻撃するのではなく、時間測定、消費電力測定、さらには音声を聞くことによって、システムの物理チャネルから機密データを取得します。人々は 20 年以上にわたり、従来のサイドチャネル攻撃に対するソフトウェアおよびハードウェアの防御ソリューションを研究してきました

しかし、マルチコア スーパースカラー プロセッサの急速な発展に伴い、プロセッサ システムに対するサイドチャネル攻撃の新たな亜種が絶えず出現しています

2017 年以降、複数の研究チームが独立して「Spectre」および「Meltdown」の脆弱性とその派生亜種を報告しており、それぞれプロセッサのマイクロアーキテクチャ レベルでの分岐予測やアウトオブオーダー実行などの高パフォーマンスの脆弱性を悪用しています。一時的な命令フローの実行を使用して、ソフトウェアおよびハードウェアのセキュリティ チェックをバイパスしたり、ユーザー情報を盗んだり、より高いレベルで高特権データにアクセスしたりするため、学界や産業界から幅広い注目を集めていますこれらの攻撃は、最新のプロセッサ マイクロアーキテクチャの設計思想に欠陥があることを示しており、それによっていくつかの中核となるセキュリティ上の脆弱性が暴露されます。

一時的な命令フローに基づくキャッシュサイドチャネル攻撃のセキュリティ分析

一時的命令とは、投機的実行状態にあり、最終的にリタイアできるかどうか不明な命令を指しますたとえば、分岐予測テクノロジを使用すると、プロセッサは分岐解決前に投機実行用の特定のコード セグメントを選択でき、投機実行状態にある命令は一時的な命令ストリームと呼ばれます。

一時的な命令ストリームは、後の分岐解決結果で予測が正しかったことが示された場合、最終的に正常にリタイアできます。ただし、予測ミスが見つかった場合は、パイプラインをこれらの一時的な命令の実行前の状態にロールバックする必要があります。理論的には、ロールバックされた一時命令がマイクロアーキテクチャに目に見える影響を与えることはありません。そうしないと、実行されるべきではなかったこれらの命令によってプロセッサに残された痕跡が情報漏洩を引き起こす可能性があります。

残念ながら、プロセッサが一時的な命令ストリームの実行トレースを完全に除去することは困難です。典型的な例としては、一時的な命令ストリームで実行されたメモリ ロード命令がデータの一部をキャッシュに取り込んだ場合、たとえパイプラインが復帰したとしてもです。ロールオーバー中、プロセッサは命令によって返されたメモリ アクセス結果を破棄しますが、変更されたキャッシュ状態を取り消すことはできませんこのことから、攻撃者はキャッシュの変化を監視することで被害プログラムのメモリアクセスアドレスを推測することができ、そのアドレス自体に機密情報が含まれていた場合、情報漏洩の原因となります。上記のプロセスは、一時的な命令フローに基づく一種のキャッシュ サイドチャネル攻撃を構成します。

従来のサイドチャネル攻撃とは異なり、一時的な命令フローに基づくサイドチャネル攻撃は、ハードウェア マイクロアーキテクチャ レベルで一般的なセキュリティ上の欠陥を悪用して機密情報を盗み出します。この種の攻撃はソフトウェア手段では完全に防御できませんこのタイプの攻撃には通常、次の 3 つの特徴があります。

  • 広範囲にわたる影響: 最新のプロセッサのほとんどはキャッシュ構造を備えており、アウトオブオーダー スーパースカラーなどの高性能テクノロジをサポートしているため、主流メーカーのアーキテクチャ設計がこの攻撃の影響を受けます。
  • 高い防御コスト: このタイプの攻撃は現在、学術および業界の保護システム全体のパフォーマンスに大きな影響を与えます。
  • ハードウェア依存性:このタイプの攻撃の実装は、プログラムの実行環境と特定のハードウェア設計に依存し、マイクロアーキテクチャごとに異なる攻撃計画を導き出すことができます。

キャッシュサイドチャネル攻撃の防御方法

「ゴースト」攻撃と「メルトダウン」攻撃は、学界や産業界で幅広い注目と研究を集めています。参考として、現在学界でキャッシュ サイド チャネル攻撃に使用されている防御アイデアの一部を簡単に紹介します。

1. パイプライン内での投機的価値の伝播を防止する

一時的な命令フローに基づくサイドチャネル攻撃は、基本的に、プロセッサ内の誤った投機パスにある値が後続の命令の実行に使用され、最終的に攻撃者がサイドチャネル手段を通じて取得するものです。

したがって、単純な解決策は、プライベート データを含む投機的な値がパイプライン上で伝播するのを防ぐことです実際、フェンスタイプのバリア命令を使用するという業界の初期のソリューションもこの考えに基づいていましたが、単純にバリア命令を使用して後続のすべての命令をブロックすると、投機実行のパフォーマンスに大きな損失が発生します。

したがって、安全でない命令をハードウェア内でよりきめ細かく分割して動的にマークすることで、実行が制限される命令の範囲を狭め、ソリューションのパフォーマンス損失を軽減することが重要な研究方向となっています。 (MICRO'19)、NDA (MICRO'19)、SpectreGuard (DAC'19) およびその他の論文の設計手法。

2. 投機的メモリアクセス命令によるキャッシュ状態の変更を延期する

このタイプのソリューションでは、キャッシュ アーキテクチャに追加のバッファが導入され、投機的実行をまだ回避していないメモリ アクセス命令は、キャッシュではなくバッファにのみ入ることができます推測が正しければ、バッファの値がキャッシュに入力されますが、推測が間違っていれば、バッファの値は破棄され、その結果、キャッシュの状態がメモリ アクセス結果によって変更されるのを防ぎます。間違った推測パス。代表的な作品としては、InvisiSpec (MICRO'18) や SafeSpec (DAC'19) の設計メソッドなどがあります。

3. キャッシュ レベルで異なるセキュリティ ドメイン間でデータを分離する

この方向性は、攻撃者がキャッシュ情報を効果的に測定できないようにキャッシュ アーキテクチャも変更しますが、本質は、攻撃者と攻撃対象者との間のデータ分離を提供することです。基本的な方向には、キャッシュの分割とキャッシュ アドレス マッピングのランダム化が含まれます

その中で、Intel の CAT (Cache Allocation Technology) テクノロジも LLC でのキャッシュ分割メカニズムを提供しており (CAT はもともとマルチコア システムのノイジー ネイバー問題を解決するために導入されました)、一部の研究ではこの構造を借用または利用しています。

4. サイドチャネル攻撃者を動的に特定する

キャッシュ サイド チャネル攻撃者は、通常、同じキャッシュの物理的な場所にアクセスする攻撃者と競合するため、特定のメモリ アクセス パターン (パターン) を示します。ハードウェアが潜在的なサイド チャネル攻撃のメモリ アクセス パターンを識別し、タイムリーな警告を与えることができる場合、攻撃者はデータ漏洩を避けるための措置を講じることができます。たとえば、Cyclone (MICRO '19) における設計手法。

キャッシュサイドチャネル攻撃が再発

以下は、Spectre-v1 (境界チェック バイパス) の攻撃プログラム フラグメントの例です。

if (idx < array1_sz){
        secret = array1[idx]
        dummy = array2[secret * L1_BLOCK_SZ_BYTES];
}

この攻撃は条件付き分岐命令 (RISC-V の bge など) をターゲットにしており、攻撃プロセスは次の段階で構成されます。

  • トレーニングフェーズでは、境界を越えていないデータインデックスidxで上記のコードセグメントが繰り返し実行されるため、PHT(Pattern History Table)に記録される分岐ジャンプの方向がifのコードセグメントになります。この段階では idx 値が配列 array1 のインデックス範囲を超えることはないため、セキュリティ上の問題は発生しません。

  • 攻撃フェーズでは、上記のコード セグメントが範囲外の配列インデックス idx を使用して実行されます。ソフトウェア作成者の観点から見ると、if 条件判定では idx 値が array1 のインデックス範囲を超えてはいけないと規定されているため、この時点ではコードセグメント内のデータアクセスは実行されるべきではなく、プログラムは安全である必要があります。ただし、分岐予測子はすでにトレーニングされているため、ハードウェアは引き続き投機的にコード セグメントの実行に入り、メモリ アドレス空間の別の場所にある境界外の配列インデックス idx を持つプライベート データ シークレットにアクセスします。次に、攻撃者は、投機的実行ウィンドウ内で、補助配列 array2 にアクセスするために、一時的な命令ストリーム内の秘密の値を使用してメモリ アクセス アドレスを構築します。

  • プロセッサの回復フェーズ中に、分岐予測エラーが発見され、プロセッサはパイプラインをロールバックし、上記の命令のメモリ アクセス結果を破棄します。ただし、補助アレイ array2 内の一部のデータは攻撃段階でキャッシュに持ち込まれており、キャッシュ アドレスはプライベート データの秘密に関連付けられていますキャッシュに取り込まれたコンテンツは、パイプラインのロールバックによって取り消されません。

  • データ再構成フェーズでは、攻撃者はキャッシュ内の配列 array2 のさまざまな位置でデータのヒットを測定するだけでよく、その後、攻撃フェーズ中に上記のコード セグメントが配列 2 のどこにアクセスしたかを推測し、特定の値を推測できます。機密情報を漏洩し、データの盗難が完了します。

上記の攻撃プロセスは、ソフトウェアによって設定された境界チェックをバイパスし、プログラム例外をスローすることなく、メモリ アドレス空間の別の場所でプライベート データを取得することがわかります。

以下では、この攻撃を実際のプロセッサ上で再現します。使用する SoC 環境は Chipyard、プロセッサ コアは SonicBoom、FPGA は VCU118 または VC707 を使用します。攻撃のソース コードについては、SonicBOOM https://github.com/riscv-boom/boom-attachs が提供する POC コードを参照してください。

攻撃されたアドレスが保存されました:!「ThisIsTheBabyBoomerTest」

実際の攻撃者は次の情報を取得しました:!「ThisIsTheBabyBoomerTest」

Spectre-v1 の攻撃プログラムが SonicBoom 上で再現されていることがわかります。

メモリデータのセキュリティ

MITRE の最新の統計によると、2022 CWE トップ 25 の最も危険なソフトウェアの弱点 (2022 CWE トップ 25 の最も危険なソフトウェアの弱点) に含まれる脆弱性の 40% はメモリの変更/制御に関連しています。近年、現代のシステムプログラミングではC/C++言語が広く使われており、メモリシステムを操作できるC/C++などの言語の特性により、プログラムの実行速度と効率が大幅に向上し、しかし、多くのメモリの安全性の問題も引き起こします。現在、主流のコンパイラとランタイムは、C/C++ プログラム ポインタに対して静的または動的なセキュリティ チェックを実行しないため、C/C++ でプログラムされたプログラムは攻撃者に対して非常に脆弱になります。

不正なポインタアクセスの種類に応じて、メモリの安全性は主に空間的メモリの安全性と時間的安全性(空間的安全性と時間的安全性)の 2 つのカテゴリに分類されます。

  • 空間安全性違反: ポインタがプログラムのスコープ外のオブジェクトにアクセスすると、メモリ空間の安全性が侵害されます。最も一般的な例は、スタック上のバ​​ッファ オーバーフローを使用して、プログラムの実行フローの方向を導くために攻撃者が設計した値で関数の戻りアドレスを上書きするか、オーバーフローを直接使用して重要な変数や重要な情報を書き換えることです。 。

  • 時間的安全性違反: オブジェクトへの参照が指定された時間範囲外で使用されると、通常はインスタンス化されたオブジェクトのメモリが厳密なメモリ初期化を行わずに再割り当てされた後、メモリの時間的安全性が違反されます。たとえば、無効な (通常は未割り当てまたは解放された) メモリへのポインタの逆参照によって引き起こされる時間安全性違反 (解放後の使用) です。

メモリの安全性はさらに次のように細分化できます。

  • バッファオーバーフロー、
  • ダブル無料、
  • Null ポインタの逆参照、
  • 無効な無料、
  • 未初期化メモリへのアクセス (未初期化メモリの読み取り)、
  • 無料後の使用 (無料後の使用) およびその他のいくつかのサブカテゴリ。

メモリ脆弱性攻撃は主に3段階に分かれる

  • コード埋め込み: 攻撃コード (シェルコード) をターゲット プログラムに埋め込みます。

  • オーバーフロー攻撃: バッファ オーバーフローはパラメータとして特殊な文字列を入力することで実現され、オーバーフロー後のリターン アドレスは攻撃コードの開始アドレスを指します。

  • システムハイジャック: 攻撃コードを実行することでシステムをハイジャックし、制御します。

メモリセキュリティソフトウェア保護技術

メモリ脆弱性攻撃とさまざまなメモリ脆弱性を理解した後、既存のソフトウェア保護テクノロジを紹介しましょう。

より一般的なのは、データ実行保護 (DEP) メカニズムです。その基本原理は、データが配置されているメモリ ページを実行不可能としてマークすることです。プログラムがオーバーフローしてシェルコードに正常に転送されると、プログラムは実行を試みます。データ ページ上の命令を実行すると、CPU は悪意のある命令を実行する代わりに例外をスローします。DEP を有効にすると、データ ページ (デフォルトのヒープ ページ、さまざまなスタック ページ、メモリ プール ページなど) によるコードの実行を効果的に防ぐことができます。

ASLR (Address Space Layout Randomization) テクノロジは、プログラムのロード時に固定ベース アドレスを使用しなくなることで、シェルコードの配置を妨げる保護メカニズムです。画像のランダム化、スタックのランダム化、PEB(ProcessEnvironment Block、プロセス環境ブロック)とTEB(ThreadEnvironmentBlock、スレッド環境ブロック)のランダム化を含む

もう 1 つの効果的な防御メカニズムは Stack Canary メカニズムです。その原理は、関数の実行時に Cookie 情報をスタックの一番下に挿入することです。関数が戻ると、Cookie 情報が正当かどうかが検証されます。正当でない場合は、プログラムは実行を停止します。

仮想記憶システムによる ASLR 機構、DEP (NX/XD) 機構、または Stack Canary 機構により、攻撃者が任意の攻撃コードを挿入して実行することは防止され、プログラムの安全な動作はある程度保護されます。

しかし、より複雑な攻撃コードや攻撃手段に直面すると、これらの保護メカニズムは失敗するという結果に直面することになります。たとえば、リターン指向プログラミング (ROP) では、コード ポインター (リターン アドレスなど) を破損し、複数のガジェットの実行を連鎖させることによって、任意のコードが実行されます。これらの生のバイナリ コードのシーケンスが結合されて、攻撃者が想定した悪意のある攻撃コードが実装されます。

オリジナルのプログラミング言語にいくつかのソフトウェア保護テクノロジーを追加することに加えて、近年、セキュリティに重点を置いた多くのプログラミング言語が登場しています。例えば、Rust言語は高いセキュリティを確保しながらC/C++と同等の性能を実現するという特徴から注目を集めているため、本稿では安全な言語であるRustについて簡単に紹介する。

安全性

Rustは安全性とスピードを第一に考えており、ガベージコレクション機構は備えていませんが、メモリの安全性を実現しています。Rust が C や C++ と異なる点は、強力な安全性が保証されていることです。

Rust は、「unsafe」キーワードを使用して明示的に選択しない限り、完全にメモリセーフです。

Rust の中核となる設計は、コンパイル時のチェックを通じて強制される一連の厳格な安全ルールです。より低レベルの制御をサポートするために、Rust ではプログラマがこれらのコンパイラ チェックをバイパスして安全でないコードを作成できるようにしています。MSRC (Microsoft Security Response Center) が提供する CVE のセキュリティ問題の約 70% はメモリ セキュリティの問題です。彼らは、現在セキュリティ上の問題を引き起こすことが判明しているプログラムが Rust で書かれていれば、メモリの安全性の問題の 70% は存在しなくなると考えています。

ACM SIGPLAN International Conference (PLDI'20) の研究論文では、「Rust言語のセーフコードメカニズムは、メモリの安全性の問題を非常に効果的に回避できる。安定版で見つかったメモリの安全性の問題はすべて、安全でないコードに関連している」と指摘している。

パフォーマンス

C または C++ を主流のプログラミング言語として置き換えるために Rust を使用したい場合は、プログラミング言語のパフォーマンスと制御機能を考慮する必要があります。

Rustには構成可能なランタイムもあり、Rustの標準ライブラリはCやC++言語と同じようにそのプラットフォームをサポートするためにlibcに依存しており、Rust標準ライブラリもオプションであり、オペレーティングシステムなしのプラットフォーム上でRustコンパイルされたプログラムを実行することもできます。

メモリセキュリティハードウェア保護技術

ここでは、参考のために、メモリ セキュリティ ハードウェアを保護するために学術コミュニティで現在使用されているいくつかの技術的アイデアを簡単に紹介します。

1.トリップワイヤーベースの軽減策

このタイプのソリューションは主に、割り当てられたメモリ ブロックの間にレッドゾーンを配置するため、ポインタがレッドゾーン領域にアクセスすると、対応するエラーが発生します。代表的な例としては、Google の AddressSanitizer (ATC'12) や Valgrind のメモリ チェッカー (PLDI'07) があります。

Tripwire の革新的な点は、ソフトウェアに依存して明示的なチェックを実行する Canary (Stack Canary) などのソフトウェア対策とは異なり、メモリ侵入が発生するとすぐにアクティブ化され、シャドウ メモリに依存してチェックが行われることです。

Tripwire は強力なセキュリティを提供しますが、法外な高パフォーマンスのオーバーヘッドをもたらすため、パフォーマンスを重視するデバイスへの導入には適していません。以下の図はREST(ISCA'18)の動作フローチャートです。REST は、プログラムに埋め込まれた非常に大きなランダム値です。ハードウェア ベースのレッドゾーン検出 - シャドウ メモリへの依存を排除​​するために、レッドゾーンをトークンに置き換えます。ロード/ストア命令はすべて、アドレス領域が分離されているかどうかを検出します。

2. ファットポインター

Tripwire メカニズムに加えて、ファット ポインタも業界で人気のある方向性であり、主にオブジェクトのメタデータ (一般にオブジェクトのベース、境界などを指します) を維持し、ポインタに挿入され、ポインタ アドレスとともにインデックス付けされます。一般に、メモリ セキュリティ保護のため、静的コンパイル中および実行時の動的インストルメンテーション中にチェックされます。

ハードバウンド (SOSP'08) は、シャドウ スペースを使用してポインタのアクセス許可を保存します。ポインタが指すアドレスは、バインド間隔全体としての基本プラスサイズです。ソフトバウンド (PLDI'09) およびウォッチドッグ (ISCA'12) は、それぞれのウォッチドッグを生成します。各メモリ割り当ての識別子を使用し、これらの識別子をポインタに関連付け、すべてのメモリ アクセスに識別子が存在することを確認します。包括的な検出を提供するために、Watchdog はハードウェア上でほぼ完全に識別子ベースの識別子を使用します。以下の図は HardBound 設計の概要です。具体的な意味については論文を参照してください。この記事では説明しません。

3. 能力

Capability と Fat ポインタはある程度似ています。ポインタにメタデータを付加することで保護されています。ただし、Capability と Fat ポインタの違いは、変更できない Fat ポインタであることです。各機能は作成と転送のみが可能です。 (子モジュール参照) となり、削除されます。各ポインターの読み取り、書き込み、実行、およびその他の権限もポインターに付加されます。ポインタはインデックスとして機能するだけでなく、アクセス許可を取得する「オブジェクト」のように機能します。

機能に基づいたハードウェア実装もいくつかあり、代表的な設計は CHERI (ISCA'14、Capability Hardware Enhanced RISC 命令) です。メタデータ (境界と権限) はアドレスとインラインで維持されるため、領域、ストレージ、メモリ帯域幅を交換することによる高価なシャドウ テーブル ルックアップが不要になります。以下に、CHERI 設計のいくつかの利点を簡単に説明します。

  • CHERI の抽象保護モデルが提案され、64 ビット MIPS、32/64 ビット RISC-V、および 64 ビット ARMv8-A ISA にそれぞれ実装されました。
  • 正式な ISA モデルを備え、Qemu-CHERI シミュレーションと複数の FPGA プロトタイプをサポート
  • ISA セキュリティ モデルがソフトウェアを通じて確立されていることを確認する
  • システムをサポートする多数のソフトウェア: CHERI Clang/LLVM/LLD、CHERI BSD、C/C++ APP
  • Morello: CHERI ISA アーキテクチャの産業グレードのデモ ボードは、現時点では CHERI プロトタイプ アーキテクチャの唯一の物理実装です。

制御フローの整合性

制御フローハイジャック攻撃は、特定の攻撃ベクトルを構築し、メモリオーバーフローなどのソフトウェアの脆弱性を悪用し、プロセス内の制御データを不正に改ざんすることで、プロセスの制御フローを変更し、事前に構築された攻撃プログラムを実行することで攻撃目的を達成します。バッファ オーバーフロー攻撃の成功は、コンピュータ システムの実行中の制御フローを変更するための効果的な前提条件として使用できます。たとえば、プログラムのリターン アドレス、呼び出し関数の EBP、関数ポインタや GOT の変更などを行うことができます。攻撃プログラムは、悪意のあるコードを実行するために使用され、プログラム全体を崩壊させたり、攻撃者がシステムの一部を制御できるようにして、コンピュータ システム全体のセキュリティ危機を引き起こします。 。したがって、バッファ オーバーフロー攻撃に対する防御は実用上非常に重要です。

W ⊕ 、これはコード再利用攻撃です。最初のコード再利用攻撃は Return-to-libc 攻撃です。システムの libc ライブラリには、システム コールを実行するためのサブルーチンや、攻撃者に役立つ可能性のあるその他の関数が含まれていることが多いため、攻撃を組み立てるためのコードが検索される可能性が最も高くなります。 . .

Return-to-libc 攻撃では、攻撃者はバッファ オーバーフローの脆弱性を悪用してプログラム制御フローをハイジャックし、利用可能なライブラリ関数を選択し、リターン アドレスをそのエントリの場所で上書きし、詳細なスタックの場所の上書きで設計されたパラメータを上書きします。攻撃を完了するために関数に渡されます。

ROP攻撃

Return-to-libc 攻撃は W⊕X 防御手法を回避しますが、その欠点も明らかです。実行できる攻撃プログラムは十分な柔軟性がなく、防御のターゲットになりやすいため、ROP が登場しました。

ROP (Return-Oriented Programming) を使用すると、攻撃者は実行可能領域の保護やコード署名などのセキュリティ防御が存在する場合でもコードを実行できます。この手法では、攻撃者はコール スタックを制御してプログラム制御フローをハイジャックし、マシンのメモリにすでに存在する「ガジェット」と呼ばれる、慎重に選択された一連のマシン命令を実行できます。

各ガジェットは通常、リターン命令 (ret) で終了し、既存のプログラムや共有ライブラリ コード内のサブルーチンに配置されます。これらのガジェットは連鎖的に接続されており、攻撃者が防御されたマシン上で任意のアクションを実行できるようになります。

ROP は引き続きリターン アドレスとパラメーターでスタックを上書きしますが、攻撃者が提供するリターン アドレスは、コード ベース内の任意の点、具体的には ret 命令で終わる任意のコード フラグメント (ガジェット) を指すことができます。


既存の利用可能なライブラリ関数が完全に悪用できない場合でも、特に x86 アーキテクチャの命令セットは非常に高密度であり、ほとんどすべてのランダムなバイト シーケンスが有効なものとして解釈される可能性があるため、ROP はパッチワーク アプローチを使用して完全な攻撃プログラムを組み立てることができます。 x86 命令セット。

ROP 攻撃の焦点は、次の要件を満たす一連のガジェットを見つけることです。

  • ret で終わる必要があります
  • スタックポインタを明示的に変更しません
  • 算術関数や論理関数などの基本的な関数を備えています
  • メモリアクセスやシステムコールなどの複雑な機能を持つ
  • 条件分岐およびループ機能付き(ロジックによるesp値の変更)
  • 上記の条件を満たすガジェットのセットが実行可能プログラム内で見つかる限り、チューリング完全復帰指向マシンが偽装生成されます。

ROP に対する多くの防御策:

  • DynIMA (Dynamic Integrity Measurement and Attestation、動的完全性測定) - ret で終わる連続して実行された各命令シーケンスを検出します。
  • DROP (ROP 悪意のあるコードの検出、リターン指向プログラミングの悪意のあるコードの検出) - 常に特定のメモリ空間を指す、スタックにポップされたリターン アドレスを検出します。
  • 「リターンレス」カーネル - プログラム内のすべての ret 命令を排除するコンパイラ レベルの最適化により、攻撃者が ROP 攻撃を使用できなくなります。
  • ……

JOP攻撃

ROP 攻撃は強力ですが、スタックと ret 命令に依存して制御フローをハイジャックするという欠点もあります。これに基づいて、攻撃者は JOP/COP 攻撃手法を提案しました。

JOP/COP (ジャンプ/呼び出し指向プログラミング) は、スタックとガジェットの検出とリンクの制御フローへの依存をすべて放棄し、一連の間接ジャンプ命令のみを使用します。これにより、ROP に対する Passed all 防御が完全にバイパスされます。

ROP では、ジャンプ指向のプログラムは、メモリにロードされる一連のガジェット アドレスとデータ値で構成されます。ガジェット アドレスは、新しいジャンプ指向のマシンのオペコードに似ています。ROP では、これらのデータはスタックに格納されるため、スタック ポインタはリターン指向のプログラムの「プログラム カウンター」として機能します。


JOP は、esp を使用してガジェット アドレスを参照することに限定されず、制御フローが ret 命令によって駆動されることもありません。代わりに、JOP はディスパッチ テーブルを使用してウィジェットのアドレスとデータを保持します。


「プログラム カウンタ」は、ディスパッチ テーブルを指すレジスタです。制御フローは、一連のガジェットを実行する特別なスケジューラ ガジェットによって駆動されます。呼び出しごとに、スケジューラは仮想プログラム カウンタを進め、関連するウィジェットを開始します。ガジェットの実行が終了すると、ディスパッチャが返されます。


上記はジャンプ指向のプログラムの例であり、ジャンプの順序は 1->6 という数字で表されます。ここでは、edx が pc として使用され、ディスパッチャは単に 4 を加算することによって、ガジェット アドレスの連続テーブル内の次のアドレスに移動します (つまり、f(pc) = pc + 4)。「攻撃」機能は、

  • eax の逆参照
  • アドレスebxの値をeaxに加算します。
  • 結果はアドレス ecx に保存されます。esi
    および edi レジスタは、制御をスケジューラに戻すために使用されます。

防御手段

Control-flow Enforcement Technology (CET) は、特に ROP/COP/JOP などの高度なスタック オーバーフローのためにインテルが提案した命令セット拡張です。それは主に次の 2 つの側面に分けられます。

  • a. シャドウ スタック (SS、シャドウ スタック) は、主に ROP に対する防御方法であり、スタックのリターン アドレスを保護することを目的としています。この防御により、プログラム データ スタックとは別に 2 番目のスタックが作成され、シャドウ スタックが有効になると、CALL 命令がリターン アドレスをデータ スタックとシャドウ スタックにプッシュします。
  • b. 間接支店追跡(IBT、間接支店追跡)は、主に COP/JOP に対する防御手法です。この方法は、プログラム内の間接呼び出しおよびジャンプの実効ターゲット アドレスを識別するために使用される新しい ENDBRANCH 命令を追加することです。この命令と互換性のない古いアーキテクチャでは、そのオペコードは NOP として表現され、プログラムの実行を妨げることはありません。CET をサポートするプロセッサの場合、オペコードは NOP のままであり、追加のハードウェア負担はかかりません。

    制御フロー整合性攻撃に対して、ARM は 2 つの防御ソリューションを提供しています: BTI と PAC:
    a. ポインター認証コード (PAC、ポインター認証コード): ARMV8.3-A 命令セットは、ポインター認証 (PA) メカニズムを追加します。データまたはコードにアクセスする前にその内容を確認するためのポインターとしてのレジスターは、R​​OP 攻撃に対抗することを目的としています。このメカニズムの基本原理は、特別な命令を使用して、64 ビット コンテキスト、ポインタの元の値、および 128 ビット キーに基づく暗号化アルゴリズムを通じて 64 ビット暗号文を取得し、それを切り捨てて暗号文として使用することです。 PAC。ポインタを使用する前に特別な命令を使用してポインタ値を検証します。検証に合格すると、ポインタの上位ビットは元の状態に戻ります。そうでない場合は、ポインタの上位ビットにエラー コードが埋められます。そして、アドレス指定フェーズ中に例外がトリガーされます。
  • b. ブランチターゲット識別 (BTI、Branch Target Identification): BTI は、攻撃を制限するために Armv8.5 で追加されたセキュリティ機能で、主に JOP (ジャンプ指向プログラミング) 攻撃を防御するために使用されます。動作原理は、プロセッサがコンパイル時に BR または BLR 命令の BTI 命令を構成することです。つまり、指定されたジャンプ ターゲットを間接ジャンプ命令に設定します (英語では、ランディング パッド、ランディング ポイントという非常に適切な単語が使用されます)。 。間接ジャンプ先が指定した着地点でない場合、ジャンプ先例外が発生します。ランディング サイトを使用すると、間接ジャンプの対象となる可能性のあるターゲットの数が制限されるため、ガジェットを連鎖させて新しいプログラムを形成することが困難になります。

記憶攻撃が再発する

例として、バッファ オーバーフロー攻撃プログラムの一部を次に示します。

void shellcode() {
  .......
}
int main(int argc, char *argv[]) {
  char buf[8];
  if(argc < 2) {
    printf("Pass an argument, champ!\n");
  }
  strcpy(buf,argv[1]);
  printf(buf);
}
  • コード埋め込みの第 1 段階: 攻撃コード (シェルコード) をターゲット プログラムに埋め込みます。

  • 第 2 段階のオーバーフロー攻撃: バッファ オーバーフローは特殊な文字列をパラメータとして入力することで実現され、オーバーフロー後のリターン アドレスは攻撃コードの開始アドレス (シェルコード開始アドレス) を指します。

  • システムハイジャックの第 3 段階: 攻撃コードを実行してシステムをハイジャックし、制御します。

SoC環境はChipyard、プロセッサコアはSonicBoom、FPGAはVCU118/VC707を使用

これはスタックオーバーフロー攻撃プログラムの出力結果の例で、GDBデバッグではプログラムRAのアドレス(リターンアドレス)を見つけ、スタックオーバーフローによって上書きし、所定の攻撃プログラムにジャンプさせます。アウトプットすることです You win! プログラムのシェルも変更します。

Arm セキュリティ フレームワーク - RISC-V セキュリティ設計の重要なリファレンス システム

上記のセキュリティ脅威に対応して、RISC-V 分野の多くの開発者が独自のソリューションを構築していますが、これらのセキュリティ ソリューションはまだ標準化されていません。Arm アーキテクチャには、高度に標準化されたセキュリティ対策が備わっています。Arm セキュリティ アーキテクチャから学ぶことで、RISC-V の将来のセキュリティ拡張の方向性を考えることができます。ここでは、主に 4 種類のセキュリティ対策を紹介します。

  • 防御実行テクノロジー: これは、制御フロー攻撃、データ アクセス攻撃、およびサイド チャネル攻撃に対する保護テクノロジーのクラスです。ソフトウェアが完璧であることはほとんどなく、一部のプログラムの脆弱性は防御的なプログラミングによって人為的に修復できますが、このアプローチはすべてのコード プログラムに適用できるわけではありません。現在、このようなセキュリティ問題の解決策は主に、ハードウェア、コンパイラ、ランタイムを変更して保護するという 3 つの技術的手段によって行われています。この種のコンテンツについては後で詳しく説明するため、ここでは説明しません。
  • 分離テクノロジー: 明確に定義されたセキュリティ境界は、セキュリティ エンジニアリングの最も基本的な原則の 1 つです。このセキュリティ防御は主にTEE向けに設計された防御分離技術の一種で、代表的な製品としてはArm TrustZone、Intel SGX、Apple Secure Enclave、Penglai Enclave、Keystone Enclaveなどが挙げられます。
  • 共通プラットフォーム セキュリティ サービス: セキュリティの目的で、すべてのデバイスには信頼のルート (RoT) が必要であり、セキュリティ要件の広範なチェックリストに対して検証されます。公開されているフレームワークを使用しないと、製品が攻撃に対して適切に耐性があるかどうかを市場は判断できません。
  • 標準セキュリティ API: コンピューター科学技術の急速な発展に伴い、さまざまなマイクロサービスの反復開発を実行するために開発者によってカスタマイズされた API インターフェイスを使用する顧客がますます増えています。このため、API インターフェースはサービスの機能を接続するだけでなく、データの送信も行うことができ、API のセキュリティ保護がますます重要になっています。2018年の中国華珠情報漏洩事件ではユーザーの個人情報が大量に流出、2019年にはInstagramのAPIインターフェースの脆弱性によるユーザーデータや脆弱性など、API攻撃や脆弱性によるデータ漏洩事故が多発しています。写真が流出した。
    RISC-V エコロジカル チェーン上で完全かつ効果的なコンピューティング セキュリティ アーキテクチャを確立し、技術設計の断片化を軽減する方法は、現在の RISC-V エコロジカル開発において非常に困難かつ緊急の必要性です。

機会と課題

5G テクノロジーの普及により、真の Internet of Everything の時代が到来し、際限のない脆弱性がますます広範囲に影響を与えることになります。セキュリティ保護における既存の欠点はさらに拡大されるでしょう。あらゆるものが攻撃される可能性がある環境では、さまざまな弱点が攻撃者の最初のターゲットになります。X86、Arm、MIPS、その他のアーキテクチャの開発を見ると、アーキテクチャの初期設計ではチップのセキュリティが常に「連絡が取れず」、設計サイクルの後期段階で「パッチ」が追加されます。 RISC-V アーキテクチャはより早く実装されますか? 安全な「堀」を展開して構築しますか? 産業界や学界は、オープンソースの命令セット RISC-V の効率性と利便性をさまざまな例 (高性能プロセッサ、効率的なアクセラレータなど) を通じて証明してきましたが、現在、RISC-V 分野のセキュリティ拡張は依然として積極的に推進されています。 。ミッションクリティカルなシステムでの RISC-V チップの使用が増えるにつれて、セキュリティ手法とセキュリティ開発のライフサイクルにさらに多くの考え方と戦略を導入する方法、および単一ポイントの保護から体系的なグローバル保護に拡張する方法が重要になります。はアーキテクチャ開発者にとって新たな課題です。

おすすめ

転載: blog.csdn.net/weixin_45264425/article/details/132698911