Protezioni di Libc
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Applicazione dell’allineamento dei chunk
Malloc alloca memoria in gruppi da 8 byte (32-bit) o 16 byte (64-bit). Questo significa che la fine dei chunk nei sistemi a 32-bit dovrebbe allinearsi su 0x8, e nei sistemi a 64-bit su 0x0. La funzionalità di sicurezza verifica che ogni chunk sia correttamente allineato in queste posizioni specifiche prima di usare un puntatore da un bin.
Benefici di sicurezza
L’applicazione dell’allineamento dei chunk nei sistemi a 64-bit aumenta significativamente la sicurezza di Malloc limitando il posizionamento di fake chunks a solo 1 indirizzo ogni 16. Ciò complica gli sforzi di exploitation, specialmente in scenari in cui l’utente ha controllo limitato sui valori di input, rendendo gli attacchi più complessi e difficili da eseguire con successo.
- Fastbin Attack on
__malloc_hook
Le nuove regole di allineamento in Malloc ostacolano anche un attacco classico che coinvolge __malloc_hook. In precedenza, gli attacker potevano manipolare le dimensioni dei chunk per sovrascrivere questo puntatore a funzione e ottenere esecuzione di codice. Ora, il rigido requisito di allineamento fa sì che tali manipolazioni non siano più praticabili, chiudendo una via di sfruttamento comune e migliorando la sicurezza complessiva.
Nota: 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 onsetcontext,_IO_list_allprimitives, etc.
Pointer Mangling on fastbins and tcache
Pointer Mangling è un miglioramento della sicurezza usato per proteggere i puntatori Fd di fastbin e tcache nelle operazioni di gestione della memoria. Questa tecnica aiuta a prevenire alcuni tipi di tattiche di exploitation della memoria, specificamente quelle che non richiedono informazioni leaked o che manipolano posizioni di memoria direttamente in modo relativo rispetto a posizioni note (relative overwrites).
Il nucleo di questa tecnica è una formula di offuscamento:
New_Ptr = (L >> 12) XOR P
- L è la Storage Location del puntatore.
- P è il reale fastbin/tcache Fd Pointer.
La ragione per lo shift bitwise della storage location (L) di 12 bit verso destra prima dell’operazione XOR è critica. Questa manipolazione affronta una vulnerabilità insita nella natura deterministica dei 12 bit meno significativi degli indirizzi di memoria, che sono tipicamente prevedibili a causa dei vincoli dell’architettura di sistema. Spostando questi bit fuori dall’equazione, la porzione prevedibile viene rimossa, aumentando la casualità del nuovo puntatore offuscato e proteggendo così dagli exploit che fanno affidamento sulla prevedibilità di questi bit.
Questo puntatore offuscato sfrutta la casualità già fornita da ASLR, che randomizza gli indirizzi usati dai programmi per rendere difficile predire il layout di memoria di un processo.
Il processo di demangling per recuperare l’indirizzo originale utilizza la stessa operazione XOR. Qui, il puntatore mangled è trattato come P nella formula, e quando viene XORato con la storage location (L) invariata, risulta nell’indirizzo originale. Questa simmetria tra mangling e demangling garantisce che il sistema possa codificare e decodificare i puntatori in modo efficiente senza overhead significativo, aumentando notevolmente la sicurezza contro attacchi che manipolano puntatori di memoria.
Benefici di sicurezza
Pointer mangling mira a prevenire sovrascritture parziali e totali di puntatori nell’heap, rappresentando un miglioramento significativo della sicurezza. Questa caratteristica impatta le tecniche di exploitation in diversi modi:
- Prevenzione di Bye Byte Relative Overwrites: In precedenza, gli attacker potevano modificare parte di un puntatore per reindirizzare chunk dell’heap a differenti posizioni senza conoscere indirizzi esatti, una tecnica evidente nell’exploit leakless House of Roman. Con pointer mangling, tali relative overwrites senza un heap leak ora richiedono brute forcing, riducendo drasticamente la probabilità di successo.
- Maggiore difficoltà negli attacchi su tcache bin/fastbin: Attacchi comuni che sovrascrivono puntatori a funzione (come
__malloc_hook) manipolando voci di fastbin o tcache sono ostacolati. Per esempio, un attacco potrebbe implicare il leaking di un indirizzo LibC, il free di un chunk nel tcache bin, e poi la sovrascrittura del puntatore Fd per reindirizzarlo a__malloc_hookper ottenere esecuzione di codice arbitraria. Con pointer mangling, questi puntatori devono essere correttamente mangled, richiedendo un heap leak per una manipolazione accurata, elevando così la barriera di exploitation. - Richiesta di heap leak anche per posizioni non-heap: Creare un fake chunk in aree non-heap (come lo stack, la sezione .bss, o PLT/GOT) ora richiede anch’esso un heap leak a causa della necessità del pointer mangling. Ciò estende la complessità dello sfruttamento di queste aree, similmente al requisito per manipolare indirizzi LibC.
- Diventa più difficile leakare indirizzi heap: Pointer mangling limita l’utilità dei puntatori Fd nei bin fastbin e tcache come fonte per leak di indirizzi heap. Tuttavia, i puntatori in unsorted, small, e large bins rimangono non mangled e quindi ancora sfruttabili per leak. Questo sposta gli attacker a esplorare questi bin per informazioni sfruttabili, sebbene alcune tecniche possano ancora permettere di demangleare i puntatori prima di un leak, seppur con vincoli.
Safe-Linking Bypass (page-aligned leak scenario)
Anche con safe-linking abilitato (glibc ≥ 2.32), se si può leakare il puntatore mangled e sia il chunk corrotto che il chunk vittima condividono la stessa pagina da 4KB, il puntatore originale può essere recuperato usando solo l’offset di pagina:
// 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
Questo ripristina il Fd e permette il classico tcache/fastbin poisoning. Se i chunks si trovano su pagine diverse, il brute-forcing dell’offset di pagina a 12 bit (0x1000 possibilità) è spesso fattibile quando i pattern di allocazione sono deterministici o quando i crash sono accettabili (es., CTF-style exploits).
Demangling dei puntatori con un Heap Leak
Caution
For a better explanation of the process check the original post from here.
Panoramica dell’algoritmo
La formula usata per mangling e demangling dei puntatori è:
New_Ptr = (L >> 12) XOR P
Dove L è la posizione di memorizzazione e P è il puntatore Fd. Quando L viene shiftato a destra di 12 bit, espone i bit più significativi di P, a causa della natura dell’XOR, che restituisce 0 quando bit uguali vengono XORati tra loro.
Passaggi chiave nell’algoritmo:
- Initial Leak of the Most Significant Bits: XORando il valore shiftato di L con P, si ottengono effettivamente i top 12 bit di P perché la parte shiftata di L sarà zero, lasciando i bit corrispondenti di P invariati.
- Recovery of Pointer Bits: Poiché l’XOR è reversibile, conoscendo il risultato e uno degli operandi è possibile ricavare l’altro. Questa proprietà viene usata per dedurre l’insieme completo dei bit di P successivamente XORando insiemi di bit noti con porzioni del puntatore mangled.
- Iterative Demangling: Il processo viene ripetuto, ogni volta usando i bit di P appena scoperti dal passo precedente per decodificare il segmento successivo del puntatore mangled, fino al recupero di tutti i bit.
- Handling Deterministic Bits: Gli ultimi 12 bit di L vengono persi a causa dello shift, ma sono deterministici e possono essere ricostruiti post-processo.
Puoi trovare un’implementazione di questo algoritmo qui: https://github.com/mdulin2/mangle
Pointer Guard
Pointer Guard è una tecnica di mitigazione degli exploit usata in glibc per proteggere i function pointers memorizzati, in particolare quelli registrati da chiamate di libreria come atexit(). Questa protezione coinvolge lo scrambling dei puntatori XORandoli con un segreto memorizzato nei dati del thread (fs:0x30) e applicando una rotazione di bit. Questo meccanismo mira a impedire agli attaccanti di dirottare il controllo del flusso sovrascrivendo function pointers.
Bypassare Pointer Guard con un leak
- Understanding Pointer Guard Operations: Lo scrambling (mangling) dei puntatori è effettuato usando la macro
PTR_MANGLEche XORa il puntatore con un segreto a 64 bit e poi esegue una left rotation di 0x11 bit. L’operazione inversa per recuperare il puntatore originale è gestita daPTR_DEMANGLE. - Attack Strategy: L’attacco si basa su un approccio known-plaintext, dove l’attaccante deve conoscere sia la versione originale sia quella mangled di un puntatore per dedurre il segreto usato per il mangling.
- Exploiting Known Plaintexts:
- Identifying Fixed Function Pointers: Esaminando il codice sorgente di glibc o le tabelle di function pointer inizializzate (come
__libc_pthread_functions), un attaccante può trovare function pointers prevedibili. - Computing the Secret: Usando un function pointer noto come
__pthread_attr_destroye la sua versione mangled dalla tabella dei function pointer, il segreto può essere calcolato reverse-rotando (right rotation) il puntatore mangled e poi XORandolo con l’indirizzo della funzione.
- Alternative Plaintexts: L’attaccante può anche sperimentare munging di puntatori con valori noti come 0 o -1 per vedere se questi producono pattern riconoscibili in memoria, rivelando potenzialmente il segreto quando tali pattern vengono trovati in dump di memoria.
- Practical Application: Dopo aver calcolato il segreto, un attaccante può manipolare i puntatori in modo controllato, bypassando essenzialmente la protezione Pointer Guard in un’applicazione multithread se conosce la base di libc e ha la capacità di leggere posizioni di memoria arbitrarie.
GLIBC Tunables & Recent Loader Bugs
Il loader dinamico parsea GLIBC_TUNABLES prima dell’avvio del programma. Bug di mis-parsing qui influenzano direttamente libc prima che la maggior parte delle mitigazioni entri in gioco. Il bug “Looney Tunables” del 2023 (CVE-2023-4911) è un esempio: un valore GLIBC_TUNABLES troppo lungo overflowa buffer interni in ld.so, abilitando l’escalation di privilegi su molte distro quando combinato con binari SUID. L’exploitazione richiede solo la costruzione dell’ambiente e l’invocazione ripetuta del binario target; pointer guard o safe-linking non lo prevengono perché la corruzione avviene nel loader prima della configurazione dell’heap.
References
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.


