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