Jump to content
Nytro

Bypassing Pointer Guard in Linux's glibc

Recommended Posts

Bypassing Pointer Guard in Linux's glibc

 
 
Dr Silvio Cesare
@silviocesare
 

Summary 

Pointer guard is an exploit mitigation in glibc that applies to stored pointers and especially stored function pointers. A number of library calls can register function pointers that get executed later on. An example of this is registering an exit handler with atexit(). Stored function pointers are scrambled or mangled by XORing them with a secret in the thread data (fs:0x30) and applying a bitwise rotation. This mitigates control-flow hijacking by an attacker who would otherwise be able to overwrite the stored function pointer with a location of their choosing. In this blog post, I'll present a bypass for pointer guard in multithreaded applications where an attacker knows the libc base address and has an arbitrary read.
 

Introduction

Pointer guard is documented in glibc reference materials https://sourceware.org/glibc/wiki/PointerEncryption. The mitigation provides a set of macros that mangle and demangle pointers. The API to use is PTR_MANGLE and PTR_DEMANGLE. For example, if an application wants to store a function pointer in *stored_ptr, they could use the following:

*stored_ptr = PTR_MANGLE(ptr)

And to demangle it:

ptr = PTR_DEMANGLE(*stored_ptr);

The pointer mangling works by XORing the pointer with an internal 64-bit secret, then performing a bitwise left rotatation of 0x11 bits (on x86-64). Demangling is the reverse.

Related Work

After I tweeted the requirements for this attack, I was linked to http://binholic.blogspot.com/2017/05/notes-on-abusing-exit-handlers.html. This is similar attack to the one I present with some specific differences. Interested readers are advised to review it.
 

The Attack

The attack is essentially a known-plaintext attack against the mangling operation. If we know the original pointer and its mangled version, we can recover the 64-bit secret.

How do we get known plaintexts? The related work linked earlier shows 1 way to identify known plaintext. I will present another approach.

Let's grep -rw PTR_MANGLE glibc/ --include '*.c' and examine each reference. I can quickly see an interesting use:
 
ptr_mangle_pthread_init.png

In thread initialization, we can see a function pointer table at a fixed address (__libc_pthread_functions).

If we examine what the first entry of this function pointer table, we can see that it points to __pthread_attr_destroy.

This is enough to defeat pointer guard if we know the library base from an ASLR leak. This is shown in the following pseudo code.
  
x = __libc_pthread_functions[0];
secret = rotr64(x, 0x11) ^ &__pthread_attr_destroy;

There is something else we can try. Is there a possibility that there is a mangled function pointer where the function pointer is equal to 0 or perhaps -1 or another fixed constant?

I write some test code to recover the cookie in a multithreaded application, and then i take the results of:

PTR_MANGLE(0);
PTR_MANGLE((unsigned long)-1);

In GDB using the GEF debugging plugin, I use pattern-search to find any such memory in the address space that has stored one of these mangled pointers with known plaintexts (pointers).

I find one.

__libc_pthread_functions[1] in my particular application has a mangled NULL pointer.

To defeat pointer guard then after program initialization, given the address of __libc_pthread_functions, is:

secret = rotr64(__libc_pthread_functions[1], 0x11);

From this point, an attacker can safely and correctly mangle their own pointers.
 

Conclusion

In this blog post, I presented an attack against the pointer guard exploit mitigation in Linux's glibc. The bypass requires the base address of libc and an arbitrary read.

 

Sursa: https://blog.infosectcbr.com.au/2020/04/bypassing-pointer-guard-in-linuxs-glibc.html

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...