📜  信息安全 – 回到 LIBC

📅  最后修改于: 2022-05-13 01:57:28.543000             🧑  作者: Mango

信息安全 – 回到 LIBC

缓冲区溢出是最早出现的漏洞之一,因此当它在 1996 年发布时,信息安全还不是一个流行的领域,并且不清楚如何处理它。像重新排序变量这样的解决方案很好地展示了这一点。 安全研究人员不了解黑客,不知道如何像他们一样思考,因此处于巨大的劣势。

缓冲区溢出攻击的缓解措施

1. 第一个缓解价值被称为金丝雀,以小黄鸟命名,以及它如何帮助保护矿工在我们的例子中,canary 将是一些将存储在返回地址存储位置和缓冲区分配位置之间的值。在函数返回之前,它应该检查那个值的完整性,看看它没有改变。

信息安全---返回到LIBC

2.如果没有,世界就一切都好。如果确实如此,则说明有人一直在溢出缓冲区,我们应该在他们接管之前中止程序。这很有用,因为当缓冲区溢出时,它会按顺序进行。它不能跳过字节。这意味着,如果攻击者确实溢出了缓冲区,并确实覆盖了返回地址,那么她一定也通过了金丝雀,并在此过程中破坏了它,从而泄露了她的信息。



3. 这种缓解措施不会阻止缓冲区溢出,但会使执行变得更加困难。因为不经过金丝雀就无法到达返回地址,它的值是随机的,很难猜测。然而,它并不完美。例如,信息泄露漏洞可能让攻击者窥探内存,查看程序使用的金丝雀,并制作缓冲区溢出,使其用自己的值覆盖金丝雀,从而保持其完整性并使一切看起来都正常。

信息安全---返回到 LIBC2

4.有用的缓解措施称为数据执行预防或 DEP。我喜欢它的是它不仅仅治疗症状。真的需要退一步重新评估情况,然后提出一个非常合理的问题,为什么缓冲区甚至可以执行?

为什么缓冲区是可执行的

1.每个内存区域都有某些在硬件级别强制执行的特性。它可以是可读的,在这种情况下我们有读取它的权限,它可以是可写的,在这种情况下我们有写入它的权限,而安全专家所做的是引入另一个特性,它是否可执行,在这种情况下我们有权像运行代码一样运行此内存。

2.这通常称为NX 位,表示不可执行,因此我们可以将堆栈(存储缓冲区和返回地址的内存区域)映射为不可执行。现在,即使攻击者成功溢出缓冲区,覆盖返回地址,并将程序执行转移到该缓冲区,硬件也会拒绝将该缓冲区作为代码执行,并中止程序。

信息-安全--返回-LIBC3

3.更一般地说,这被称为 W^X 原则。内存应该是可写的或可执行的,但不能两者兼而有之,因为这样攻击者可能能够在那里编写一些任意代码并转移程序执行来运行它。好消息是 Canary 和 DEP 都被广泛使用,并且默认情况下处于启用状态。大多数编译器会自动添加金丝雀,也称为堆栈保护,并将堆栈标记为不可执行。



信息安全---返回到 LIBC4

4. DEP 不会阻止缓冲区溢出,而是阻止在堆栈上执行代码。

5.我们仍然可以覆盖函数的返回地址,但是已经失去了在缓冲区上写入可执行代码的能力,我们需要弄清楚跳转到哪里以及运行什么来代替。你知道什么仍然映射为可执行文件吗?代码。

6.每个进程在内存中的某处都有定义其执行流程的代码。事实上,这就是函数返回地址首先指向的地方。如果函数f 调用函数g,后者调用函数h,在该函数中堆栈溢出,我们可以更改返回地址,因此我们跳过它并直接返回 f,而不是返回 g。

信息安全---返回到 LIBC6

7.但那又怎样?每个程序的代码都是独一无二的,并且按照定义执行程序应该执行的操作。所以,混合和匹配它来做一些恶意的事情并不是那么容易,而且绝对不是跨程序通用的。

8.幸运的是,或者不那么幸运,大多数程序都使用通用的外部库,首先是 C 标准库或 libc。该库定义了诸如 memcmp、memcpy 和 printf 等基本函数,这些函数是构建所有其他代码的基础。

9.你明白这是怎么回事吗?如果我们可以覆盖返回地址指向代码中的其他地方,并且所有代码都包含这些构建块,那么我们可以覆盖返回地址,实际上是多个后续的返回地址,以这样的方式和这样的方式跳转到所有地方为了将某种弗兰肯斯坦代码拼凑在一起,这可以是任意复杂的。

10.另一种思考方式是,在失去写作能力后,我们仍然可以通过拿一份报纸来写一封信,从报纸上剪下单词,然后重新排列它们以传达我们自己的信息,就像在赎金纸上一样.

11.在这种情况下,我们没有删除任何内容,而是覆盖一系列返回地址以指向这样的地方,一旦函数返回,它就会启动有效执行我们出价的连锁反应。真正令人沮丧的是 DEP 对此无能为力,因为它是由实际的可执行代码组成的。

例子

1.我们用称为系统的标准 C函数的地址覆盖函数的返回地址。这个函数接受一个参数,字符串命令,然后执行那个命令。这个参数也存储在内存中,所以我们可以进一步覆盖内存,这样一旦我们返回,系统函数被调用,并寻找它的参数,它会找到我们提供的一个值,即“sh”或“ cmd”,一个启动 shell 的命令。

2.正如我们所知,一旦我们有了外壳,游戏就结束了。

注 – 为了减轻这种称为“返回 libc”的攻击,操作系统采用了地址空间布局随机化或 ASLR。这是一种奇特的说法,每次启动进程时,我们应该加载它的代码,最重要的是,加载它使用的任何外部库,以稍微不同的或随机的地址。这样,当返回到 libc 的攻击尝试跳到那里时,它将很难到达预期的位置。当然,这还不够。

信息安全---返回到 LIBC5

注意:没有什么是足够的。一个不相关的信息泄露漏洞可能会泄露一些地址,我们或许可以用它来推断 libc 的确切加载位置,并相应地校准我们的攻击。但它确实极大地阻碍了攻击,并且目前在所有主要操作系统中默认启用。