Sconfiggi gli attacchi per l'iniezione di codice in x86

2

Nei sistemi x86, ci sono tre requisiti per un attacco di iniezione di codice che funzioni:

  1. scrive il carico utile di attacco in memoria
  2. il carico utile di attacco è eseguibile
  3. devia il controllo del flusso sul payload

Come possiamo impedire che 2) il carico utile di attacco sia eseguibile in modo da difendersi dagli attacchi di iniezione di codice?

    
posta George 07.10.2015 - 17:49
fonte

1 risposta

4

Rendere il payload iniettato "non eseguibile" è ciò che Prevenzione dell'esecuzione dei dati riguarda. Esistono varie tecniche per ottenere ciò, a seconda di cosa può fare l'hardware sottostante. Sulla maggior parte delle architetture, ciò avverrà tramite MMU : pagine che dovrebbero contenere "dati" (ad es. Lo stack) sono contrassegnati come non eseguibili.

La vecchia CPU x86 rende la DEP un po 'difficile perché la MMU originale della 80386 non distingue tra accessi "letti" ed "esegui"; quindi, non consente di contrassegnare la memoria come non eseguibile pur rimanendo leggibile. DEP può ancora essere fatto in una certa misura con l'aiuto di registri di segmenti , anche se con meno flessibilità (in pratica puoi fare tutto il resto stack non eseguibile, ma è difficile o impossibile riutilizzare i blocchi di memoria dinamicamente). Un altro metodo chiamato PaX consente di separare i diritti di accesso "read" ed "execute" su una base per pagina, ma ciò richiede un po 'di giocoleria con il TLB e ha un overhead di runtime (i fallimenti di TLB innescano le eccezioni della CPU). Vedi questa risposta per i dettagli.

Più recenti x86, e in particolare tutte le CPU x86 che possono essere eseguite in modalità 64 bit, hanno una MMU che sa in modo nativo come distinguere tra "leggi" ed "esegui" (questo è chiamato NX bit ) rendendo obsoleti questi giochi segmentari o PaX.

La cosiddetta " politica W ^ X " (leggi come "Writeable esclusivo o eseguibile") ) afferma che il sistema operativo non dovrebbe mai lasciare un pezzo di memoria sia scrivibile che eseguibile allo stesso tempo, quindi se il carico utile potrebbe essere iniettato (cioè scritto su un blocco di RAM), allora non può essere eseguito fino a quando alcuni cambiamenti espliciti dei diritti di accesso vengono eseguiti sulla pagina (e, presumibilmente, il codice di destinazione non ha motivo di effettuare tale modifica).

DEP non è una panacea; gli attaccanti hanno ora imparato a usare pezzi di codice esistenti, già nella RAM e contrassegnati come eseguibili, per fungere da payload. Cerca Programmazione orientata al ritorno per i dettagli.

Non consentire che il punto 3 sia un metodo più completo per prevenire attacchi riusciti; sfortunatamente, alcuni linguaggi di programmazione tradizionali diffusi (C e C ++, in particolare) sono poveri in questo compito. La deviazione del flusso di controllo avviene come conseguenza di un accesso di memoria non controllato (buffer overflow, use-after-free, double-free ...) che la lingua può accadere perché non controlla tali occorrenze. Lo sviluppatore dovrebbe aggiungere tutti i controlli necessari. Accade così che anche i migliori sviluppatori con le più approfondite pratiche di sviluppo continuino a non riuscire a farlo.

    
risposta data 07.10.2015 - 19:15
fonte

Leggi altre domande sui tag