In primo luogo, un piccolo chiarimento: gli spray heap classici non sono mai necessari per riempire comunque l'intero indirizzo virtuale. Hanno solo bisogno di riempire abbastanza memoria per coprire l'intervallo di incertezza che si ha per l'indirizzo di se lo shellcode sarà. Quindi, 100 MB circa erano sufficienti.
L'immagine è cambiata molto con l'avvento di DEP, perché non si può più spruzzare shellcode; ora si deve spruzzare uno stack ROP (per esempio). Si potrebbe pensare che ASLR abbia anche reso più difficile l'irrorazione dell'heap, ma VirtualAlloc
alloca a indirizzi deterministici anche se ASLR è abilitato (forse lo fa ancora), il che ha reso molto più facile predire l'indirizzo. Infine, lo spazio di indirizzamento a 64 bit ha aumentato la quantità di variabilità disponibile per ASLR, che ha il potenziale di effettuare alcuni attacchi di heap spray più difficile .
Il più grande cambiamento si trova in Windows 8, che ha fatto due importanti cambiamenti che potrebbero rendere gli spray heap più impegnativi. Innanzitutto, HiASLR consente una maggiore entropia per ASLR. Su piattaforme a 64 bit, HiASLR introduce una gamma di possibilità da 1 TB per la base dell'heap. Ciò lo rende più difficile per prevedere l'indirizzo di qualcosa sullo heap. In secondo luogo, Windows 8 rende allocazioni non deterministiche: quando si assegna un oggetto utilizzando l'allocatore predefinito, la posizione che viene utilizzata è casuale (non è più deterministica), introducendo la casualizzazione a grana fine a livello di singolo oggetto. La randomizzazione oggetto per oggetto non viene utilizzata per tutto (solo per l'allocatore LFH, che a mio avviso viene utilizzato solo per oggetti heap con una dimensione massima di 16 KB), ma aggiungerà una sfida aggiuntiva.
Detto questo, l'irrorazione dell'heap può essere ancora possibile in alcuni casi. La situazione in cui l'irrorazione dell'heap diventa utile è dove abbiamo una conoscenza parziale del valore di un puntatore (o dove alcuni oggetti saranno in memoria), ma non della conoscenza esatta. In tale situazione, un heap spray può ancora essere una tecnica utile per rendere l'exploit affidabile nonostante la mancanza di perfetta prevedibilità in quell'indirizzo.
Ad esempio, un esempio è L'exploit di Ivan Fratric di 64-bit IE11 , dove ha usato un heap spray per rendere l'exploit affidabile. In tale vulnerabilità, l'autore dell'attacco può attivare una scrittura per indirizzare A
+ 256 MB, dove A
è l'indirizzo di qualche oggetto heap. A causa di ASLR, non possiamo predire il valore di A
, e a causa dell'heap a 64-bit, non possiamo spruzzare abbastanza per riempire tutto l'heap - ma Ivan ha notato che in questo caso è sufficiente spruzza circa 256 MB di dati nell'heap. Ciò rende probabile che l'indirizzo di un oggetto heap casuale, più 256 MB, raggiungerà la regione spruzzata.
Quindi, come spiega Ivan Frartic, l'irrorazione dell'heap può ancora essere utile per l'aggressore se "possiamo creare una vulneroria di dereference di applicazioni vulnerabili a un indirizzo heap valido + un offset grande" (ad esempio, immagina il codice buggy do_something_with(a[i])
, dove i
potrebbe essere un offset che punta oltre la fine dell'array). Fornisce un altro esempio di una precedente vulnerabilità che aveva anche questo modulo, per illustrare che questo caso è abbastanza comune.
Infine, i processi a 32 bit potrebbero essere utilizzati nei casi che non ti aspetteresti. Ad esempio, anche IE a 64 bit su piattaforme a 64 bit utilizzerà processi figlio a 32 bit per ogni nuova scheda , in Windows 8.1. Chi lo sapeva?
Bottom line: No, non possiamo dire che non ci sia bisogno di preoccuparsi degli spray heap contro i processi a 64 bit. Era davvero troppo ingenuo.