概要
1. はじめに
2. 背景
3. 脅威モデル
4. タグ漏洩ガジェットの発見
5. TIKTAGガジェット
6. 実世界攻撃
6.1. Chromeへの攻撃
7. 評価
8. 関連研究
9. 結論と参考文献
\
MTEベースの緩和策におけるTIKTAGガジェットの悪用可能性を実証するため、本セクションではChromeとLinuxカーネルに対する2つの実世界攻撃を開発する(図9)。TIKTAGガジェットを使用した実世界攻撃の実行にはいくつかの課題がある。第一に、TIKTAGガジェットはターゲットアドレス空間で実行される必要があり、攻撃者はターゲットシステムからガジェットを構築または発見する必要がある。第二に、攻撃者はタグチェック結果を漏洩させるためにキャッシュ状態を制御および観察する必要がある。以下では、2つの実世界システム(Google Chromeブラウザ(§6.1)とLinuxカーネル(§6.2))でTIKTAGガジェットを使用した実世界攻撃を実証し、緩和策について議論する。
\ 6.1. Chromeへの攻撃
ブラウザ ウェブブラウザは、JavaScriptやHTMLなどの信頼できないウェブコンテンツを処理するため、ウェブベース攻撃の主要な攻撃対象である。まず脅威モデル(§6.1.1)の概要を説明し、V8 JavaScriptエンジンで構築されたTIKTAGガジェットを提供する(§6.1.2)。次に、ブラウザの悪用におけるTIKTAGガジェットの有効性を実証し(§6.1.3)、緩和戦略について議論する(§6.1.4)。
\ ==6.1.1. 脅威モデル== Chromeブラウザ攻撃の典型的な脅威モデルに従い、攻撃者はレンダラープロセスのメモリ破損脆弱性を悪用することを目指す。被害者ユーザーが攻撃者制御のウェブサイトにアクセスし、悪意のあるウェブページを提供されると仮定する。ウェブページには細工されたHTMLとJavaScriptが含まれており、被害者のレンダラープロセスのメモリ破損脆弱性を悪用する。ASLR [18]、CFI [15]、サイト分離[53]、V8サンドボックス[56]を含む、Chromeの最新の緩和技術がすべて導入されていると仮定する。さらに、直交する防御として、レンダラープロセスがPartitionAlloc [2]でランダムMTEタギングを有効にしていると仮定する。
\ ==6.1.2. TIKTAGガジェットの構築== V8 JavaScript環境では、TIKTAG-v2が正常に構築され、任意のメモリアドレスのMTEタグを漏洩させた。ただし、BRとCHECK間の厳密なタイミング制約が投機的V8サンドボックスエスケープ技術(§A)で実現不可能だったため、構築可能なTIKTAG-v1ガジェットは見つからなかった。
V8 TikTag-v2ガジェット 図8は、V8 JavaScriptエンジンで構築されたTIKTAG-v2ガジェットとJITコンパイル後の疑似Cコードである。このガジェットにより、攻撃者は推測されたタグTgがtarget_addrに割り当てられたタグTmと一致するかどうかを知ることができる。攻撃者は3つの配列、slow、victim、probe、およびidx値を準備する。slowは長さ64のUnit8Arrayであり、分岐予測ミスをトリガーするためにBRでアクセスされる。victimは長さ64のFloat64Arrayであり、ストア・トゥ・ロードフォワーディングをトリガーするためにアクセスされる。probeは長さ512のUint8Arrayであり、
\ TESTでタグチェック結果を漏洩させるためにアクセスされる。Number型のidx値は、victimの範囲外アクセスに使用される。idx値は、victim[idx]が推測されたタグTgを持つtarget_addrを指すように選択される(すなわち、(Tg«56)|target_addr)。V8サンドボックスの外側のtarget_addrに投機的にアクセスするため、研究中に発見した投機的V8サンドボックスエスケープ技術を活用した。詳細は§Aに記載する。図8aの8行目は、TIKTAG-v2ガジェットのBRブロックであり、slow[0]で分岐予測ミスをトリガーする。
\ 12〜13行目はCHECKブロックであり、victim[idx]でストア・トゥ・ロードフォワーディングを実行し、推測されたタグTgでtarget_addrにアクセスする。このコードがJITコンパイルされると(図8b)、idxとvictim.lengthを比較する境界チェックが実行される。idxが範囲外のインデックスの場合、コードはundefinedを返すが、victim.lengthフィールドの読み込みに時間がかかる場合、CPUは後続のストアおよびロード命令を投機的に実行する。
\ その後、17行目はTESTブロックを実装し、フォワードされた値valをインデックスとしてprobeにアクセスする。再度、probeの長さに対するvalの境界チェックが先行するが、PROBE_OFFSETがprobe配列の長さより小さいため、このチェックは成功する。その結果、probe[PROBE_OFFSET]は、ストア・トゥ・ロードフォワーディングが成功した場合、つまりTgがTmと一致する場合にのみキャッシュされる。
\ ==6.1.3. Chrome MTEバイパス攻撃== 図9aは、TIKTAGガジェットの任意のタグ漏洩プリミティブを使用したChromeブラウザへの全体的なMTEバイパス攻撃を示している。レンダラープロセスにバッファオーバーフロー脆弱性があると仮定する。時間的脆弱性(例:use-after-free)の悪用はほぼ同じである。この脆弱性は、脆弱なオブジェクト(すなわち、objvuln)へのポインター(すなわち、vuln_ptr)をオーバーフローさせ、隣接するオブジェクト(すなわち、objtarget)を破損させる。
\ PartitionAllocのMTE適用により、2つのオブジェクトは14/15の確率で異なるタグを持つ。例外を発生させないために、攻撃者はobjvulnとobjtargetのタグが同じであることを確認する必要がある。TIKTAG-v2を利用して、objvulnのタグ(1)とobjtargetのタグ(2)を漏洩させることができる。漏洩したタグの両方が同じ場合、攻撃者は脆弱性を悪用し、タグチェックエラーを発生させない(3)。そうでない場合、攻撃者はobjtargetを解放して再割り当てし、タグが一致するまで最初のステップに戻る。
\ ==キャッシュサイドチャネルのトリガー== TIKTAGガジェットを正常に悪用するには、攻撃者は次の要件を満たす必要がある:
i) 分岐トレーニング、
ii) キャッシュ制御、
iii) キャッシュ測定。これら3つの要件はすべてJavaScriptで満たすことができる。
まず、攻撃者は、ゼロでないslow[0]と範囲内のidxでガジェットを実行することにより分岐予測器をトレーニングし、ゼロ値のslow[0]と範囲外のidxでBRの分岐予測ミスをトリガーできる。
第二に、攻撃者はJavaScriptキャッシュ削除技術[8、21、70]を使用して、slow[0]、victim.length、およびprobe[PROBE_OFFSET]のキャッシュラインを削除できる。
第三に、攻撃者はSharedArrayBuffer [16、58]に基づく高解像度タイマーを使用して、probe[PROBE_OFFSET]のキャッシュステータスを測定できる。
\ ==メモリ破損脆弱性の悪用== 漏洩したMTEタグが与えられると、攻撃者はレンダラー内の空間的および時間的メモリ破損脆弱性を悪用できる。攻撃戦略は従来のメモリ破損攻撃とほぼ同じだが、漏洩したタグを利用して脆弱性がタグチェックエラーを発生させないことを確認する必要がある。攻撃戦略の詳細は§Cで説明する。
\ ==6.1.4. 緩和策== ブラウザレンダラープロセスでのTIKTAGガジェットベースのMTEバイパス攻撃を緩和するために、次の緩和策を採用できる:
i) 投機的実行を考慮したサンドボックス: V8サンドボックスのようなサンドボックス環境からTIKTAGベースの攻撃を開始するのを阻止するために、サンドボックスのメモリ領域を超える投機的メモリアクセスを防止することでサンドボックスを強化できる。最新のウェブブラウザは、信頼できないウェブコンテンツをレンダラーから分離するためにサンドボックスを採用しているが、投機的パスを見落とすことが多い。
\ たとえば、Chrome V8サンドボックス[56]とSafari Webkitサンドボックス[1]は、投機的パス[27]を完全に仲介しない。現在のポインター圧縮技術[64]に基づいて、ポインターの上位ビットをマスクすることにより、投機的パスをサンドボックス領域に制限できる。
\ ii) 投機バリア: §5で提案されているように、潜在的なTIKTAGガジェットのBRの後に投機バリアを配置することで、投機的タグ漏洩攻撃を防ぐことができる。ただし、この緩和策は、パフォーマンスが重要なブラウザ環境では適用できない可能性があり、大幅なパフォーマンスオーバーヘッドが発生する可能性がある。
\ iii) ガジェット構築の防止:§5.2で提案されているように、TIKTAG-v2ガジェットは、ストア命令とロード命令の間に命令をパディングすることで緩和できる。悪用可能なTIKTAGv1ガジェットは見つかっていないが、§5.1で説明されているように、分岐とメモリアクセスの間に命令をパディングすることで緩和できる。
\ 6.2. Linuxカーネルへの攻撃
ARM上のLinuxカーネルは、モバイルデバイス、サーバー、IoTデバイスで広く使用されており、魅力的な攻撃ターゲットとなっている。カーネルのメモリ破損脆弱性を悪用すると、ユーザーの権限を昇格させることができるため、MTEはLinuxカーネルにとって有望な保護メカニズムである。Linuxカーネルに対するTIKTAGベースの攻撃は、ブラウザ攻撃(§6.1)とは異なる独特の課題を提起する。
\ これは、攻撃者のアドレス空間がガジェットが実行されるカーネルのアドレス空間から分離されているためである。以下では、まずLinuxカーネルの脅威モデル(§6.2.1)の概要を説明し、Linuxカーネルで発見した概念実証TIKTAGガジェットを提供する(§6.2.2)。最後に、Linuxカーネル脆弱性の悪用におけるTIKTAGガジェットの有効性を実証する(§6.2.3)。
\ ==6.2.1. 脅威モデル== ここでの脅威モデルは、カーネルに対する典型的な権限昇格攻撃の脅威モデルとほぼ同じである。具体的には、デフォルトのカーネル保護(例:KASLR、SMEP、SMAP、CFI)で強化されたARMベースのAndroid Linuxカーネルに焦点を当てる。さらに、カーネルは、本番環境対応のMTEソリューションであるScudo [3]に類似したMTEランダムタギングソリューションで強化されていると仮定する。
\ 具体的には、各メモリオブジェクトはランダムにタグ付けされ、オブジェクトが解放されるときにランダムなタグが割り当てられ、それにより空間的および時間的メモリ破損の両方が防止される。攻撃者は非特権プロセスを実行でき、カーネルのメモリ破損脆弱性を悪用して権限を昇格させることを目指す。攻撃者はカーネルメモリ破損脆弱性を知っているが、カーネルメモリのMTEタグを知らないと仮定する。タグが一致しないカーネルオブジェクト間でメモリ破損をトリガーすると、
\ タグチェックエラーが発生し、実世界の悪用には望ましくない。この攻撃における重要な課題の1つは、ガジェットが既存のカーネルコードを再利用して構築され、攻撃者が呼び出すことができるシステムコールによって実行される必要があることである。ARMv8アーキテクチャはユーザーとカーネルのページテーブルを分離するため、ユーザー空間ガジェットはカーネルメモリに投機的にアクセスできない。このセットアップは、攻撃者提供のコードを利用してガジェットを構築したブラウザ攻撃(§6.1)の脅威モデルとは大きく異なる。eBPFベースのガジェット構築[17、28]も除外した。なぜなら、eBPFは非特権Androidプロセスでは利用できないためである[33]。
\ ==6.2.2. カーネルTikTagガジェット== §4.1で説明されているように、TIKTAGガジェットはいくつかの要件を満たす必要があり、各要件はカーネル環境で課題を伴う。
まず、BRでは、ユーザー空間から制御可能なcond_ptrで分岐予測ミスをトリガーする必要がある。最近のAArch64プロセッサはユーザーとカーネル間の分岐予測トレーニングを分離しているため[33]、分岐トレーニングはカーネル空間から実行する必要がある。
第二に、CHECKでは、guess_ptrを逆参照する必要がある。guess_ptrは、推測タグ(Tg)を埋め込み、タグ(Tm)を漏洩させるためにカーネルアドレス(すなわち、target_addr)を指すように、ユーザー空間から作成される必要がある。ブラウザJavaScript環境(§6.1)とは異なり、ユーザー提供のデータはシステムコールで厳重にサニタイズされるため、任意のカーネルポインターを作成することは困難である。
\ たとえば、access_ok()はユーザー提供のポインターがユーザー空間を指していることを確認し、array_index_nospecマクロはユーザー提供のインデックスでの投機的範囲外アクセスを防ぐ。したがって、guess_ptrは既存のカーネルポインター、具体的にはメモリ破損を引き起こす脆弱なポインターである必要がある。たとえば、use-after-free(UAF)のダングリングポインターまたはバッファオーバーフローの範囲外ポインターを使用できる。最後に、TESTでは、test_ptrを逆参照する必要があり、test_ptrはユーザー空間からアクセス可能である必要がある。キャッシュ状態測定を容易にするために、test_ptrはシステムコール引数を通じて提供されるユーザー空間ポインターである必要がある。
\ ==発見されたガジェット== 前述の要件を満たすTIKTAGガジェットを見つけるために、Linuxカーネルのソースコードを手動で分析した。その結果、snd_timer_user_read()(図10)で悪用可能な可能性のあるTIKTAG-v1ガジェットを1つ発見した。このガジェットはTIKTAG-v1の要件を満たしている(§5.1)。10行目(すなわち、BR)で、switch文はユーザー制御可能な値tu->tread(すなわち、cond_ptr)で分岐予測ミスをトリガーする。14〜17行目(すなわち、CHECK)で、tread(すなわち、guess_ptr)は4つのロード命令によって逆参照される。treadは、攻撃者が任意に割り当ておよび解放できるstruct snd_timer_tread64オブジェクトを指す。
\ 時間的脆弱性がtreadをダングリングポインターに変換すると、guess_ptrとして使用できる。20行目(すなわち、TEST)で、ユーザー空間ポインターバッファー(すなわち、test_ptr)はcopy_to_userで逆参照される。このガジェットはユーザー空間から直接到達できないため、カーネルコードにわずかな変更を加えた。6行目のデフォルトケースの早期returnを削除した。これにより、投機的実行によるキャッシュ状態の違いを観察するために、投機的パスでのみバッファーにアクセスされることが保証される。
\ この変更は実世界のシナリオでは現実的ではないが、同様のコード変更が行われた場合のガジェットの悪用可能性を示している。さらにいくつかの悪用可能な可能性のあるガジェットを発見したが、タグの一致と不一致の間のキャッシュ状態の違いを観察することはできなかった。それでも、これらのガジェットを悪用する強い可能性があると考えている。TIKTAGベースの攻撃の実行には複雑で繊細なエンジニアリングが含まれるため、すべての可能なケースを実験することはできなかった。
\ 特に、TIKTAG-v1は誤ったパスイベントでの投機的縮小に依存しており、これには分岐予測ミスパスでのアドレス変換エラーやその他の例外も含まれる可能性がある。システムコールには複雑な制御フローが含まれるため、投機的縮小は予想どおりにトリガーされない可能性がある。さらに、カーネルコードが変更されると、いくつかのガジェットが悪用可能になる可能性がある。たとえば、ip6mr_ioctl()のTIKTAG-v1ガジェットは、システムコールパス(すなわち、ioctl)から呼び出されたときにMTEタグ漏洩動作を示さなかった。ただし、このガジェットは、単純な制御フローを持つ他のsyscalls(例:write)に移植されたときにタグ漏洩を示した。
\ ==6.2.3. カーネルMTEバイパス攻撃== 図9bは、LinuxカーネルへのMTEバイパス攻撃を示している。use-after-free脆弱性を例として、攻撃者が脆弱性によって作成されたダングリングポインターのタグチェック結果を漏洩できる対応するTIKTAGガジェット、SysTikTagUAF()を特定していると仮定する。たとえば、snd_timer_user_read()(図10)のTIKTAG-v1ガジェットは、use-after-freeまたはdouble-free脆弱性によってダングリングポインターになる可能性のあるtreadのタグチェック結果を漏洩させることができる。
\ 攻撃は次のように進行する:まず、攻撃者はカーネルオブジェクト(すなわち、objvuln)を解放し、そのポインター(すなわち、vuln_ptr)をダングリングポインターとして残す(1)。次に、攻撃者はSysAllocTarget()でobjvulnのアドレスに別のカーネルオブジェクト(すなわち、objtarget)を割り当てる(2)。次に、攻撃者はユーザー空間バッファー(すなわち、ubuf)でSysTikTag()を呼び出し(3)、ubufのアクセス遅延を測定してタグチェック結果(すなわち、Tm == Tg)を漏洩させる(4)。タグが一致する場合、攻撃者はuse-after-free脆弱性を悪用するシステムコールであるSysExploitUAF()をトリガーする(5)。そうでない場合、攻撃者はタグが一致するまでobjtargetを再割り当てする。
\ ==キャッシュサイドチャネルのトリガー== §6.1.3と同様に、TIKTAGガジェットの悪用を成功させるには、i) 分岐トレーニング、ii) キャッシュ制御、iii) キャッシュ測定が必要である。分岐トレーニングについては、攻撃者はユーザー空間からユーザー制御の分岐条件で分岐予測器をトレーニングし、投機を開始できる。キャッシュ制御については、攻撃者はユーザー空間バッファー(すなわち、ubuf)をフラッシュでき、カーネルメモリアドレスはキャッシュラインバウンシング[25]によって削除できる。キャッシュ測定については、ubufのアクセス遅延は仮想カウンター(すなわち、CNTVCT_EL0)またはメモリカウンターベースのタイマー(すなわち、CPUサイクル解像度に近い)で測定できる。
\ ==メモリ破損脆弱性の悪用== TIKTAGガジェットにより、MTEをバイパスし、カーネルメモリ破損脆弱性を悪用できる。攻撃者は、カーネル内のTIKTAGガジェットを呼び出して投機的にメモリ破損をトリガーし、タグチェック結果を取得できる。次に、攻撃者はタグチェック結果を取得し、タグが一致する場合にのみメモリ破損をトリガーできる。Linuxカーネル MTEバイパス攻撃プロセスの詳細は§Dで説明する。
\ ==6.2.4. 緩和策== Linuxカーネルで TIKTAGガジェットを緩和するために、カーネル開発者は次の緩和策を検討する必要がある:
i) 投機バリア: 投機バリアは、LinuxカーネルでTIKTAG-v1ガジェットを効果的に緩和できる。攻撃者がユーザー空間バッファーを通じてタグチェック結果を漏洩させるのを防ぐために、copy_to_userやcopy_from_userなどのユーザー空間アドレスにアクセスするカーネル関数を投機バリアで強化できる。§5.1で説明されているように、ストアアクセスによるタグチェック結果の漏洩は、ストアアクセス(すなわち、TEST)の前に投機バリアを配置することで緩和できる。
\ たとえば、copy_to_userを利用するガジェットを緩和するために、copy_to_user呼び出しの前に投機バリアを挿入できる。ユーザー空間バッファーへのロードアクセスを利用するガジェットの場合、分岐とカーネルメモリアクセス(すなわち、CHECK)の間に挿入すると、バリアはガジェットを緩和する。たとえば、copy_from_userを利用するガジェットを緩和するために、カーネル開発者はカーネルコードベースを慎重に分析して、条件分岐、カーネルメモリアクセス、およびcopy_from_user()のパターンを見つけ、分岐とカーネルメモリアクセスの間に投機バリアを挿入する必要がある。
\ ii) ガジェット構築の防止: Linuxカーネルで潜在的なTIKTAGガジェットを排除するために、カーネルソースコードを分析してパッチを適用できる。TIKTAGガジェットはコンパイラ最適化によっても構築される可能性があるため、バイナリ分析を実施できる。発見された各ガジェットについて、§5.1および§5.2の緩和戦略に従って、命令を並べ替えるか、追加の命令を挿入してガジェットの構築を防ぐことができる。
:::info 著者:
:::
:::info 本論文は、CC 4.0ライセンスの下でarxivで入手可能です。
:::
\


