ASLR(アドレス空間配置のランダム化)まとめ(Qiita向けメモ)
概要
ASLR(Address Space Layout Randomization)は、プロセスのメモリ領域(実行ファイルのベース、ライブラリ、ヒープ、スタックなど)の開始アドレスを実行ごとにランダム化することで、攻撃者が固定アドレスに依存したエクスプロイト(例:リターンアドレス上書きやROPチェーン構築)を行いにくくするセキュリティ技術です。
基本的な動作
- 実行時に OS が各領域のベースアドレスへランダムオフセットを付与する
- 同じバイナリでも毎回異なるアドレス空間配置になるため、アドレス予測が困難になる
- 単体では万能で はなく、他の保護(DEP/NX、Stack Canary、RELRO など)と組み合わせて効果を高める
Linux での確認・設定方法
ASLR の現在の設定を確認
# 0 = disabled, 1 = conservative, 2 = full
cat /proc/sys/kernel/randomize_va_space
一時的に有効/無効にする
# disable
sudo sysctl -w kernel.randomize_va_space=0
# enable (full)
sudo sysctl -w kernel.randomize_va_space=2
実験用の簡単な C サンプル(アドレスを観察する)
コード中のコメントは英語(Qiita の記事や共有用に読みやすく)。
// aslr_demo.c
#include <stdio.h>
#include <stdlib.h>
int global_var = 42;
int main(void) {
int stack_var = 99;
void *heap_ptr = malloc(16);
printf("Address of main: %p\n", (void*)main); // address in code segment
printf("Address of global: %p\n", (void*)&global_var); // data segment
printf("Address of stack: %p\n", (void*)&stack_var); // stack
printf("Address of heap: %p\n", heap_ptr); // heap
free(heap_ptr);
return 0;
}
コンパイル・実行例(PIE によるバイナリ再配置を確認)
# 1) normal compile (may produce non-PIE on some distros)
gcc -o aslr_demo aslr_demo.c
# 2) force PIE (recommended to observe full randomization)
gcc -fPIE -pie -o aslr_demo_pie aslr_demo.c
# run multiple times
./aslr_demo_pie
./aslr_demo_pie
./aslr_demo_pie
main / global / heap / stack のアドレスが実行ごとに変わるはず(ASLR が有効な場合)。
バイナリ/コンパイルのポイント
-
Position Independent Executable
実行可能ファイル自身が再配置可能であれば、コード領域(text)もベースアドレスをランダム化できる。-fPIE -pieを付けてビルドする - 共有ライブラリ (.so / DLL) は通常既に再配置可能(位置無関係)になっているためランダム化の恩恵を受ける
- 静的にアドレスを埋め込むようなコードや、明示的にASLRを無効にした環境では効果が減る
他の緩和策との組み合わせ
- DEP/NX (Data Execution Prevention / No-eXecute):データ領域で実行を禁止。コード注入攻撃を軽減
- Stack Canaries(スタックカナリア):バッファオーバーフロー時の改ざん検出
- RELRO(Read-Only Relocations):GOT などの書き換え防止(partial/full)
- Control-Flow Integrity (CFI):実行制御フローを制約する高度な保護
複数手段を重ねることで、攻撃難度が大幅に上昇する。
回避・バイパス手法(代表例)
ASLR は単体だと以下で弱体化する可能性があるため注意:
- 情報漏洩(info leak):アドレス情報を外部へ漏らす脆弱性があれば、攻撃者はランダム化を無効化できる
- 部分上書き(partial overwrite):低バイトのみ上書きしてアドレスを調整する手法
- JIT-Spraying / heap-spraying:ターゲット領域に予測可能なペイロードを大量に配置して当たりを引く試み(主にブラウザ攻撃)
- Brute-force:ASLR のエントロピーが小さい環境では試行回数で突破される場合がある(ただし検出・クラッシュログで遮断されることが多い)
OS 別の注意点
-
Linux:
randomize_va_spaceの値や PIE ビルドに依存。ディストリビューションやカーネル設定により挙動が少し異なる -
Windows:Vista 以降で
ASLRサポート。PE の/DYNAMICBASEフラグや ASLR の強さは OS バージョンやプロセス属性に依存。Visual Studio のリンカオプションで制御可能 - macOS:dyld によるランダム化が有効(基本的に有効)
実務でのチェックリスト
-
自分のビルドが PIE であるか確認する(
readelf -h <binary>でType: DYNなら PIE 可能性あり) -
重要なサーバ/バイナリで
kernel.randomize_va_spaceが有効になっているか確認 -
ビルド時に RELRO / Stack Canary / NX / PIE を有効にする
# example gcc flags -fstack-protector-strong -fPIE -pie -Wl,-z,relro,-z,now -O2 -
情報漏洩を防ぐ(フォーマット文字列、メモリダンプ、ログ出力の過剰な情報など)
-
エントロピーが十分か(古い組み込み機器などではASLRの効果が限定的な場合あり)
参考(短いまとめ)
- ASLR は「アドレスを毎回ランダムにすることで攻撃者の予測を困難にする」技術
- 単体では不十分 → DEP/NX・Canary・RELRO 等と併用することが重要
- 開発者は PIE でビルド し、OS の設定を確認、情報漏洩を防ぐ設計を心掛ける