系统安全浅薄知识系列(一)-ASLR

作者:@Diting0x
转载请注明:作者信息以及来源《CSysSec:系统安全浅薄知识系列(一)-ASLR》


ASLR全称是Address Space Layout Randomization,翻译成中文就是地址空间布局随机化。

怎么做?

随机化程序的关键数据在内存中的位置,这些数据包括程序的数据段、堆、栈以及共享库。见下图:(图来源于CCS’15)




这些数据为什么没有包括代码段? 下文会继续讨论。

干嘛用的?

ASLR是一种保护缓冲区溢出攻击的防御技术,通过增加内存攻击(如return-into-libc或ROP)预测目标地址的难度阻碍其实施攻击。见下图:(图来源于CODASPY’16)




攻击者欲跳转到目标地址0xbfffd5d8的shellcode中,但在执行时其地址被随机化到了0xbfffe3f8中,此时跳转到0xbfffd5d8会导致内存奔溃。

ASLR历史

请看下图:(图来源于Abusing Performance Optimization Weaknesses to Bypass ASLR, 2014 BlackHat USA)




如何开启或关闭ASLR?

以Linux系统为例,通过配置/proc/sys/kernel/randomize_va_space中的值来开启或关闭ASLR.
运行cat /proc/sys/kernel/randomize_va_space命令,若输出为0,表示没有随机化,所有都是静态的;若输出为1,表示保守随机化,共享库、栈、mmap(),VDSO以及堆都被随机化;若输出为2,表示全随机化,在1的基础上,增加了通过brk()方式内存管理的随机化。
下图为Ubuntu14.04的结果

aslr3

关闭ASLR,可以运行echo 0 /proc/sys/kernel/randomize_va_space

Windows和Linux在ASLR机制上有所不同,想了解详情可以参考这里

编译成PIE?

说到这里,还遗留了一个问题,那就是随机化的数据为什么没有包括代码段? 要想让ASLR机制有效,就必须保证程序在内存空间的所有区域都是随机化的。有任何一部分没有被随机化,都有可能被攻击者利用来定位有效的gadgets来实施攻击。实际上,ASLR对代码段(.text)是不作随机化的,只有当可执行文件在编译成PIE(Position Independent Executable,位置依赖可执行文件)时,代码段才会被随机化。

对于non-PIE(也就是没有添加编译选项PIE),尽管ASLR的级别设置为2,攻击者仍然能利用程序的.text段以及GOT/PLT(全局偏移表/过程连接表)实施攻击(比如return-to-got/plt、ROP)。

既然non-PIE的可执行文件不能享受ASLR机制带来的安全性,那ASLR又有何意义? 是不是可以把所有的程序在编译时都加上PIE选项? 对Linux系统来说,是有选择性的编译PIE,所有的库文件都是默认编译成PIE的,而大部分程序默认是不会被编译成PIE的。详情可以参考这篇论文的发现Too much PIE is bad for performance

说了这么多,PIE的原理是什么?文章提到的这么多专有名词,ROP, Return-to-libc,Return-to-GOT/PIT, gadgets都又是什么呢?有机会再谈。

References

Lu et al,”ASLR-Guard: Stopping Address Space Leakage for Code Reuse Attacks”,CODASPY’16
Gu et al, “Derandomizing Kernel Address Space Layout for Memory Introspection and Forensics”, CCS’15
ASLR在Windows与Linux系统之间的差别
PAX/ASLR
How Effective is ASLR on Linux Systems?


转载请注明:作者信息以及来源《CSysSec:系统安全浅薄知识系列(一)-ASLR》