Pointer mangling (glibc PTR_MANGLE)¶
glibc, hassas saklanmış function pointer'larını (longjmp hedefleri, atexit/exit handler'ları, TLS destructor'ları)
PTR_MANGLEile karıştırır — TCB'deki process başına rastgele birpointer_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¶
- m101 / binholic. Notes on abusing exit handlers, bypassing pointer mangling and glibc ptmalloc hooks. — https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html
- Marco-Gisbert, Ripoll. CVE-2013-4788: glibc PTR_MANGLE weakness in static binaries. — https://hmarco.org/bugs/CVE-2013-4788.html