Relro

Support HackTricks

Relro

RELRO 代表 Relocation Read-Only,它是一种用于二进制文件的安全特性,用于减轻与 GOT (Global Offset Table) 重写相关的风险。RELRO 保护有两种类型:(1)部分 RELRO 和(2)完全 RELRO。它们都重新排列了 ELF 文件中的 GOTBSS,但结果和影响不同。具体来说,它们将 GOT 部分放在 BSS 之前。也就是说,GOT 的地址低于 BSS,因此通过溢出 BSS 中的变量来重写 GOT 条目是不可能的(记住,写入内存是从低地址向高地址进行的)。

让我们将这个概念分解为两个不同的类型以便于理解。

部分 RELRO

部分 RELRO 采取了一种更简单的方法来增强安全性,而不会显著影响二进制文件的性能。部分 RELRO 使 .got 变为只读(GOT 部分的非 PLT 部分)。请注意,部分(如 .got.plt)仍然是可写的,因此仍然容易受到攻击。这 并不防止 GOT任意写入 漏洞滥用。

注意:默认情况下,GCC 编译的二进制文件具有部分 RELRO。

完全 RELRO

完全 RELRO 通过 使整个 GOT(包括 .got 和 .got.plt)和 .fini_array 部分完全 只读 来增强保护。一旦二进制文件启动,所有函数地址都会在 GOT 中解析并加载,然后,GOT 被标记为只读,有效地防止在运行时对其进行任何修改。

然而,完全 RELRO 的权衡在于性能和启动时间。因为它需要在启动时解析所有动态符号,然后再将 GOT 标记为只读,启用完全 RELRO 的二进制文件可能会经历更长的加载时间。这种额外的启动开销是完全 RELRO 在所有二进制文件中默认未启用的原因。

可以通过以下方式查看二进制文件是否 启用 完全 RELRO:

readelf -l /proc/ID_PROC/exe | grep BIND_NOW

绕过

如果启用了完整的 RELRO,绕过它的唯一方法是找到另一种不需要在 GOT 表中写入以获取任意执行的方法。

请注意,LIBC 的 GOT 通常是部分 RELRO,因此可以通过任意写入进行修改。更多信息请参见 Targetting libc GOT entries.

Support HackTricks

Last updated