はじめに
低レイヤやセキュリティの勉強をしていると必ず耳にするASLR(Address Space Layout Randomization:アドレス空間配置のランダム化)。 「メモリのアドレスをランダムにするやつでしょ?」という共通認識はあっても、具体的に「どこが」「どう」ランダムになり、なぜそれが攻撃の防御に繋がるのか、パッと説明できますか?
本記事では、セキュリティ初学者に向けて、ASLRの仕組みからその限界(どうやってバイパスされるか)までを分かりやすく解説します!
1. ASLRとは?
ASLR(Address Space Layout Randomization)は、プログラムが実行される際に、メモリ上のデータ配置(スタック、ヒープ、ライブラリなど)のアドレスをランダムに割り当てるOSのセキュリティ機能です。
主にバッファオーバーフロー(BOF)などの脆弱性を悪用した悪意あるコードの実行(シェルコードの実行やROP攻撃)を防ぐために導入されています。
現在では、Linux、Windows、macOS、iOS、Androidなど、ほぼすべての主要なOSに標準で搭載されています。
2. なぜASLRが必要なのか?(導入前の世界)
ASLRがない世界を想像してみましょう。
ASLRがない場合、プログラムが起動するたびに、関数やライブラリ(libcなど)は常にまったく同じメモリのアドレスに配置されます。
攻撃者の視点
- 手元の環境でプログラムを動かし、実行したい関数(例:
system関数)のアドレスが0x7fffffffe000であることを突き止める。 - 本番環境のサーバーにバッファオーバーフローの脆弱性を見つける。
- メモリを溢れさせて、戻りアドレス(リターンアドレス)を
0x7fffffffe000に書き換える。 - 常に同じアドレスに標的の関数があるため、攻撃が100%成功する。
このように、アドレスが固定だと、攻撃者は「標的のピンポイントな住所」を知るだけで簡単にシステムを乗っ取ることができてしまいます。
3. ASLRの仕組み(導入後の世界)
ASLRが有効な場合、プログラムを起動するたびに、OSはメモリマップをシャッフルします。
具体的には、以下の領域のアドレスが起動ごとにランダム化されます。
- スタック領域(ローカル変数や関数のリターンアドレスが置かれる場所)
- ヒープ領域(動的に確保されるメモリ領域)
-
共有ライブラリ(
libc.soなどの共通パーツが置かれる場所)
これにより、攻撃者が手元の環境で「system関数のアドレスは 0x7fffffffe000 だ!」と特定しても、サーバー側でプログラムが再起動すると全く違うアドレス(例:0x7fff1234a000)に移動しているため、攻撃者が送り込んだ固定のアドレスへのジャンプは失敗し、プログラムはクラッシュ(Segmentation Fault)します。
💡 補足:PIE(Position Independent Executable)について ASLRだけでは、プログラム自身のコード領域(テキストセグメント)はランダム化されないことがあります。コンパイル時に PIE(位置独立実行形式) というオプション(gccの
-fPIE -pie)を有効にすることで、プログラム本体のアドレスもランダム化され、防御がより強固になります。
4. ASLRの限界とバイパス(回避)手法
「じゃあASLRを有効にしていれば100%安全なのか?」と言われると、残念ながらそうではありません。攻撃者もASLRを突破する手法(バイパス)を編み出しています。
① 情報漏洩(Information Leak)
これが最も一般的なバイパス手法です。 プログラムに別の脆弱性(Format String Bugや、メモリの境界チェックミスなど)があり、メモリの中身を攻撃者に読み取られてしまう(リークする)ケースです。
どこか1つでも有効な関数やライブラリのアドレスがリークすると、攻撃者はそこから「相対的なオフセット(距離)」を計算して、目的の関数のアドレスを割り出すことができてしまいます。
② ブルートフォース(当たりっパチ)
32bitシステムの場合、アドレス空間が狭いため、ランダム化のパターン数(エントロピー)が少なくなります。 プログラムがクラッシュしても自動で高速再起動するようなサービスの場合、攻撃者は何千回、何万回とアドレスを予測してリクエストを送り続けることで、偶然正解のアドレスに的中させることが可能です。 (※64bitシステムではアドレス空間が広大すぎるため、この手法は現実的ではありません)
5. 自分のLinux環境でASLRを確認・制御する
最後に、Linux環境でASLRの状態を確認・変更するコマンドを紹介します。実験する際に役立ててください。
ASLRの設定値を確認する
/proc/sys/kernel/randomize_va_space の値を確認します。
cat /proc/sys/kernel/randomize_va_space
-
0:ASLRが無効 -
1:スタック、データセグメント、VDSO、共有ライブラリをランダム化 -
2:1に加えてヒープもランダム化(通常はこれがデフォルト)
ASLRを一時的に無効化する(検証用)
root権限で値を 0 に書き換えることで無効化できます。
sudo sysctl -w kernel.randomize_va_space=0
(※セキュリティリスクになるため、実験が終わったら 2 に戻しましょう)
まとめ
- ASLRは、メモリ上の配置をランダムにして攻撃者の狙い撃ちを防ぐ技術。
- これがあるおかげで、バッファオーバーフロー攻撃の難易度が劇的に上がっている。
- ただし、「メモリリークの脆弱性」と組み合わされると突破される可能性がある。
セキュリティは「これ一つで万全」というものはなく、ASLRのようなOS側の防御壁と、脆弱性のないセキュアなコードを書くことの組み合わせが重要ですね!