La compilazione da fonti "kinda" protegge dagli attacchi di overflow del buffer?

17

Durante la discussione sui buffer overflow, qualcuno mi ha detto che compilare il proprio binario per un'applicazione (con specifici flag di compilazione) invece di usare il "mainstream binary" rende più difficile per un attacker sfruttare il buffer overflow.

Apparentemente perché "cambia l'allocazione della memoria" rispetto al binario mainstream.

posta Brian Clozel 18.07.2011 - 23:26
fonte

4 risposte

17

Poiché la domanda è riportata nel titolo, "Compilare dalle fonti .. proteggere dagli attacchi di overflow del buffer?", la risposta è in generale no .

Tuttavia, qui è un'ipotesi su ciò a cui il tuo amico potrebbe aver pensato: Le versioni correnti del compilatore GNU C (GCC) possono facoltativamente utilizzare GCC Stack-Smashing Protector quando invocato con i flag della riga di comando -fstack-protector . Ci sono molte altre tecniche che devono essere abilitate al momento della compilazione, vedi il link di Ubuntu sotto. Immagino che uno o più di questi sia ciò che intendeva il tuo amico, e ha ipotizzato che le versioni Linux / BSD non lo usino già.

Ma la compilazione di te stesso non è utile se la tua distribuzione Linux / BSD utilizza già queste tecniche. E molti di questi lo fanno oggigiorno, ecco una comoda panoramica di cosa Ubuntu fa nelle loro Server Edition (vedi titoli Stack e Heap Protector, Obfuscation del puntatore, 5x ASLR e 4x "Built ...").

Infine, non tutto il software funzionerà con queste tecniche. Se vuoi farlo tu stesso, rischi di passare un sacco di tempo a rintracciare bug sfuggenti. Il fornitore di distribuzione upstream si trova in una posizione migliore per applicare queste modifiche e fornire i binari risultanti con sufficiente verifica e garanzia della qualità per considerarli stabili.

Queste tecniche sono utili e aggiungono un livello significativo di difesa in profondità. Ma non compilare da te la fonte per questo. Scegli una distribuzione Linux / BSD che abbia una buona mentalità ingegneristica per la sicurezza e abbia già applicato meccanismi di protezione rilevanti (superficie di attacco minima, protezione da sovraccarico del buffer, forse SELinux / AppArmor) in base alle tue esigenze.

    
risposta data 19.07.2011 - 01:49
fonte
20

È in gran parte falso. Usando un compilatore di una versione diversa da quella usata per il binario "mainstream", o usandolo con diversi flag di compilazione, può risultare in alcune cose ordinate diversamente, ma è probabile che la maggior parte del codice gli elementi appariranno nello stesso ordine. Nella misura in cui cambia qualcosa per quanto riguarda il sovrasfruttamento del buffer, la ricompilazione delle cose può facilitare le cose per l'attaccante nello stesso modo in cui può rendere le cose più difficili.

La maggior parte delle operazioni di overflow del buffer consiste nel calpestare un indirizzo di codice (es. indirizzo di ritorno di una funzione, nello stack o un puntatore di funzione da qualche parte, in particolare in vtables per oggetti in C ++) in modo che l'attaccante costringa l'esecuzione ad andare dove lui desidera. Tradizionalmente, l'attaccante ha cercato di far saltare l'esecuzione ai dati con cui ha riempito il buffer, ma stack non eseguibili e più in generale il cosiddetto W ^ X impedisce che ciò avvenga: i dati non saranno interpretati come codice. Quindi l'attaccante ora punta alla libreria C (o ad una libreria di sistema simile, a seconda del sistema operativo), che contiene delle belle funzioni per eseguire altri file, ad es. una conchiglia. Ciò implica indovinare dove la suddetta bella funzione è in memoria. Bottom-line: se vuoi eseguire una ricompilazione su di esso, devi ricompilare la libreria C , non l'applicazione.

La randomizzazione del layout dello spazio degli indirizzi è solo un modo generico per rendere l'indirizzo di una funzione non percettibile. È molto più accurato che ricompilare (anche supponendo che la ricompilazione cambi davvero le cose intorno, cosa che non accade) perché la randomizzazione del layout dello spazio degli indirizzi è ancora randomizzata ad ogni esecuzione . In particolare, un utente malintenzionato non otterrà informazioni sull'indirizzo della funzione di destinazione ottenendo una copia del file eseguibile, poiché tale indirizzo non è stato ancora deciso.

Tuttavia, la randomizzazione del layout dello spazio degli indirizzi non è una pallottola d'argento poiché deve operare in condizioni severe: non può collocare la libreria da nessuna parte a causa dell'allineamento (in genere, l'indirizzo di caricamento deve essere un multiplo di 4 kB) e della frammentazione (a Lo spazio degli indirizzi di 2 GB - su un sistema a 32 bit - è troppo piccolo per consentire la diffusione di librerie ovunque: ciò impedirebbe artificialmente l'allocazione di grandi blocchi di memoria).

(Inoltre, un "proiettile d'argento" è un modo per uccidere i licantropi: è una "soluzione ideale" solo se la tua idea di medicina è sparare ai pazienti.)

Un buffer overflow è un bug. Se l'utente malintenzionato può fare in modo che l'applicazione sovrascriva parti dei suoi dati con byte scelti dall'attaccante, in modo silenzioso, non esiste un limite a priori sul danno che l'attaccante può fare. Questo è il motivo per cui sono stati inventati linguaggi come Java: almeno, con Java, su un buffer overflow, si ottiene un arresto immediato del thread, non un danneggiamento dei dati silenzioso.

    
risposta data 18.07.2011 - 23:59
fonte
8

