hacktricks/binary-exploitation/common-binary-protections-and-bypasses/libc-protections.md
2024-12-12 11:39:29 +01:00

11 KiB

Libc Protections

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Chunk Alignment Enforcement

Malloc allocates memory in 8-byte (32-bit) or 16-byte (64-bit) groupings. This means the end of chunks in 32-bit systems should align with 0x8, and in 64-bit systems with 0x0. The security feature checks that each chunk aligns correctly at these specific locations before using a pointer from a bin.

Security Benefits

The enforcement of chunk alignment in 64-bit systems significantly enhances Malloc's security by limiting the placement of fake chunks to only 1 out of every 16 addresses. This complicates exploitation efforts, especially in scenarios where the user has limited control over input values, making attacks more complex and harder to execute successfully.

  • Fastbin Attack on __malloc_hook

The new alignment rules in Malloc also thwart a classic attack involving the __malloc_hook. Previously, attackers could manipulate chunk sizes to overwrite this function pointer and gain code execution. Now, the strict alignment requirement ensures that such manipulations are no longer viable, closing a common exploitation route and enhancing overall security.

Pointer Mangling on fastbins and tcache

Pointer Mangling is a security enhancement used to protect fastbin and tcache Fd pointers in memory management operations. This technique helps prevent certain types of memory exploit tactics, specifically those that do not require leaked memory information or that manipulate memory locations directly relative to known positions (relative overwrites).

The core of this technique is an obfuscation formula:

New_Ptr = (L >> 12) XOR P

  • L is the Storage Location of the pointer.
  • P is the actual fastbin/tcache Fd Pointer.

The reason for the bitwise shift of the storage location (L) by 12 bits to the right before the XOR operation is critical. This manipulation addresses a vulnerability inherent in the deterministic nature of the least significant 12 bits of memory addresses, which are typically predictable due to system architecture constraints. By shifting the bits, the predictable portion is moved out of the equation, enhancing the randomness of the new, mangled pointer and thereby safeguarding against exploits that rely on the predictability of these bits.

This mangled pointer leverages the existing randomness provided by Address Space Layout Randomization (ASLR), which randomizes addresses used by programs to make it difficult for attackers to predict the memory layout of a process.

Demangling the pointer to retrieve the original address involves using the same XOR operation. Here, the mangled pointer is treated as P in the formula, and when XORed with the unchanged storage location (L), it results in the original pointer being revealed. This symmetry in mangling and demangling ensures that the system can efficiently encode and decode pointers without significant overhead, while substantially increasing security against attacks that manipulate memory pointers.

Security Benefits

Pointer mangling aims to prevent partial and full pointer overwrites in heap management, a significant enhancement in security. This feature impacts exploit techniques in several ways:

  1. Prevention of Bye Byte Relative Overwrites: Previously, attackers could change part of a pointer to redirect heap chunks to different locations without knowing exact addresses, a technique evident in the leakless House of Roman exploit. With pointer mangling, such relative overwrites without a heap leak now require brute forcing, drastically reducing their likelihood of success.
  2. Increased Difficulty of Tcache Bin/Fastbin Attacks: Common attacks that overwrite function pointers (like __malloc_hook) by manipulating fastbin or tcache entries are hindered. For example, an attack might involve leaking a LibC address, freeing a chunk into the tcache bin, and then overwriting the Fd pointer to redirect it to __malloc_hook for arbitrary code execution. With pointer mangling, these pointers must be correctly mangled, necessitating a heap leak for accurate manipulation, thereby elevating the exploitation barrier.
  3. Requirement for Heap Leaks in Non-Heap Locations: Creating a fake chunk in non-heap areas (like the stack, .bss section, or PLT/GOT) now also requires a heap leak due to the need for pointer mangling. This extends the complexity of exploiting these areas, similar to the requirement for manipulating LibC addresses.
  4. Leaking Heap Addresses Becomes More Challenging: Pointer mangling restricts the usefulness of Fd pointers in fastbin and tcache bins as sources for heap address leaks. However, pointers in unsorted, small, and large bins remain unmangled, thus still usable for leaking addresses. This shift pushes attackers to explore these bins for exploitable information, though some techniques may still allow for demangling pointers before a leak, albeit with constraints.

Demangling Pointers with a Heap Leak

{% hint style="danger" %} For a better explanation of the process check the original post from here. {% endhint %}

Algorithm Overview

The formula used for mangling and demangling pointers is:

New_Ptr = (L >> 12) XOR P

Where L is the storage location and P is the Fd pointer. When L is shifted right by 12 bits, it exposes the most significant bits of P, due to the nature of XOR, which outputs 0 when bits are XORed with themselves.

Key Steps in the Algorithm:

  1. Initial Leak of the Most Significant Bits: By XORing the shifted L with P, you effectively get the top 12 bits of P because the shifted portion of L will be zero, leaving P's corresponding bits unchanged.
  2. Recovery of Pointer Bits: Since XOR is reversible, knowing the result and one of the operands allows you to compute the other operand. This property is used to deduce the entire set of bits for P by successively XORing known sets of bits with parts of the mangled pointer.
  3. Iterative Demangling: The process is repeated, each time using the newly discovered bits of P from the previous step to decode the next segment of the mangled pointer, until all bits are recovered.
  4. Handling Deterministic Bits: The final 12 bits of L are lost due to the shift, but they are deterministic and can be reconstructed post-process.

You can find an implementation of this algorithm here: https://github.com/mdulin2/mangle

Pointer Guard

Pointer guard is an exploit mitigation technique used in glibc to protect stored function pointers, particularly those registered by library calls such as atexit(). This protection involves scrambling the pointers by XORing them with a secret stored in the thread data (fs:0x30) and applying a bitwise rotation. This mechanism aims to prevent attackers from hijacking control flow by overwriting function pointers.

Bypassing Pointer Guard with a leak

  1. Understanding Pointer Guard Operations: The scrambling (mangling) of pointers is done using the PTR_MANGLE macro which XORs the pointer with a 64-bit secret and then performs a left rotation of 0x11 bits. The reverse operation for recovering the original pointer is handled by PTR_DEMANGLE.
  2. Attack Strategy: The attack is based on a known-plaintext approach, where the attacker needs to know both the original and the mangled versions of a pointer to deduce the secret used for mangling.
  3. Exploiting Known Plaintexts:
    • Identifying Fixed Function Pointers: By examining glibc source code or initialized function pointer tables (like __libc_pthread_functions), an attacker can find predictable function pointers.
    • Computing the Secret: Using a known function pointer such as __pthread_attr_destroy and its mangled version from the function pointer table, the secret can be calculated by reverse rotating (right rotation) the mangled pointer and then XORing it with the address of the function.
  4. Alternative Plaintexts: The attacker can also experiment with mangling pointers with known values like 0 or -1 to see if these produce identifiable patterns in memory, potentially revealing the secret when these patterns are found in memory dumps.
  5. Practical Application: After computing the secret, an attacker can manipulate pointers in a controlled manner, essentially bypassing the Pointer Guard protection in a multithreaded application with knowledge of the libc base address and an ability to read arbitrary memory locations.

References

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}