Libc Protections

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

Chunk Alignment Enforcement

Malloc 在内存分配时以 8 字节(32-bit)或 16 字节(64-bit)分组 进行分配。这意味着在 32-bit 系统中 chunk 的结束应与 0x8 对齐,而在 64-bit 系统中应与 0x0 对齐。这个安全特性会在从某个 bin 使用指针之前,检查每个 chunk 是否在这些特定位置 正确对齐

Security Benefits

在 64-bit 系统中强制 chunk 对齐显著提升了 Malloc 的安全性,因为它将伪造 chunk 的可放置位置限制为 每 16 个地址中的 1 个。这使得利用变得更加困难,尤其是在用户对输入值控制有限的场景中,使攻击更复杂且更难成功。

  • Fastbin Attack on __malloc_hook

新的对齐规则也阻止了涉及 __malloc_hook 的经典攻击。之前,攻击者可以操纵 chunk 大小来 覆盖该函数指针 并获得 code execution。现在,严格的对齐要求确保这类操纵不再可行,关闭了一条常见的利用路径并提升了整体安全性。

Note: Since glibc 2.34 the legacy hooks (__malloc_hook, __free_hook, etc.) are removed from the exported ABI. Modern exploits now target other writable function pointers (e.g. tcache per-thread struct, vtable-style callbacks) or rely on setcontext, _IO_list_all primitives, etc.

Pointer Mangling on fastbins and tcache

Pointer Mangling 是一种用于保护 fastbin 和 tcache Fd pointers 的安全增强手段,用于内存管理操作。该技术有助于防止某些类型的内存利用手法,特别是那些不需要 leaked memory 信息或直接相对已知位置操纵内存位置的技术(相对 overwrites)。

该技术的核心是一个混淆公式:

New_Ptr = (L >> 12) XOR P

  • L 是指针的 存储位置(Storage Location)
  • P 是实际的 fastbin/tcache Fd Pointer

在进行 XOR 操作之前将存储位置 L 右移 12 位的原因很关键。这个操作解决了内存地址最低 12 位确定性的一个漏洞,这些位通常由于系统架构约束而可预测。通过右移,这部分可预测的位被移出计算,从而增强了新生成的、被混淆指针的随机性,进而防止依赖这些可预测位的利用手法。

这种被混淆的指针利用了 ASLR 提供的现有随机性,ASLR 会随机化程序使用的地址,使攻击者难以预测进程的内存布局。

Demangling 指针以恢复原始地址需要使用相同的 XOR 操作。此处,将被混淆的指针视为公式中的 P,并与未变化的存储位置 L 进行 XOR,就能得到原始指针。混淆与解混淆在对称性上保证了系统可以高效地对指针进行编码和解码,而不会带来显著开销,同时大幅提升了对操纵内存指针攻击的防护。

Security Benefits

Pointer mangling 的目标是 防止堆管理中的部分或完整指针重写(pointer overwrites),这是对安全性的重大增强。该特性对利用技术有多方面影响:

  1. 阻止按字节的相对重写(Bye Byte Relative Overwrites):此前,攻击者可以修改指针的一部分以 在不知道精确地址的情况下 将堆 chunk 指向不同位置,这在无 leak 的 House of Roman 利用中有所体现。使用 pointer mangling 后,这类在没有 heap leak 的情况下的相对重写 如今需要蛮力穷举(brute forcing),大幅降低了成功率。
  2. 增加对 tcache Bin/fastbin 攻击的难度:通过操纵 fastbin 或 tcache 条目来覆盖函数指针(例如 __malloc_hook)的常见攻击会受到阻碍。例如,一种攻击可能先泄露一个 LibC 地址,将一个 chunk 释放到 tcache bin,然后覆盖 Fd 指针以将其重定向到 __malloc_hook 来实现任意代码执行。使用 pointer mangling 后,这些指针必须被正确混淆,需要 heap leak 才能准确操纵,从而提高了攻击门槛。
  3. 在非堆区域创建伪造 chunk 也需要 heap leak:在非堆区域(如栈、.bss 段或 PLT/GOT)创建伪造 chunk 现在也 需要 heap leak,因为需要处理指针混淆。这样对这些区域的利用复杂度也随之提高,类似于操纵 LibC 地址的难度。
  4. 泄露堆地址变得更具挑战性:Pointer mangling 限制了 fastbin 和 tcache bin 中 Fd 指针作为堆地址泄露源的可用性。然而,unsorted、small 和 large bin 中的指针仍未被混淆,因此仍可用于泄露地址。这个改变促使攻击者转向这些 bin 寻找可利用的信息,尽管某些技术仍可能在泄露前对指针进行解混淆,但带有一定限制。

