Rowhammer とハードウェアフォルト注入攻撃
メモリへの読み出しだけで隣の行のビットが勝手に反転する。Rowhammer がページテーブルを書き換えて権限昇格する原理、TRR や ECC が守りきれない理由、電圧グリッチによるフォルト注入までを把握できる。
- 1.Rowhammer は DRAM の行を高速反復アクセスすると、隣接行のセルが電荷漏れを起こし、書き込まずにビットが反転する物理現象。攻撃者はこれをページテーブルや権限ビットの改ざんに利用して権限昇格やサンドボックス脱出を狙う。
- 2.ECC は単一ビット誤りを訂正するが、複数ビット反転や ECC 自体の漏洩で迂回され得る。TRR(Target Row Refresh)も多数の攻撃行を同時に叩く TRRespass や Half-Double で破られ、緩和は完全ではない。
- 3.電圧・クロックグリッチやレーザによるフォルト注入は、CPU に瞬間的な異常を与えて分岐や境界チェックをスキップさせる。秘密鍵の差分故障解析(DFA)や Secure Boot バイパスに使われ、対策は冗長化・センサ・チェックの二重化。
ソフトを一切壊さずにメモリが書き換わる
Rowhammer(2014年に Kim らの論文で報告され、2015年に Google Project Zero が実用攻撃を示した)は、読み出しアクセスだけで、自分が触れていない別のメモリ領域を物理的に書き換えられるという直感に反する脆弱性です。バグのあるコードを踏むのではなく、DRAM という記憶素子そのものの電気的な性質を突きます。攻撃者は権限のないメモリだけを正規に読み書きしながら、その副作用として隣接する特権データのビットを反転させ、最終的に制御を奪います。
原因は DRAM の高密度化です。DRAM の 1 ビットは「コンデンサに電荷があるか否か」で表され、セルは行(ロウ)と列の格子に並びます。プロセス微細化でセル間隔が縮むと、ある行を活性化(アクティベート)するたびに、隣接行のセルからわずかに電荷が漏れる。通常はリフレッシュ(既定で 64ms ごとに全行を読み直して書き戻す)が漏れを補いますが、1 回のリフレッシュ周期の間に同じ行を数万回叩くと、漏れがリフレッシュの補充を上回り、隣接行のビットが 1 から 0(あるいは逆)へ反転します。
反復アクセスする行を aggressor、ビットが反転する隣接行を victim と呼びます。代表手法が二つあります。**ダブルサイド(double-sided)**は victim 行をその上下の 2 つの aggressor で挟み撃ちし、両側からの電荷漏れで反転確率を大きく高めます。**多数行(many-sided / TRRespass)**は多数の aggressor を同時に叩き、後述の TRR の追跡能力を飽和させます。いずれも「victim の中身は読まず、周囲を叩くだけ」で内容が変わる点が核心です。
ビット反転を狙撃するには:行を確実に叩く工夫
DRAM コントローラとキャッシュは攻撃の邪魔をします。第一に、同じアドレスを連続で読むと CPU キャッシュがヒットして DRAM まで到達しません。そこで clflush でキャッシュラインを明示的に追い出すか、キャッシュを溢れさせるキャッシュエビクションで、毎回 DRAM 本体へアクセスを飛ばします。第二に、行を「叩く」には行バッファを毎回入れ替える必要があるため、同一バンク内の異なる行を交互にアクセスして毎回 row activate を強制します。
ダブルサイド Rowhammer の中核ループ(擬似コード):
loop:
read(aggressor_up) // victim の 1 つ上の行
read(aggressor_down) // victim の 1 つ下の行
clflush(aggressor_up) // キャッシュから追い出し、次回も DRAM を叩く
clflush(aggressor_down)
// これを 1 リフレッシュ周期内に数万回反復し、
// 間の victim 行のビット反転を誘発する
難所は、論理アドレスと物理的な「バンク・行」の対応が公開されていない点です。攻撃者は DRAM アドレッシング関数をリバースエンジニアリングするか、アクセス時間の差(同バンク別行はバンク競合で遅い)を観測して、物理的に隣接する行のペアを特定します。Linux の透過的ヒュージページや /proc/self/pagemap は連続物理メモリの確保と物理アドレス推定を助けたため、攻撃を実用化させた重要な足がかりでした。
権限昇格へ:反転したビットで何を壊すか
単にどこかのビットが反転しても害は限定的です。攻撃の真価は、反転を狙った場所で起こさせるメモリ整形(memory massaging)にあります。古典的な手口がページテーブルエントリ(PTE)攻撃です。
攻撃者はまず大量のメモリを確保してプロセスのページテーブルを敵の制御下のメモリ領域に大量配置させ、自分のページが指す物理フレーム番号を含む PTE が victim 行に載るよう仕向けます。そこで Rowhammer を打ち、PTE の物理フレーム番号や権限ビットのビットを反転させる。すると、自分のあるページの仮想アドレスが別の物理フレーム――しばしば自分自身のページテーブルそのもの――を指すようになります。ページテーブルへの書き込み権を得た攻撃者は、以後あらゆる物理ページを任意にマップでき、カーネルメモリの読み書きと完全な権限昇格に至ります。
ECC と TRR はなぜ守りきれないのか
DRAM 防御の二本柱が ECC と TRR ですが、いずれも限界があります。
ECC(誤り訂正符号)。 サーバ向け DRAM は通常 SECDED(単一ビット訂正・二重ビット検出)を備え、64 ビットに 8 ビットの冗長を付けます。単一ビット反転なら透過的に訂正し、二重ビットなら検出してマシンを停止できます。しかし三つ以上のビットが同じ語内で反転すると、訂正も検出も外れ、誤訂正で別の正常ビットを壊すことすらあります。ECCploit は、ECC の訂正・検出挙動をタイミングから観測して内部符号を推定し、訂正されない多ビット反転パターンを探索できることを示しました。ECC は反転確率を大きく下げますが、根絶はしません。
TRR(Target Row Refresh)。 メモリ側が、頻繁にアクセスされる aggressor 行を検知し、その隣接行を周期外に追加リフレッシュして電荷を補う緩和です。ベンダ独自・非公開で、追跡できる aggressor 数に上限があります。TRRespass は、TRR が追える数を超える多数の aggressor を同時に叩いて追跡テーブルを飽和させ、保護の隙間で victim を反転させました。さらに Half-Double は、aggressor の「隣の隣」にあたる遠い行まで影響が及ぶ現象を使い、TRR の追加リフレッシュ自体を新たな aggressor として悪用します。
| 緩和策 | 守る仕組み | 残る穴 |
|---|---|---|
| リフレッシュ間隔短縮 | 漏れの蓄積前に書き戻す | 消費電力と帯域が増え、極端な攻撃には不十分 |
| ECC(SECDED) | 1 ビット訂正・2 ビット検出 | 3 ビット以上で迂回。ECCploit で訂正挙動が漏れる |
| TRR | aggressor 隣接行を追加リフレッシュ | TRRespass で飽和、Half-Double で遠隔行が反転 |
| DDR5 on-die ECC | チップ内で訂正 | 外部から見えず誤りを隠すだけで反転自体は残る |
| PARA(確率的追加リフレッシュ) | 活性化のたび確率的に隣接をリフレッシュ | 確率設計次第で取りこぼし。標準採用は限定的 |
電圧・クロックグリッチによるフォルト注入
Rowhammer がメモリの記憶を狂わせるのに対し、**フォルト注入(fault injection)**は CPU や制御フローそのものに瞬間的な異常を与えて誤動作させる、より広いハードウェア攻撃の系です。物理アクセスできる組み込み機器やスマートカード、TPM などが主な標的になります。
代表がグリッチ攻撃です。電圧グリッチは、CPU の電源電圧を狙ったタイミングで一瞬だけ規定外に落とす(または上げる)。これでフリップフロップのセットアップ時間が間に合わず、ある命令のフェッチやレジスタ書き込みがスキップ・破損します。クロックグリッチは、クロックに極端に短いパルスを注入し、命令が完了する前に次へ進ませて同様の効果を出します。より精密なレーザフォルト注入は、チップを開封して特定のトランジスタに光を当て、狙った 1 ビットだけを反転させます。
これらの典型的な悪用が二つあります。第一にチェックのスキップです。if (pin_ok) や Secure Boot の署名検証直後の分岐をグリッチで飛ばし、認証やセキュアブートを素通りさせます。第二が**差分故障解析(DFA)**です。RSA や AES の演算の途中に故障を 1 つ注入し、正しい暗号文と故障した暗号文の差分を解析すると、わずかな試行で秘密鍵を復元できます。例えば CRT を用いた RSA 署名で片方のモジュラ計算だけを故障させると、正しい署名との差から gcd 計算一発で素因数 p が漏れます。
サイドチャネル攻撃が「秘密が外へ漏れる情報を受動的に観測する」のに対し、フォルト注入は「内部状態を能動的に狂わせて漏れを誘発する」攻撃です。両者は組み合わさると強力で、グリッチで防御コードを無効化してからタイミングで鍵を抜く、といった連鎖が可能です。物理アクセスを許す脅威モデルでは、セキュアエンクレーブや TPM も電圧・温度・グリッチセンサと冗長検証で武装してはじめて耐性を持ちます。
防御の現実:確率を下げ、多重化する
Rowhammer もフォルト注入も物理現象を根絶できない点が共通の難しさです。防御は単一の銀の弾丸ではなく、攻撃成立の確率と費用を実用上耐えられない水準まで押し上げる多層化になります。
Rowhammer 側は、リフレッシュ間隔の短縮(tREFI を半減する BIOS 設定)、ECC、TRR、PARA、DDR5 のオンダイ ECC とリフレッシュ管理(RFM)を重ねます。OS 側では物理的に連続したメモリの確保を攻撃者に渡さない(pagemap の権限制限、ヒュージページの制御)、機微なデータ(ページテーブル等)を物理的に隔離する、clflush や高分解能タイマーへのアクセスを制限する、といった緩和が併用されます。それでも完全ではなく、新変種(Blacksmith、ZenHammer など)が緩和を順次破ってきた歴史があるため、脆弱性は残存リスクとして管理するのが現実的な姿勢です。
フォルト注入側は、署名検証や PIN 照合のような重要分岐を二重に評価して結果を突き合わせる冗長化、演算結果を別経路で再計算して照合する(DFA 耐性のための署名後検証)、電圧・クロック・温度・光の異常を検知して即座にリセット・鍵消去するセンサ、配線のシールドや配置難読化が定石です。要は、1 回の物理的故障では破れないようチェックを冗長化し、異常を検知する設計に尽きます。
(1) Rowhammer は DRAM 隣接行への高速反復アクセスが電荷漏れを起こし、書き込まずにビット反転を誘発する物理現象。aggressor を叩いて victim を反転させる。(2) 悪用の鍵はメモリ整形で、PTE のビットを反転させ自分のページテーブルを指させて権限昇格する。(3) ECC は多ビット反転で迂回され、TRR は TRRespass/Half-Double で飽和・遠隔反転され、完全には守れない。(4) フォルト注入(電圧・クロックグリッチ、レーザ)はチェックのスキップや差分故障解析(DFA)による鍵復元に使う。(5) 防御は根絶不能を前提に、リフレッシュ・ECC・TRR の多層化、チェックの冗長化、異常センサで確率と費用を押し上げる。
セキュリティ Article
Rowhammer とハードウェアフォルト注入攻撃を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
Rowhammer
比較で見る軸
難易度: advanced / カテゴリ: セキュリティ / タグ数: 6
導入後に効く点
ECC は単一ビット誤りを訂正するが、複数ビット反転や ECC 自体の漏洩で迂回され得る。TRR(Target Row Refresh)も多数の攻撃行を同時に叩く TRRespass や Half-Double で破られ、緩和は完全ではない。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- セキュリティ
- タグ数
- 6
判断チェックリスト
- 自社の用途が「Rowhammer / DRAM」に近いか確認する。
- 強みである「Rowhammer は DRAM の行を高速反復アクセスすると、隣接行のセルが電荷漏れを起こし、書き込まずにビットが反転する物理現象。攻撃者はこれをページテーブルや権限ビットの改ざんに利用して権限昇格やサンドボックス脱出を狙う。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。