Skip to content

Pointer mangling (glibc PTR_MANGLE)

glibc, hassas saklanmış function pointer'larını (longjmp hedefleri, atexit/exit handler'ları, TLS destructor'ları) PTR_MANGLE ile karıştırır — TCB'deki process başına rastgele bir pointer_guard'a karşı XOR, ardından bir bit-rotate — böylece pointer'ın üzerine yazan bir saldırgan, önce guard'ı leak etmeden kullanılabilir bir adres sağlayamaz.

Mechanism

Neden çalışır

Birkaç glibc structure'ı, daha sonra indirect olarak çağrılan raw function pointer'lar saklar: setjmp tarafından kaydedilen / longjmp tarafından geri yüklenen jmp_buf, exit handler listesi (__exit_funcs, atexit/on_exit'ten) ve thread başına destructor listesi (tls_dtor_list, __call_tls_dtors tarafından çalıştırılan). Eğer saldırgan bu pointer'lardan birini bozabilirse (jmp_buf'a bir heap overflow, exit-handler listesinde bir UAF), bir sonraki longjmp/exit'te control'ü yönlendirir.

Pointer mangling, value-forgery yolunu kapatır. Bir pointer saklanmadan önce glibc PTR_MANGLE uygular: pointer'ı secret process başına 64-bit bir pointer_guard ile XOR et, sonra sabit bir miktar rotate-left et. Kullanımdan önce tersi olan PTR_DEMANGLE'ı uygular: rotate-right sonra XOR. Secret, Thread Control Block'ta yaşar — x86-64'te %fs:0x30'daki tcbhead_t.pointer_guard — process başlangıcında randomize edilir.

Invariant: heap/data segment'inde saklanmış bir function pointer gerçek adres değil, rol(addr XOR guard, n)'dir. Saklanan değerin üzerine istediği bir hedef T ile yazan bir saldırgan aslında T'yi yüklemiştir, ama PTR_DEMANGLE ror(T, n) XOR guard hesaplayıp oraya atlayacaktır — saldırganın guard'ı bilmeden kontrol edemeyeceği bir değer. Yani mangling, "bir pointer'ın üzerine yaz"ı "önce process başına guard'ı leak et"e indirger.

Walkthrough

1. x86-64 makroları. glibc'nin sysdep.h'i onları, TCB guard'a karşı bir XOR artı 2*LP_SIZE+1 = 0x11 (17) bit'lik bir rotate olarak tanımlar:

# PTR_MANGLE: store side
    xor    %fs:0x30, %reg        # XOR with tcbhead_t.pointer_guard
    rol    $0x11,    %reg        # rotate left 17

# PTR_DEMANGLE: use side (exact inverse)
    ror    $0x11,    %reg        # rotate right 17
    xor    %fs:0x30, %reg        # XOR with pointer_guard

2. Neyi korur. Bu makrolardan geçen üç pointer sınıfı:

Structure Set by Demangled & called by
jmp_buf setjmp/sigsetjmp longjmp
__exit_funcs atexit / on_exit __run_exit_handlers
tls_dtor_list __cxa_thread_atexit __call_tls_dtors

3. Tüm savunma guard'ın gizliliğine dayanır. Eğer saldırgan, plaintext hedefini bildiği (örn. bilinen bir exit-handler) tek bir mangle'lanmış pointer leak ederse, guard'ı cebirsel olarak kurtarır ve kendi keyfi hedeflerini mangle'layabilir:

/* leaked = rol(known_fn XOR guard, 0x11)  ->  solve for guard */
guard = ror(leaked, 0x11) ^ known_fn;

/* now forge any pointer the demangler will accept */
forged = rol(target_fn ^ guard, 0x11);

Static-link guard-of-zero (CVE-2013-4788)

Tarihsel olarak pointer guard, statik olarak link'lenmiş executable'lar için randomize edilmiyordu — sıfır kalıyordu — bu yüzden mangling, saldırganın offline geri alabileceği saf bir rotate'a çöküyordu. Bu, kabaca glibc/eglibc 2.4–2.17'yi etkiledi. Dinamik olarak link'lenmiş binary'ler etkilenmedi. Hedefte guard'ın gerçekten rastgele olduğunu daima doğrulayın.

Detection

Mangling runtime'da şeffaftır; savunma amaçlı "tespit edilecek" bir şey yoktur. Exploit analizi için, makul herhangi bir code adresine eşit olmayan ama ror(x,0x11) XOR guard'ı gerçek bir fonksiyona düşen saklanmış bir function pointer, bir mangle'lanmış pointer'ın parmak izidir.

Mitigation

(Artık risk / bypass.) Mangling, bir integrity kontrolü değil, bir secret'a key'lenmiş bir obfuscation'dır: hiçbir authentication tag eklemez. Guard'ın veya plaintext'i bilinen bir mangle'lanmış pointer'ın herhangi bir pointer/info leak'i onu tamamen yener (yukarıdaki cebir). Aynı structure'ların data-only suistimaline karşı da hiçbir şey yapmaz — örn. __exit_funcs'ın count veya type alanlarını bozmak ya da bir mangle'lanmış entry yerine list pointer'ını hijack etmek. run-exit-handlers-abuse ve tls-dtor-list-hijack'a bakın. ARM Pointer Authentication gibi hardware pointer-integrity şemaları, keyed-XOR'u, bir hedef leak'inden sonra bile value forgery'ye direnen kriptografik bir MAC ile değiştirir.

References