TLBleedの論文がやっと発表された。The Registerで記事が出てから論文が出てくるまでずっと監視していたのだが、随分と時間がかかったね。
このTLBleedの論文非常に長いので読むのがつかれるし、あまりセキュリティの知識とか無いので大変なのだが、要点だけつかもうと時間を作ってざっくりと読み進んでいった。
まだまだ分からないところが多いが、まとめていこう。 なんか難しげなアルゴリズムとかサクッと英語で説明してあるのでその辺りはまだよく理解できていないが、一通り読んで概要は何となくわかった。
この手法、スレッドが特権を持っていなくても同時に実行されているスレッド内の命令を読み取ることができるというものなのだが、当然ターゲットとなるサーバ内で攻撃スレッドが実行できている必要がある。
これはAWSなどのクラウド上で、意図していなくても何らなの別スレッドとリソースを共有しているような状態で脅威になる可能性はある。
要点
TLBleedは、攻撃対象のスレッドと攻撃スレッドがハイパースレッディングの環境下でTLBを共有することにより発生するミス攻撃手法。 TLBは仮想アドレスから物理アドレスへの変換を行うMMUの機能を補填するための機能であり、キャッシュと同様にバッファとしての機能を持っている。 従ってSpectre / Meltdownのようにスレッド毎の共有資源であり、攻撃対象となる。
しかし、TLBを使って攻撃するためにはいくつか問題がある。
- 仮想アドレスから物理アドレスへの変換は一定ではない。TLBのバッファへのマッピングはマイクロアーキテクチャとして明確に明言されていない手法でハッシュ化されており、狙ってアドレスを作り出すことが難しい。
- TLBは1ページ(4kB)での管理が行われる。従ってTLBの内容を盗んだところで、どのようにして情報を搾取するのか?
- アドレス変換の部分には様々なランダム化手法 ASLR / CAT / TSX などの情報漏洩防御手段が存在しており、どのようにかいくぐるか?
これらに対して、
- TLBの綿密な解析によるTLBのレイテンシ解析
- 機械学習(サポートベクタマシン)によりTLBのレイテンシ情報から実行されている関数の識別
により、暗号化ライブラリ(libgcrpyt)の秘匿情報の取得に成功している。
手法
まず、TLBから情報を盗み出すためには、いくつかの困難を乗り越えなければならない。 これらについて、本論文では4つに分けて説明している。
- Q1. TLBの動作をどのようにしてモニタリングするか?仮想アドレスから物理アドレスの変換をどのようにして計算し、モデルを作成するかが重要になる。
- Q2, TLBの同一セット内に、どのようにして攻撃対象と攻撃スレッドを同居させるか?
- Q3. TLBの動作をどのように監視するか?つまり、特権実行が不可能な状態でどのようにしてTLBのレイテンシを測定して、動作を監視するか?
- Q4. TLBはページ(4kB)単位でのデータやりとりとなる。この、粗粒度な状態で、どのようにして秘匿データを盗み見るか?
これらの問題を1つずつ解決していき、TLBleedを構成していく。 (余談だが上記のように1つ1つ問題を設定して解決先を導いていくあたり、論文内にストーリーが作られていて面白い。)
TLBのモニタリング
TLBは、仮想アドレスから物理アドレスへの変換情報を記憶しておくバッファだが、どのアドレスがTLBのどのセットに入るかは明言されていない。 これを解析するために、ハッシュ関数を仮定しプログラムを作成し、リバースエンジニアリングを行っている。 例えば、Skylake L2 TLBは、仮想アドレスに対して使用するTLBのセットは以下のハッシュ関数により推定できることが分かったとしている。
対象となっているIntelのCPUはTLBは2段階構成となっており、L1 iTLB / L1 dTLB / L2 sTLBの動作を解析してパラメータを抽出した。
その結果、以下の表に示すようなパラメータを取得することができた。 L1 dTLB と L2 STLBはスレッド毎にセットが共有されているため、攻撃対象に用いることができると考え、この2つのTLBを攻撃手法に使うことにした。
TLBのレイテンシを読む
ハイパースレッディングにより攻撃スレッドと攻撃対象スレッディングが同居している中で、攻撃スレッドは特権、つまりTLBのイベント情報などを取得する方法がない。
これを解決するために、TLB動作時のレイテンシを監視することで、TLB内に格納されている特定スレッドのヒット・ミスを測定する手法を作成した。これには、rdtsc
命令, rdtscp
命令(タイムスタンプ命令)を用いている。
実験では、彼らの開発したプログラムにより、TLBのレイテンシを測定することでTLBのヒット・ミスを測定できるようになったとしている。
TLBのレイテンシから動作している関数を同定する
TLBのレイテンシが計測できるようになったので、このレイテンシ情報から、どの関数が実行されているのかが特定できるようになる。
これには、機械学習(具体的には、サポートベクタマシン)を用いている。これにより、下記の図のように動作している関数を特定できるようになった。 実験では、EdDSAで用いられている2つの関数のどちらが実行されているかが分かるようになった。
- duplication
_gcry_mpi_ec_dup_point
- addition
_gcry_mpi_ec_add_points
どの程度効果があるのか?
彼らの実験では、
- EdDSAの鍵生成については、99%に近い確率で読み取り可能
- ソフトウェアによる防御手法 (わざと意味のないメモリアクセスを発生させる、など)は効果がない。
- RSA鍵生成について90%に近い確率で読み取り可能
- Intel CAT (プロセス毎にキャッシュを分離する手法)は効果がない
- Intel TSX (Hardware Transactional Memory)も効果がない。
- ALSR (アドレスのランダム化)も効果がない。
としている。
(ブログ筆者の)感想
もう、スレッド毎で共有されているすべての資源は見直す必要があるのではなかろうかという気分になってくる。
また、暗号系の鍵を扱う処理は、プロセッサのようにレイテンシやキャッシュの存在するような状況かで扱うのではなく、例えば専用ハードウェアでどのような演算でも同一レイテンシになるようにしないと、これ以上の防御は難しいのではないだろうか、という気分になる。