ASLR(Adress Space Layout Randomization)
ASLRはプロセスのアドレス空間における実行ファイルの基底、ライブラリ、ヒープ、スタックの位置をランダムにする機能です。
ASLR検証用プラグラム
#include <stdio.h>
#include <stdlib.h>
int global_var;
int global_initialized_var = 0;
int main(){
int stack_var;
static int static_initialized_var = 5;
static int static_var;
int *heap_var_ptr;
heap_var_ptr = (int *) malloc(4);
// 以下の変数はデータセグメントに格納される
printf("global_initialized_varは0x%08xにあります。\n", &global_initialized_var);
printf("static_initialized_varは0x%08xにあります。\n", &static_initialized_var);
// 以下の変数はbssセグメントに格納される
printf("static_varは0x%08xにあります。\n", &static_var);
printf("global_varは0x%08xにあります。\n", &global_var);
// 以下のポインタ変数はヒープセグメントにあります。
printf("heap_var_ptrは0x%08xを挿しています。\n", heap_var_ptr);
// 以下の変数はスタックセグメント内にあります。
printf("stack_varは0x%08xにあります。\n", &stack_var);
return 0;
}
- 初期化されていないグローバル変数はbssセグメントに置かれます。
- 初期化されたグローバル変数はデータセグメント上に置かれます。
- 初期化されていないstaticローカル変数はbssセグメントに置かれます。
- 初期化されたstaticローカル変数はデータセグメントに置かれます。
- mallocで確保された領域はヒープセグメントに置かれます。
- 通常のローカル変数はスタックセグメントに置かれます。
ASLR無効化時の挙動
k0u5uk3@debian:~$ ./a.out global_initialized_varは0x0804988cにあります。 static_initialized_varは0x08049884にあります。 static_varは0x08049890にあります。 global_varは0x08049894にあります。 heap_var_ptrは0x0804a008を挿しています。 stack_varは0xbffff718にあります。 k0u5uk3@debian:~$ ./a.out global_initialized_varは0x0804988cにあります。 static_initialized_varは0x08049884にあります。 static_varは0x08049890にあります。 global_varは0x08049894にあります。 heap_var_ptrは0x0804a008を挿しています。 stack_varは0xbffff718にあります。
全ての変数は同じ位置に配置されているのがわかります。
ASLR有効化時の挙動
k0u5uk3@debian:~$ ./a.out global_initialized_varは0x0804988cにあります。 static_initialized_varは0x08049884にあります。 static_varは0x08049890にあります。 global_varは0x08049894にあります。 heap_var_ptrは0x08701008を挿しています。 stack_varは0xbfe52698にあります。 k0u5uk3@debian:~$ ./a.out global_initialized_varは0x0804988cにあります。 static_initialized_varは0x08049884にあります。 static_varは0x08049890にあります。 global_varは0x08049894にあります。 heap_var_ptrは0x09d32008を挿しています。 stack_varは0xbf892468にあります。
ヒープ領域、スタック領域のメモリアドレスはランダム化されていることがわかります。
- ASLRが有効なのかを調べる
sudo sysctl -a | grep kernel.randomize_va_space
- ASLR設定
#無効化 sudo sysctl -w kernel.randomize_va_space=0 #stackセグメントのみをランダム化 sudo sysctl -w kernel.randomize_va_space=1 #stack, heap, mmap locationランダム化 sudo sysctl -w kernel.randomize_va_space=2
- 実行時にsetarchでASLRを無効化する。
setarch `arch` -R ./victim
- 32bit環境でのulimitによるASLR無効化
ulimit -s unlimited
- gdb上でのASLR有効化
gdbはデフォルトでASLRが無効化されるので有効化した状態でデバッグする。
show disable-randomization set disable-randomization off
参考文献
- http://inaz2.hatenablog.com
- http://d.hatena.ne.jp/yupo5656/20060625/p2
- http://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/c905.html
- アドレス空間配置のランダム化
- https://www.ipa.go.jp/files/000013695.pdf
- http://pacsec.jp/psj04/psj04-hiroaki-j.ppt
- http://postd.cc/64-bit-linux-return-oriented-programming/