読者です 読者をやめる 読者になる 読者になる

ASLRについてのまとめ

pwn

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

参考文献