1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

バッファオーバーフローを防ぐ「ASLR」の仕組みと限界

1
Posted at

はじめに

低レイヤやセキュリティの勉強をしていると必ず耳にする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など)は常にまったく同じメモリのアドレスに配置されます。

攻撃者の視点

  1. 手元の環境でプログラムを動かし、実行したい関数(例:system関数)のアドレスが 0x7fffffffe000 であることを突き止める。
  2. 本番環境のサーバーにバッファオーバーフローの脆弱性を見つける。
  3. メモリを溢れさせて、戻りアドレス(リターンアドレス)を 0x7fffffffe000 に書き換える。
  4. 常に同じアドレスに標的の関数があるため、攻撃が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、共有ライブラリをランダム化
  • 21に加えてヒープもランダム化(通常はこれがデフォルト

ASLRを一時的に無効化する(検証用)

root権限で値を 0 に書き換えることで無効化できます。

sudo sysctl -w kernel.randomize_va_space=0

(※セキュリティリスクになるため、実験が終わったら 2 に戻しましょう)

まとめ

  • ASLRは、メモリ上の配置をランダムにして攻撃者の狙い撃ちを防ぐ技術。
  • これがあるおかげで、バッファオーバーフロー攻撃の難易度が劇的に上がっている。
  • ただし、「メモリリークの脆弱性」と組み合わされると突破される可能性がある。

セキュリティは「これ一つで万全」というものはなく、ASLRのようなOS側の防御壁と、脆弱性のないセキュアなコードを書くことの組み合わせが重要ですね!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?