Libc Protections
Last updated
Last updated
Impara e pratica Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Malloc alloca memoria in raggruppamenti di 8 byte (32-bit) o 16 byte (64-bit). Ciò significa che la fine dei chunk nei sistemi a 32 bit dovrebbe allinearsi con 0x8, e nei sistemi a 64 bit con 0x0. La funzionalità di sicurezza verifica che ogni chunk sia allineato correttamente in queste posizioni specifiche prima di utilizzare un puntatore da un bin.
L'applicazione dell'allineamento dei chunk nei sistemi a 64 bit migliora significativamente la sicurezza di Malloc limitando il posizionamento di chunk falsi a solo 1 su ogni 16 indirizzi. Questo complica gli sforzi di sfruttamento, specialmente in scenari in cui l'utente ha un controllo limitato sui valori di input, rendendo gli attacchi più complessi e difficili da eseguire con successo.
Attacco Fastbin su __malloc_hook
Le nuove regole di allineamento in Malloc ostacolano anche un attacco classico che coinvolge il __malloc_hook
. In precedenza, gli attaccanti potevano manipolare le dimensioni dei chunk per sovrascrivere questo puntatore di funzione e ottenere esecuzione di codice. Ora, il rigoroso requisito di allineamento assicura che tali manipolazioni non siano più praticabili, chiudendo una comune via di sfruttamento e migliorando la sicurezza complessiva.
Offuscamento dei Puntatori è un miglioramento della sicurezza utilizzato per proteggere i puntatori Fd di fastbin e tcache nelle operazioni di gestione della memoria. Questa tecnica aiuta a prevenire determinati tipi di tattiche di sfruttamento della memoria, specificamente quelle che non richiedono informazioni di memoria trapelate o che manipolano direttamente le posizioni di memoria relative a posizioni note (sovrascritture relative).
Il nucleo di questa tecnica è una formula di offuscamento:
New_Ptr = (L >> 12) XOR P
L è la Posizione di Memorizzazione del puntatore.
P è il reale Puntatore Fd di fastbin/tcache.
Il motivo per cui lo spostamento bit a bit della posizione di memorizzazione (L) di 12 bit a destra prima dell'operazione XOR è critico. Questa manipolazione affronta una vulnerabilità intrinseca nella natura deterministica dei 12 bit meno significativi degli indirizzi di memoria, che sono tipicamente prevedibili a causa delle limitazioni dell'architettura di sistema. Spostando i bit, la porzione prevedibile viene rimossa dall'equazione, aumentando la casualità del nuovo puntatore offuscato e quindi proteggendo contro gli exploit che si basano sulla prevedibilità di questi bit.
Questo puntatore offuscato sfrutta la casualità esistente fornita dalla Randomizzazione del Layout dello Spazio degli Indirizzi (ASLR), che randomizza gli indirizzi utilizzati dai programmi per rendere difficile per gli attaccanti prevedere il layout di memoria di un processo.
Demangling del puntatore per recuperare l'indirizzo originale comporta l'uso della stessa operazione XOR. Qui, il puntatore offuscato è trattato come P nella formula, e quando viene XORato con la posizione di memorizzazione invariata (L), si rivela il puntatore originale. Questa simmetria nell'offuscamento e nel demangling assicura che il sistema possa codificare e decodificare i puntatori in modo efficiente senza un sovraccarico significativo, aumentando sostanzialmente la sicurezza contro gli attacchi che manipolano i puntatori di memoria.
L'offuscamento dei puntatori mira a prevenire sovrascritture parziali e complete dei puntatori nella heap, un significativo miglioramento della sicurezza. Questa funzionalità impatta le tecniche di sfruttamento in diversi modi:
Prevenzione delle Sovrascritture Relative Byte per Byte: In precedenza, gli attaccanti potevano cambiare parte di un puntatore per reindirizzare i chunk della heap a diverse posizioni senza conoscere indirizzi esatti, una tecnica evidente nell'exploit senza leak House of Roman. Con l'offuscamento dei puntatori, tali sovrascritture relative senza un leak della heap ora richiedono brute forcing, riducendo drasticamente la loro probabilità di successo.
Aumento della Difficoltà degli Attacchi Tcache Bin/Fastbin: Gli attacchi comuni che sovrascrivono puntatori di funzione (come __malloc_hook
) manipolando le voci di fastbin o tcache sono ostacolati. Ad esempio, un attacco potrebbe comportare il leak di un indirizzo LibC, liberando un chunk nel bin tcache, e poi sovrascrivendo il puntatore Fd per reindirizzarlo a __malloc_hook
per l'esecuzione di codice arbitrario. Con l'offuscamento dei puntatori, questi puntatori devono essere correttamente offuscati, richiedendo un leak della heap per una manipolazione accurata, elevando così la barriera di sfruttamento.
Requisito di Leak della Heap in Posizioni Non Heap: Creare un chunk falso in aree non heap (come lo stack, la sezione .bss, o PLT/GOT) ora richiede anche un leak della heap a causa della necessità di offuscamento dei puntatori. Questo estende la complessità di sfruttare queste aree, simile al requisito di manipolare indirizzi LibC.
Il Leak degli Indirizzi della Heap Diventa Più Difficile: L'offuscamento dei puntatori limita l'utilità dei puntatori Fd nei fastbin e tcache come fonti per leak di indirizzi della heap. Tuttavia, i puntatori in bin non ordinati, piccoli e grandi rimangono non offuscati, quindi ancora utilizzabili per leak di indirizzi. Questo cambiamento spinge gli attaccanti a esplorare questi bin per informazioni sfruttabili, sebbene alcune tecniche possano ancora consentire il demangling dei puntatori prima di un leak, sebbene con vincoli.
Per una spiegazione migliore del processo controlla il post originale da qui.
La formula utilizzata per offuscare e demanglare i puntatori è:
New_Ptr = (L >> 12) XOR P
Dove L è la posizione di memorizzazione e P è il puntatore Fd. Quando L viene spostato a destra di 12 bit, espone i bit più significativi di P, a causa della natura dell'XOR, che restituisce 0 quando i bit sono XORati con se stessi.
Passaggi Chiave nell'Algoritmo:
Leak Iniziale dei Bit Più Significativi: XORando il L spostato con P, si ottiene efficacemente i 12 bit superiori di P perché la porzione spostata di L sarà zero, lasciando i bit corrispondenti di P invariati.
Recupero dei Bit del Puntatore: Poiché l'XOR è reversibile, conoscere il risultato e uno degli operandi consente di calcolare l'altro operando. Questa proprietà viene utilizzata per dedurre l'intero insieme di bit per P XORando successivamente insiemi noti di bit con parti del puntatore offuscato.
Demangling Iterativo: Il processo viene ripetuto, ogni volta utilizzando i nuovi bit scoperti di P dal passaggio precedente per decodificare il segmento successivo del puntatore offuscato, fino a quando tutti i bit non sono recuperati.
Gestione dei Bit Deterministici: Gli ultimi 12 bit di L vengono persi a causa dello spostamento, ma sono deterministici e possono essere ricostruiti dopo il processo.
Puoi trovare un'implementazione di questo algoritmo qui: https://github.com/mdulin2/mangle
La protezione dei puntatori è una tecnica di mitigazione degli exploit utilizzata in glibc per proteggere i puntatori di funzione memorizzati, in particolare quelli registrati da chiamate di libreria come atexit()
. Questa protezione comporta la scrambatura dei puntatori XORandoli con un segreto memorizzato nei dati del thread (fs:0x30
) e applicando una rotazione bit a bit. Questo meccanismo mira a prevenire che gli attaccanti dirottino il flusso di controllo sovrascrivendo i puntatori di funzione.
Comprendere le Operazioni della Protezione dei Puntatori: La scrambatura (offuscamento) dei puntatori viene effettuata utilizzando il macro PTR_MANGLE
che XORa il puntatore con un segreto a 64 bit e poi esegue una rotazione a sinistra di 0x11 bit. L'operazione inversa per recuperare il puntatore originale è gestita da PTR_DEMANGLE
.
Strategia di Attacco: L'attacco si basa su un approccio a testo in chiaro noto, in cui l'attaccante deve conoscere sia la versione originale che quella offuscata di un puntatore per dedurre il segreto utilizzato per l'offuscamento.
Sfruttare i Testi in Chiaro Noti:
Identificazione dei Puntatori di Funzione Fissi: Esaminando il codice sorgente di glibc o le tabelle di puntatori di funzione inizializzati (come __libc_pthread_functions
), un attaccante può trovare puntatori di funzione prevedibili.
Calcolo del Segreto: Utilizzando un puntatore di funzione noto come __pthread_attr_destroy
e la sua versione offuscata dalla tabella dei puntatori di funzione, il segreto può essere calcolato ruotando all'indietro (rotazione a destra) il puntatore offuscato e poi XORandolo con l'indirizzo della funzione.
Testi in Chiaro Alternativi: L'attaccante può anche sperimentare con l'offuscamento dei puntatori con valori noti come 0 o -1 per vedere se questi producono schemi identificabili in memoria, rivelando potenzialmente il segreto quando questi schemi vengono trovati nei dump di memoria.
Applicazione Pratica: Dopo aver calcolato il segreto, un attaccante può manipolare i puntatori in modo controllato, bypassando essenzialmente la protezione della Protezione dei Puntatori in un'applicazione multithreaded con conoscenza dell'indirizzo base di libc e la capacità di leggere posizioni di memoria arbitrarie.
Impara e pratica Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)