信息隐藏大多数当前操作系统的主要防线之一是隐藏攻击者可能感兴趣的任何内容。具体来说,通过随机化所有相关内存区域(在代码、堆、全局数据和堆栈中)的位置,攻击者将不知道将控制流转移到哪里,也无法发现哪些地址包含敏感数据等。地址空间布局随机化(ASLR)这个术语是在2001年为Linux内核实现这种随机化的PaX安全补丁发布时创造的[72]——另请参阅软件安全CyBOK知识区中的讨论。很快,类似的努力出现在其他操作系统中,第一个默认启用ASLR的主流操作系统是2003年的OpenBSD和2005年的Linux。随后是2007年的Windows和MacOS。但是,这些早期的实现只是随机化了用户程序中的地址空间,直到大约十年后,随机化才以KernelASLR(KASLR)的名义进入主要操作系统的内核。在用户程序中默认启用后。这个想法的城堡很简单,但有许多重要的设计决定需要您自己做出。例如,随机有多随机?我们在这个地址的哪一部分随机化?假设您的Linux目录内核的代码地址范围为1GB(=230),代码应该与2兆字节(=221)边界保持一致。可用于随机化的位数(的熵)为3021=9位。换句话说,我们最多需要512次猜测才能找到内核代码。如果攻击发现一个漏洞,将内核的控制流从猜测的地址转移到用户空间程序,并且每次错误的猜测都会导致系统崩溃,它愿意让用户空间访问几百台机器来获得它很有可能在Minimal中正确一次(尽管在此过程中会有多台机器崩溃)。另一个重要的决定是随机化什么。今天的大多数实现都采用粗粒度随机化:它们随机化代码、堆或堆栈的基本位置,但在这些区域内,每个元素都位于距基本元素的固定偏移量处。这很简单,而且非常快。然而,一旦攻击者设法通过信息泄漏获得哪怕是单个代码指针,他们就会知道每条指令的地址。堆、堆栈等也是如此。毫不奇怪,这些信息泄漏是当今攻击者高度重视的目标。更细粒度的随机化也是可能的。例如,可以在页面级别或功能级别进行随机化。如果我们打乱内存区域中函数的顺序,即使知道内核代码的基础知识对于攻击者来说也是不够的。事实上,我们可以洗牌基本块、指令(可能使用从未执行或无效的垃圾指令),甚至可以更细粒度地进行寄存器分配。许多细粒度随机化技术是以空间和时间开销为代价的,例如由于位置和碎片减少。除了代码之外,数据的细粒度随机化也是可能的。例如,研究表明,堆栈上的堆分配、全局变量,甚至变量都可以分散在内存中。当然,这样做会产生性能和内存成本。考虑到KASLR,尤其是粗粒度的KASLR,是我们抵御内存错误攻击的第一道防线,这不会离题太远。不幸的是,它也是一种非常薄弱的??防御。许多出版物表明,通过从内存、侧通道等泄漏数据和/或代码指针,可以相当容易地破解KASLR。
