据我了解,ASLR 有 3 种模式:
- 0 - 关闭
- 1 - 随机化堆栈、堆、共享库、vDSO、mmap 内存区域和文本区域(如果使用 -fPIE -pie 构建)
- 2 - 另外随机
brk()分配的内存,据我了解,这主要来自小malloc()调用。
为什么有一个额外的模式,特别是用于brk()分配的内存(如果这真的是它所做的一切),它有多重要,或者更确切地说,何时使用 ASLR 的模式 2 而不是模式 1 很重要?
据我了解,ASLR 有 3 种模式:
brk()分配的内存,据我了解,这主要来自小malloc()调用。为什么有一个额外的模式,特别是用于brk()分配的内存(如果这真的是它所做的一切),它有多重要,或者更确切地说,何时使用 ASLR 的模式 2 而不是模式 1 很重要?
还必须有一种特定的随机化方式brk(),因为除了 glibc 的默认 (ptmalloc) 之外,还有一些可能不依赖的堆实现brk(),如果仅使用,则直接使用brk()unprotected 到可预测的地址空间va_randomize_space = 1。
这也很重要,因为攻击者可以使用直接SYS_brk系统调用来制作 shellcode,以将内存映射到预测的地址空间以进行处理。
快速查看 Linux 内核源代码建议将 ASLR 设置为模式 2 仅此而已:随机化动态内存映射地址空间的开始:
https://github.com/torvalds/linux/blob/master/fs/binfmt_elf.c#L1110-L1123
<!-- language: lang-c -->
if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) {
/*
* For architectures with ELF randomization, when executing
* a loader directly (i.e. no interpreter listed in ELF
* headers), move the brk area out of the mmap region
* (since it grows up, and may collide early with the stack
* growing down), and into the unused ELF_ET_DYN_BASE region.
*/
if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) &&
elf_ex->e_type == ET_DYN && !interpreter) {
mm->brk = mm->start_brk = ELF_ET_DYN_BASE;
}
mm->brk = mm->start_brk = arch_randomize_brk(mm);
#ifdef compat_brk_randomized
current->brk_randomized = 1;
#endif
}
https://github.com/torvalds/linux/blob/master/mm/mmap.c#L212-L213
<!-- language: lang-c -->
if (current->brk_randomized)
min_brk = mm->start_brk;