Safe-Linking Bypass (page-aligned leak scenario)

即使启用了 safe-linking(glibc ≥ 2.32),如果你可以泄露被混淆的指针,并且被破坏的 chunk 与受害 chunk 共享相同的 4KB 页面,则仅通过页面偏移就可以恢复原始指针:

// leaked_fd is the mangled Fd read from the chunk on the same page
uintptr_t l = (uintptr_t)&chunk->fd;           // storage location
uintptr_t original = (leaked_fd ^ (l >> 12));  // demangle

这会恢复 Fd 并允许经典的 tcache/fastbin poisoning。如果 chunks 位于不同的 pages,当 allocation patterns 是确定性的或可接受崩溃(例如 CTF-style exploits)时,暴力破解 12-bit page 偏移(0x1000 种可能)通常是可行的。

Demangling Pointers with a Heap leak

Caution

有关该过程的更详尽说明,请查看原始帖子(在此)

Algorithm Overview

用于对指针进行 mangling 和 demangling 的公式是:

New_Ptr = (L >> 12) XOR P

其中 L 是存储位置,P 是 Fd 指针。当 L 右移 12 位时,会暴露 P 的高位,这是由于 XOR 的特性:当相同位相互 XOR 时会输出 0,从而使 P 的对应位得以显现。

算法的关键步骤:

  1. Initial Leak of the Most Significant Bits: 通过将移位后的 LP 做 XOR,实际上可以得到 P 的高 12 位,因为 L 被移位后对应的那部分为 0,从而使 P 的相应位保持不变。
  2. Recovery of Pointer Bits: 由于 XOR 是可逆的,已知结果和其中一个操作数即可计算出另一个操作数。这个特性被用来通过已知的位集合与 mangled 指针的部分位反复 XOR,从而推断出 P 的全部位。
  3. Iterative Demangling: 该过程会重复进行,每次使用上一步新发现的 P 位去解码 mangled 指针的下一段,直到恢复所有位。
  4. Handling Deterministic Bits: 由于移位,L 的最后 12 位会丢失,但这些位是确定性的,可以在事后重建。

此算法的实现可见于: https://github.com/mdulin2/mangle

Pointer Guard

Pointer Guard 是 glibc 中用来保护已存储函数指针(例如通过 atexit() 注册的那些)的 exploit mitigation 技术。该保护通过将指针与存储在线程数据(fs:0x30)中的一个秘密做 XOR 并进行位旋转来对指针进行混淆。此机制旨在阻止攻击者通过覆盖函数指针来劫持控制流。

Bypassing Pointer Guard with a leak

  1. Understanding Pointer Guard Operations: 指针的混淆(mangling)由 PTR_MANGLE 宏完成,该宏将指针与一个 64-bit 的秘密做 XOR,然后对结果执行左旋 0x11 位。恢复原始指针的反操作由 PTR_DEMANGLE 处理。
  2. Attack Strategy: 攻击基于已知明文(known-plaintext)方法,攻击者需要同时知道指针的原始值和其 mangled 版本,才能推断出用于 mangling 的秘密。
  3. Exploiting Known Plaintexts:
  • Identifying Fixed Function Pointers: 通过检查 glibc 源码或已初始化的函数指针表(如 __libc_pthread_functions),攻击者可以找到可预测的函数指针。
  • Computing the Secret: 利用已知的函数指针(例如 __pthread_attr_destroy)及其在函数指针表中的 mangled 版本,可以通过对 mangled 指针做右旋(reverse rotate)然后与函数地址 XOR 来计算出秘密。
  1. Alternative Plaintexts: 攻击者还可以尝试用已知值(例如 0 或 -1)对指针进行 mangling,查看这些模式在内存中是否产生可识别的特征,从而在内存转储中定位并泄露该秘密。
  2. Practical Application: 在计算出秘密后,攻击者可以以受控方式操纵指针,基本上可以在已知 libc 基址且能够读取任意内存位置的多线程应用中绕过 Pointer Guard 的保护。

GLIBC Tunables & Recent Loader Bugs

动态 loader 会在程序启动前解析 GLIBC_TUNABLES。这里的解析错误会直接在大多数缓解措施生效之前影响 libc。2023 年的 “Looney Tunables” 漏洞(CVE-2023-4911)就是一个例子:过长的 GLIBC_TUNABLES 值会溢出 ld.so 内部缓冲区,当与 SUID 二进制结合时,可在许多发行版上实现 privilege escalation。利用只需构造环境并反复调用目标二进制;pointer guard 或 safe-linking 无法阻止该利用,因为破坏发生在 loader 中、堆初始化之前。

References

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks