コース目次 / 第2章

/proc/PID/maps と、ASLRの正体

プロセスの仮想メモリのレイアウトを/proc/PID/mapsで確認します。同じバイナリを複数回実行してロードアドレスが毎回変わることを観察し、setarch -Rでその変化が止まることを確認してASLRの正体を理解します。

第2章 / 全5章目安 約15分この章のゴール: /proc/PID/mapsの読み方を理解し、ASLRの効果を自分の目で確認できるようになる

仮想メモリの、地図を見る

head -8 /proc/14341/maps
560c17503000-560c17504000 r--p 00000000 fe:00 1884302  /path/to/sleepy
560c17504000-560c17505000 r-xp 00001000 fe:00 1884302  /path/to/sleepy
560c17505000-560c17506000 r--p 00002000 fe:00 1884302  /path/to/sleepy
560c17506000-560c17507000 r--p 00002000 fe:00 1884302  /path/to/sleepy
560c17507000-560c17508000 rw-p 00003000 fe:00 1884302  /path/to/sleepy
560c4a54d000-560c4a56e000 rw-p 00000000 00:00 0        [heap]
7f2336000000-7f2336028000 r--p 00000000 fe:00 152035   /usr/lib/x86_64-linux-gnu/libc.so.6
7f2336028000-7f23361b0000 r-xp 00028000 fe:00 152035   /usr/lib/x86_64-linux-gnu/libc.so.6

1行が1つのメモリ領域です。アドレス範囲(開始-終了)、権限(r=読める、w=書ける、x=実行できる)、紐づくファイル(バイナリ自身、[heap]、共有ライブラリなど)が並びます。r-xp(読める・実行できる・書けない)の領域は、mini-binで見たELFの実行可能なコード部分です。rw-p(読める・書ける・実行できない)の領域は、データや[heap]です。実行可能な領域は書き込めず、書き込める領域は実行できない——sec-cで見たNX保護が、ここに表れています。

同じプログラムを、2回実行してみる

./sleepy & PID1=$!; sleep 0.3; head -1 /proc/$PID1/maps; kill $PID1
559ed09d7000-559ed09d8000 r--p ... /path/to/sleepy
./sleepy & PID2=$!; sleep 0.3; head -1 /proc/$PID2/maps; kill $PID2
55f95a166000-55f95a167000 r--p ... /path/to/sleepy

まったく同じバイナリを実行したのに、ロードされたアドレスが毎回違います。これがASLR(Address Space Layout Randomization、アドレス空間配置のランダム化)です。cat /proc/sys/kernel/randomize_va_spaceが2なら、ASLRが有効です。

ASLRを、切ってみる

setarch -R ./sleepy & PID3=$!; sleep 0.3; head -1 /proc/$PID3/maps; kill $PID3
555555554000-555555555000 r--p ... /path/to/sleepy
setarch -R ./sleepy & PID4=$!; sleep 0.3; head -1 /proc/$PID4/maps; kill $PID4
555555554000-555555555000 r--p ... /path/to/sleepy

setarch -R(ASLRを無効化して実行するオプション)を付けると、2回とも同じアドレスになりました。これが、ASLRが無い場合の世界です。mini-ctf-pwnで扱ったret2winは、まさに-no-pieでこのランダム化を止めた状態を悪用していました。ASLRが有効だと、攻撃者は「どこにwin()があるか」を事前に決め打ちできません。

こうなっていればOK

卒業まであと2章です。

この章はまだ完了していません。