コース目次 / 第2章
/proc/PID/maps と、ASLRの正体
プロセスの仮想メモリのレイアウトを/proc/PID/mapsで確認します。同じバイナリを複数回実行してロードアドレスが毎回変わることを観察し、setarch -Rでその変化が止まることを確認して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章です。
この章はまだ完了していません。
保存できませんでした(プライベートブラウズ中かもしれません)。この端末に進捗は残りませんが、先へは進めます。