Stack Overflow - Sconfitta Canarini, ASLR, DEP, NX

74

Per evitare overflow del buffer, sono disponibili diverse protezioni come l'utilizzo di valori Canary, ASLR, DEP, NX. Ma, dove c'è una volontà, c'è un modo. Sto studiando i vari metodi che un utente malintenzionato potrebbe ignorare questi schemi di protezione. Sembra che non ci sia un luogo in cui vengano fornite informazioni chiare. Questi sono alcuni dei miei pensieri.

Canary - Un utente malintenzionato potrebbe capire il valore delle canarie e usarlo nella sua iniezione buffer per ingannare lo stack guard dal rilevamento di un exploit

DEP, NX - Se ci sono chiamate a VirtualAlloc(), VirtualProtect() , l'utente malintenzionato potrebbe provare a reindirizzare il codice a queste funzioni e disabilitare DEP, NX nelle pagine in cui desidera inserire codice arbitrario.

ASLR - Nessun indizio. Come funzionano ASLR e DEP?

    
posta sudhacker 21.09.2012 - 15:09
fonte

3 risposte

85

Canarie
I canarini di pila funzionano modificando le regioni di prologo ed epilogo di ogni funzione per posizionare e controllare rispettivamente un valore nello stack. Pertanto, se un buffer di stack viene sovrascritto durante un'operazione di copia di memoria, l'errore viene rilevato prima restituiti dall'esecuzione dalla funzione di copia. Quando ciò accade, viene sollevata un'eccezione, che restituisce la gerarchia del gestore di eccezioni fino a quando non raggiunge il gestore di eccezioni predefinito del sistema operativo. Se è possibile sovrascrivere una struttura di gestore eccezioni esistente nello stack, è possibile farlo puntare al proprio codice. Questo è un exploit Structured Exception Handling (SEH) e consente di saltare completamente il canary check.

DEP / NX DEP e NX contrassegnano essenzialmente le strutture importanti in memoria come non eseguibili e impongono eccezioni a livello di hardware se si tenta di eseguire tali aree di memoria. Ciò rende normali i buffer overflow in cui si imposta eip in esp+offset e si esegue immediatamente lo shellcode impossibile, perché lo stack non è eseguibile. Bypassare DEP e NX richiede un trucco interessante chiamato Programmazione orientata al ritorno .

Il ROP consiste essenzialmente nel trovare frammenti di codice esistenti dal programma (chiamati gadget) e saltare su di essi, in modo da produrre il risultato desiderato. Poiché il codice fa parte della memoria eseguibile legittima, DEP e NX non hanno importanza. Questi gadget sono concatenati insieme allo stack, che contiene il tuo payload di exploit. Ogni voce nella pila corrisponde all'indirizzo del prossimo gadget ROP. Ogni gadget ha il formato di instr1; instr2; instr3; ... instrN; ret , quindi ret salterà al successivo indirizzo nello stack dopo aver eseguito le istruzioni, concatenando così i gadget. Spesso i valori aggiuntivi devono essere posizionati nello stack per completare correttamente una catena, a causa di istruzioni che altrimenti si intrometteranno.

Il trucco consiste nel concatenare questi ROP per chiamare una funzione di protezione della memoria come VirtualProtect , che viene quindi utilizzata per rendere eseguibile lo stack, in modo che il codice shell possa essere eseguito tramite un jmp esp o un gadget equivalente. Strumenti come mona.py possono essere utilizzati per generare queste catene di gadget ROP o trovare i gadget ROP in generale.

ASLR
Esistono alcuni modi per aggirare l'ASLR:

  • Sovrascrittura Direct RET - Spesso i processi con ASLR caricheranno ancora moduli non ASLR, consentendo di eseguire semplicemente lo shellcode tramite jmp esp .
  • Sovrascrittura EIP parziale - Solo sovrascrivere una parte di EIP o utilizzare una divulgazione affidabile delle informazioni nello stack per trovare ciò che dovrebbe essere il vero EIP, quindi utilizzarlo per calcolare il target. Tuttavia, abbiamo ancora bisogno di un modulo non ASLR per questo.
  • Spray NOP - Crea un grande blocco di NOP per aumentare la possibilità di atterrare in modo forzato sulla memoria legittima. Difficile, ma possibile anche quando tutti i moduli sono abilitati per ASLR. Non funzionerà se DEP è acceso però.
  • Bruteforce: se riesci a provare un exploit con una vulnerabilità che non blocca il programma, puoi rinforzare 256 diversi indirizzi di destinazione fino a quando non funziona.

Lettura consigliata:

risposta data 21.09.2012 - 17:06
fonte
25

Canarie e altre sostanze volatili non impedisce l'overflow ; cercano solo di far fronte alle conseguenze di un trabocco che è successo . Il canarino prova a rilevare il caso di un overflow che ha sovrascritto l'indirizzo di ritorno in uno stack frame. DEP è un passo avanti, presuppone che l'indirizzo di ritorno sia stato sovrascritto e seguito e limita le aree in cui l'esecuzione potrebbe saltare. ASLR è ancora un passo avanti: "mescola" le aree in cui l'esecuzione è consentita.