[Does] compiling your own binary for an application (with specific compilation flags) instead of using the "mainstream binary" make it more difficult for an attacker to leverage buffer overflows?

Dipende dal sistema operativo, dalla lingua in cui è scritta l'applicazione e dal compilatore.

In primo luogo, il linguaggio di programmazione deve essere un linguaggio compilato: C, C ++, C #, Java, Objective-C, Delphi, ecc. I linguaggi interpretati (JavaScript, PHP, Ruby, ecc.) vengono eseguiti dal sorgente (non compilato) , quindi per modificare il comportamento della memoria è necessario modificare le impostazioni dell'interprete o la fonte. Ovviamente, nessuna compilazione, nessuna protezione.

Secondo il linguaggio di programmazione deve consentire la gestione manuale della memoria. Java e C # utilizzano la gestione automatica della memoria, evitando la vulnerabilità di base dell'overflow del buffer. C e C ++ consentono la gestione manuale della memoria dinamica. Se il linguaggio di programmazione ha gestito la memoria, la compilazione non sarà di aiuto.

In terzo luogo, il compilatore o le librerie utilizzate nell'applicazione devono supportare un controllo o un controllo esteso della gestione della memoria dinamica. I compilatori Microsoft C ++, Intel C ++, GNU C ++, LLVM Clang C ++ supportano tutti -fstack-protector, IBM XL C ++ supporta -qstackprotect. Alcune librerie come LibSafe di Avaya Labs hanno anche meccanismi per proteggere lo stack. Se il compilatore non supporta la protezione dello stack e non sono disponibili librerie di protezione dello stack, la compilazione non sarà di aiuto.

In quarto luogo, il sistema operativo potrebbe fornire una certa protezione. Alcuni sistemi operativi già proteggono lo stack da bit eseguibili, impilano i puntatori di base e salvano gli indirizzi di ritorno nei registri. Se il sistema operativo sta già proteggendo lo stack, la compilazione non sarà di aiuto.

Is it way less efficient than Address space layout randomization ?

La randomizzazione dello spazio degli indirizzi è una tecnica che impedisce a un utente malintenzionato di utilizzare un indirizzo ben noto per chiamare una funzione di sistema. Ad esempio, se setuid () è sempre all'indirizzo 0xDEADBEEF, l'utente malintenzionato può tentare di sovrascrivere un indirizzo di ritorno con 0xDEADBEEF ed eseguire setuid. La randomizzazione non impedisce il buffer overflow, ma impedisce solo l'uso di valori di indirizzo statici.

Is this point rendered moot by new memory management strategies in OS kernels?

Non necessariamente. Dipende dal sistema operativo. Alcuni sistemi operativi sono più focalizzati sulle prestazioni rispetto alla sicurezza. Questi sistemi operativi possono effettivamente introdurre più vulnerabilità con trucchi di gestione della memoria.

    
risposta data 19.07.2011 - 09:58
fonte
7

Di cosa sta parlando è probabilmente che in alcuni casi in cui il binario originale non è stato compilato con le protezioni disponibili, puoi ricompilarlo per abilitarle.

Al giorno d'oggi i compilatori e i sistemi operativi offrono molte protezioni avanzate di sicurezza, ma a volte spetta allo sviluppatore applicarli alla sua applicazione, e alcuni di essi vengono applicati al momento della compilazione e possono essere o meno "attivati" per impostazione predefinita .

Forse l'esempio più famoso è la protezione dagli overflow del buffer basati sullo stack. Questa protezione è puramente basata sul compilatore: al momento della compilazione, al programma vengono aggiunte istruzioni aggiuntive in modo da aggiungere e controllare i canarini nello stack, che attenua (il risultato) un certo tipo di overflow. Ma questa protezione viene aggiunta solo se, ad esempio in linux, si applica il flag -fstack-protector o in windows la famosa flag / GS. Nei recenti sistemi operativi e compilatori questi flag sono attivi per impostazione predefinita, ma non è sempre stato così.

Altre opzioni di questo tipo sono (per gcc) -D_FORTIFY_SOURCE = 2 che aggiunge alcuni controlli di integrità su determinate funzioni vulnerabili di glibc e protegge da altri buffer overflow e -Wl, -z, relro che contrassegnano determinate aree di memoria come di sola lettura.

Un'altra cosa che potrebbe aver voluto dire è che puoi includere altre librerie più sicure mentre compili, ad esempio libsafe, che sovrascrive certe funzioni note non sicure con versioni "più sicure" che hanno più controlli di integrità.

Inoltre, DEP e ASLR in Windows sono abilitati con / NXCOMPAT e / DYNAMICBASE. Ora penso che lo studio visivo abbia quelli abilitati di default, ma di nuovo non è stato il caso. Sareste sorpresi dal numero di applicazioni e DLL che ancora non hanno questi flag abilitati, anche forniti da aziende come Adobe e Microsoft. Caso in questione: Adobe Flash ha ottenuto solo quelle protezioni nella versione 10, non erano abilitate prima. È prassi comune per gli scrittori di exploit cacciare tali DLL durante il tentativo di trovare obiettivi utilizzabili (o modi per aumentare i privilegi, ecc.).

    
risposta data 19.07.2011 - 00:09
fonte

Leggi altre domande sui tag