セキュリティの重要課題: 「Row Hammer」を利用した GLitch 攻撃

「Row Hammer」の問題をご存知でしょうか。

これは、昔からよく知られたコンピュータメモリ (DRAM と呼ばれる種類のメモリ) の問題です。

DRAM は、電気的に接続され縦横に配置された極小の蓄積キャパシタのグリッドから成るシリコンチップです。

簡単に言うと、Row Hammer とは、同じ DRAM メモリアドレスを繰り返し読み取ることで、チップの小さな部分に長い時間電子的活動が集中し、隣接するメモリセルで干渉が発生する問題です。

隣接するセルの一部で電荷が変化し、0 が 1 に、あるいは 1 が 0 になることがあります。

Row Hammer に対する懸念が高まったことで、最新のオペレーティングシステムや一般的に使用されているアプリケーション (特にブラウザ) には次々に変更が加えられたり、修正プログラムが公開されたりしています。

こうした変更のおかげで、ビットの反転を意図的に引き起こして悪用することはもちろん、ビットの反転自体が発生し難くなっています。

しかし、完全にではありません。

アムステルダム自由大学 (Vrije Universiteit Amsterdam) の研究チームは、Row Hammer 問題の対策の大半がデバイスの CPU と RAM の間の相互作用に焦点を当てたものだったと指摘しています。

しかし、最近のデバイスには CPU だけでなく、1 つ以上の GPU (Graphics Processing Unit) など、さまざまな補助プロセッサも搭載されているのが一般的です。

GPU は、グラフィックを大量に使用するアプリケーションに必要な高速の数学的演算とビット操作に適しています。

攻撃のステップ

研究チームは、Android デバイスの GPU で実行されるコードを使用して、従来のプログラミング技術では不可能な Row Hammer を実行できるかどうかを調査しました。

また、問題をより具体的かつ興味深いものにするため、root 化された Android デバイスを使用せずに、また、インストール済みのマルウェアアプリに頼らずに、目的を達成できるかどうかを試すことにしました。

研究チームの目的は、Web ページで提供される JavaScript だけを使用して、ブラウザで Row Hammer 攻撃を成功させることでした。

この調査は GLitch と名付けられました。GL の由来は、WebGL (Web Graphics Library) です。

WebGL は、最近のブラウザに組み込まれているプログラミングライブラリです。WebGL を使用することで、JavaScript コードと GPU の連携が緊密になるため、グラフィックス集約型のオンラインアプリのパフォーマンスが向上します。

研究チームは、WebGL の機能が追加されればリスクも増加すると予想し、検証しました。

予想が正しかったことは証明できましたが、数多くのステップを踏まなければなりませんでした。

ステップ 1: キャッシュをバイパスする

JavaScript でメモリを読み取るのは簡単です。実際、JavaScript 変数にアクセスするたびに自動的に行われています。

しかし、Row Hammer の場合には、高い精度での制御が必要です。つまり、「読み取りは本当の意味での読み取り」であるため、プログラムコードが DRAM チップ自体の実際のシリコンにアクセスするよう強制的に仕向けます。

これは、実際には容易なことではありません。なぜなら、最近のコンピュータは、キャッシュメモリと呼ばれる特別な高速ストレージによく使用される値を格納することによって、実際の DRAM の読み取りをできるだけ回避し、スピードアップを図っているからです。

これとは対照的に、Row Hammer 攻撃を成功させるには、多くの電子負荷を DRAM 回路にかける必要があります。つまり、キャッシュがパフォーマンスの「向上」を試みることなく、できるだけ高速で同じ物理メモリ領域を何度も繰り返し読み取ります。

モバイルデバイスで一般的に使用されている ARM チップセットでは、キャッシュを空にすることでキャッシュは動作しなくなります。しかし、通常のアプリではこれは不可能で、Android のカーネル権限を持っているか、root 化された Android デバイスを使用する必要があります。

しかし、アムステルダム自由大学のチームは、調査で使用したチップセットの GPU メモリキャッシュアルゴリズムは予測が容易だったという結論に達しました。

明確なパターンに基づいてメモリにアクセスすることによって、キャッシュの動きを妨げられるので、それ以降はキャッシュに邪魔されなくなりました。

ステップ 2: 時間の経過を追う

Row Hammer 攻撃を実行するには、シリコンのどこにメモリアドレスがあるのかを特定する必要があります。これは、隣接するキャパシタ回路に干渉するには、チップ内の小さな部分にメモリ読み取りを集中させなければならないためです。

DRAM の読み取りは、一度に 1 ビットずつではなく、隣接するビットへのバーストアクセスで実行されます。したがって、2 つの読み取りを 1 回のバーストで完了できるため、物理的に近接した 2 つのアドレスからの読み取りがいつ実行されたのかを把握できます。

これにより、チップ上で離れている 2 つのアドレスにアクセスする場合よりも、読み取り速度が若干速くなります。

しかし、この方法でメモリを詳細に把握するには、マイクロ秒単位ではなくナノ秒単位の驚異的な精度で時間の経過を追跡しなければなりません。