Storicamente, buffer overflow in cui vengono sfruttati per sovrascrivere l'indirizzo di ritorno nello stack, in modo da far saltare l'esecuzione nei dati stessi che sono stati utilizzati per sovrasfruttare il buffer. Il canarino prova a rilevarlo prima di saltare e DEP viene utilizzato per rendere lo spazio dello stack non eseguibile. DEP funziona anche in caso di overflow dei buffer nell'heap (il canary è di qualsiasi utilizzo solo per overflow del buffer dello stack, ma l'heap può contenere anche buffer e anche dati sensibili da sovrascrivere, come i puntatori alle funzioni, specialmente nel contesto di OOP lingue come C ++). Per aggirare DEP e il canarino, gli attaccanti hanno iniziato a cercare trabocchi che consentono di sovrascrivere i puntatori per funzionare, in modo da far saltare l'esecuzione in codice libreria standard che è necessariamente "lì" e anche necessariamente eseguibile . Ecco perché è stato inventato ASLR: rendere questi giochi più difficili. L'ASLR può ancora essere sconfitto con la sua fortuna: poiché ASLR deve mantenere l'allineamento delle pagine (4 kB su x86), all'interno di uno spazio di indirizzi non troppo grande (in genere meno di 2 GB su x86 a 32 bit), non ci sono molti posti dove può essere il codice target (al massimo mezzo milione). A seconda del contesto di attacco e della frequenza con cui lo script dell'attaccante può tentare, questo può essere troppo basso per comodità.

Il tema importante qui è che i canarini, DEP e ASLR non sconfiggono gli stessi overflow, ma mirano ai metodi di sfruttamento dell'overflow generici che sono stati tradizionalmente impiegati. In qualsiasi applicazione, un overflow che sovrascrive i dati non puntatore può essere letale come un exploit shell remoto (ad esempio, immaginare un overflow che modifica un campo stringa chiamato " authenticated_user_name "). La corsa alle armi tra attaccanti e difensori sta diventando troppo specializzata e, a mio avviso, manca sempre di più il punto. In generale, è molto meglio non consentire mai l'overflow, ovvero bloccare / uccidere il processo / thread prima di scrivere byte al di fuori del buffer di destinazione. Questo è quello che succede con quasi ogni linguaggio di programmazione decente (Java, C #, VB.NET, Python, Ruby, Node.js, OCaml, PHP ... la scelta è grande).

    
risposta data 21.09.2012 - 16:49
fonte
13

Il livello base di protezione è ASLR + DEP.

Se non li usi entrambi, allora ci sono molte tecniche potenti per sfruttare un sovraccarico del buffer (ad esempio, calcolo orientato al ritorno, irrorazione dell'heap, ripetizione delle ipotesi). Ad esempio, il DEP da solo può essere sconfitto usando il calcolo orientato al rendimento; e l'ASLR da solo può essere sconfitto usando l'irrorazione dell'heap e ripetuti tentativi.

Tuttavia, se l'obiettivo utilizza sia ASLR + DEP, lo sfruttamento diventa molto più difficile. Le tecniche sopra menzionate non sono sufficienti per sconfiggere ASLR + DEP. ASLR + DEP sono come un punzone uno-due che rendono la vita dell'attaccante molto più difficile. Sconfiggere la combinazione di ASLR + DEP non è impossibile, ma richiede molta più intelligenza.

Il mio esempio preferito di metodi per sconfiggere ASLR + DEP è spiegato nel mazzo di diapositive, Sfruttamento dell'interprete: inferenza del puntatore e irrorazione JIT . Lì, l'autore descrive come ha sfruttato un errore di sicurezza della memoria in Flash. Ha sfruttato le proprietà del Flash JIT per organizzare la memoria in un modo che gli consenta di montare un attacco di iniezione del codice, nonostante la presenza di ASLR + DEP. Ricorda che un JIT è un compilatore just-in-time; compila codice bytecode Flash in codice nativo. Il codice nativo verrà archiviato da qualche parte nella memoria e il JIT Flash lo contrassegnerà come eseguibile (nonostante DEP). L'autore ha trovato un modo per generare bytecode Flash che, una volta compilati, genererebbero una sequenza di byte che incorporava il suo shellcode dannoso (spostato di un byte). Ha quindi utilizzato tecniche di irrorazione dell'heap per assicurarsi che vi fossero molte copie di questo in memoria. Infine, ha sfruttato il bug di sicurezza della memoria per far passare il programma a un altro indirizzo; A causa di ASLR, era come saltare a un indirizzo casuale, ma le molte copie garantivano che con alta probabilità questo sarebbe saltato nel suo shellcode. In questo modo, ha bypassato sia ASLR e DEP - un'impresa nifty.

Un'ultima nota: vale la pena ricordare che ASLR è molto più efficace su architetture a 64 bit. Nelle architetture a 32 bit, l'ASLR può essere spesso sconfitto semplicemente facendo più tentativi. Non ci sono abbastanza gradi di libertà sulle piattaforme a 32 bit per introdurre abbastanza casualità, quindi le probabilità che l'hacker di avere successo con una buona fortuna rimangono troppo alte, su piattaforme a 32 bit. Per la difesa più strong, utilizza una piattaforma a 64 bit.

    
risposta data 23.09.2012 - 02:47
fonte

Leggi altre domande sui tag