美文网首页
地址空间布局随机化ASLR

地址空间布局随机化ASLR

作者: BetterCV | 来源:发表于2020-04-30 09:56 被阅读0次
maxresdefault.jpg

观察问题

用Visual Studio调试程序时,同一个代码的同一个断点处,打印栈变量地址,发现每次都不一样

而如果是在Linux下用gdb调试,每次打印出的地址不变;直接执行程序,则每次地址又不一样

栈内存上变量的地址,为什么会不一样,又为什么会一样?

这其实是不同的ASLR设定下的表现。

ASLR概念

ASLR(Address Space Layout Randomization,地址空间布局随机化),是一种针对缓冲区溢出的安全保护技术。借助ASLR,PE文件每次加载到内存的起始地址都会随机变化。目前大部分主流操作系统都已经实现了ASLR,如Windows Vista、Linux 2.6.12、Mac OS X 10.7、iOS 4.3以及Android 4.0均从此版本开始支持ASLR。

简单说,ASLR使得渗透(基于缓冲区溢出)攻击的难度明显提升,增加了系统的安全性。但是,对于不是搞安全/逆向的Programmer来说,在调试程序时这就略显蛋疼。控制变量是调试阶段的一大原则。

临时修改ASLR

ASLR需要操作系统和程序自身的双重支持。Ubuntu16.04和Win10系统都默认开启了ASLR;对于自己有源码的情况,通过修改链接选项,生成的可执行程序可以关闭ASLR。

Visual Studio 2017

项目属性->链接器->高级->随机基址,改为“否(/DYNAMICBASE:NO)”即可:

ASLR_VisualStudio.png

GDB
GDB默认关闭了随机化的基址,这对于调试很友好。不过也可以在~/.gdbinit中进行配置:

#关闭ASLR
set disable-randomization
#或:
set disable-randomization on

#打开ASLR
set disable-randomization off

注意,MinGW环境下disable-randomization的设定不被支持。

举例

如下代码,打印&p的值,当关闭ASLR后,可以保持不变。

#include <stdio.h>
int main()
{
   char * p = malloc(10);
   printf("heap=%p stack=%p\n", p, &p);
}

堆随机化

前面的原理和设定说明,都是在处理栈内存。堆内存能否关闭ASLR呢?

这里会有些复杂,因为 Linux 中堆空间可以通过 mmap() 以及 brk() 这两个系统调用完成的,而在不同的等级上面可能会只有部分接口被随机化。

一般谁使用 glibc 中的 malloc() 类接口分配内存,通过 man 3 malloc 可以发现其中有相关的介绍,也就是当超过了 MMAP_THRESHOLD 大小后会使用 mmap(),否则使用 brk() 申请。

如果当前 ASLR 等级为 1,那么当申请空间大于 128K 时,系统通过 mmap() 分配空间,得到的地址是随机的;而当申请空间小于 128K 时,系统是通过 brk() 进行分配的,得到的地址是静止的

参考

地址空间布局随机化(ASLR)
ASLR(Address space layout randomization)地址空间布局随机化
关于Linux下ASLR与PIE的一些理解
Disable randomization of memory addresses
GCC 安全编译选项

相关文章

网友评论

      本文标题:地址空间布局随机化ASLR

      本文链接:https://www.haomeiwen.com/subject/kpoawhtx.html