1GHz とは「毎秒何かが 10 億回起きること」を示すもので、つまり 1 回が 10 億分の 1 秒であり、その 10 億分の 1 秒がナノ秒 (10-9 秒) になります。マイクロ秒は 100 万分の 1 秒 (10-6 seconds) ですが、その間に数千個のマシンコード命令の実行が可能です。

JavaScript の公式のタイマー関数の多くは、Row Hammer の防止を目的としてメーカー側が意図的に性能を低下させているため、ブラウザでメモリアクセス速度を正確に測定することは困難です。

意図的に精度が低くなっているこうしたタイマーが実装されているのは、一般的な使用には十分な精度でありながら、Row Hammer 攻撃には利用ではないようにするためです。

しかし、まだセキュリティ上の理由で精度が下げられていなかった WebGL 固有のタイミング機能を発見したのが、アムステルダム自由大学の研究チームでした。

GLitch の調査報告が発表されたことを受け、ブラウザメーカーは現在該当するタイマー (TIME_ELAPSED_EXTTIMESTAMP_EXT) の精度を意図的に下げています。しかし、研究チームは、特別なタイマー機能を使用しなくても、精度を高めることができる WebGL コードを記述する別の方法も発見したと主張しています。

ステップ 3: DRAM チップのレイアウトを把握する

キャッシュによる「実際の」メモリアクセスの実行をバイパスでき、これらのアクセスの時間を十分な精度で測定できれば、DRAM チップを正確に把握することができます。

メモリ空間全体の詳細なレイアウトを作成する必要はありません。物理的に隣接している DRAM キャパシタが 3 列あることが分かれば十分です。

チップ内の連続する 3 列のキャパシタにアクセスできれば、外側の 2 列から繰り返し素早くデータを読み取ることで、中央のキャパシタのビットを反転させられるだけの十分な電気的活動が発生します。

この攻撃方法は、「Double-sided row hammer (両側からの Row Hammer)」と呼ばれるものです。

ステップ 4: メモリアロケータを特定する

隣接する 3 列の DRAM に対応するメモリをオペレーティングシステムが分配することは、同じ大きさの 3 つのメモリブロックを順番に要求することほど簡単ではありません。

実際、研究チームがターゲットとした GPU をサポートするために使用した Android メモリアロケータでは、連続して 3 つのメモリを割り当てても、隣接するメモリブロックは全く生成されませんでした。

しかし、アロケータを調査した結果、DRAM 内部の隣接するキャパシタ列からメモリが確実に分配されるように、割り当てと割り当て解除をミックスする方法を編み出しました。

DRAM の 3 つの隣接する列が割り当てられ、その物理メモリへの高速直接読み取りアクセスが行われると、「Row Hammer 攻撃が可能な列」が出現するので、電子的打撃を与えて意図的に破壊することが可能になります。

さらなる攻撃

準ランダムな場所にある 1 ビットであったとしても、任意にメモリを破壊できるということは、エクスプロイトであると見なすことができます。少なくとも、アプリケーションやデバイスそのものを強制的にクラッシュさせて、DoS 攻撃を引き起こすことが可能です。

しかし、研究チームの挑戦はブラウザによる DoS 攻撃にとどまりませんでした。

ほんの少し運が良ければ、JavaScript 配列でランダムにビットが反転した場合に (本来 JavaScript によって阻止されるはずの) メモリへの読み取り/書き込みアクセスが可能になるように、「Row Hammer 攻撃が可能な列」と JavaScipt 配列を調整する方法を考え出しました。

これは、非公開であるはずのメモリが読み取られてデータが漏洩するだけでなく、保護されているメモリにマシンコードが埋め込まれて実行されることによって RCE (リモートからのコード実行) も可能であることを意味します。

対策

これまで、多くの人がモバイルデバイスは Row Hammer 攻撃とは無関係だと考えていました。

モバイルデバイスを標的にするには、Row Hammer 攻撃と同様の影響をもたらす別の攻撃が可能なアプリをインストールする必要がありました。あるいは、攻撃が成功するのを長い間祈りながら待っていても、デバイスで起きた別のアクティビティによって攻撃が妨害され、また最初からやり直すはめになっていました。

しかし、研究チームによれば、この「GLitch」攻撃はブラウザで実行されている JavaScript コードのみを使用して、比較的短時間に実行が可能です。root 化されたデバイスも、悪意のあるアプリをインストールする必要もありません。

では、Android は危険なので使用を中止したほうがよいのでしょうか?

いいえ、そうではありません。

これまでのところ、研究チームが成功させた攻撃は限定的であり、制御された環境下で古いバージョンの Android を実行する特定の古いデバイスが使用されていました。

ただし、今回の GLitch 攻撃を踏まえて、機能を追加したりパフォーマンスを向上させたりすると (スマートフォンのチップに GPU を組み込んだり、高機能のグラフィックスプログラミングライブラリをブラウザに追加したりするなど)、同時にセキュリティが低下するリスクがあることを覚えておく必要があります。

そのような場合には、あえてパフォーマンスを下げて、セキュリティを許容できるレベルまで引き上げる方法も検討してください。