Visualizzazione post con etichetta openbsd. Mostra tutti i post
Visualizzazione post con etichetta openbsd. Mostra tutti i post

martedì 17 marzo 2015

Respect the developers time and wills!

I believe there is a strong understimation of Open Source work today: people complains more and more everyday without taking into account that who does Open Source is donating her time and efforts to the whole community.
Having stated that, it is really simple, in my very own opinion, that developers have the rights to work on what make them happy, not on what will make the users' happy.
Most of the time, the two side of happiness coincide.
In this scenario, before expressing rage against a group of developers without providing help, it is better to remember that you, the final user, did not hire the developers themselves, and therefore they are free to ignore you.
For a pratical example, see here  and if you have a little respect for yourself, never reply like this!

mercoledì 22 maggio 2013

Quando il codice è veramente "pulito"

OpenBSD e' uno dei progetti per me piu' interessanti nel panorama Open Source: in particolare e' noto per la sicurezza intrinseca del codice (e di conseguenza del sistema operativo stesso). Lo sforzo degli sviluppatori di OpenBSD e' quello di fornire una base di codice particolarmente robusta e priva di errori banali di programmazione. Qualche giorno fa guardavo la lista delle patch per la versione 5.3 rilasciata lo scorso primo Maggio 2013. Ebbene la lista prevede solo 4 vulnerabilita' conosciute, e le patch per risolvere le problematiche sono veramente cortissime, fino anche ad una singola linea di codice.





La brevita' delle patch e' secondo me un fatto impressionante che testimonia l'alta qualita' del codice stesso, che pur non essendo immune da errori (quale codice lo e') e' cosi' robusto da permettere con piccole e semplici modifiche la correzione di errori molto specifici.

mercoledì 30 marzo 2011

La sicurezza è paranoia (?)

Premetto che non sono un esperto di sicurezza informatica, pur tentando di tenermi aggiornato sull'argomento. Qualche giorno fa ho partecipato ad un interessante corso sulla sicurezza informatica dove, fra le altre cose, si e' parlato di buffer overflow. Il buffer overflow e' una tecnica vecchia ma ancora molto in voga di compromissione: in breve si tratta di iniettare nello stack di una applicazione una quantita' di dati opportuna in modo da sovrascrivere l'indirizzo di ritorno dello stack per farlo puntare a del codice malevolo. E qui le opinioni si dividono: di chi e' colpa per questo atteggiamento? Sicuramente del programmatore che ha lasciato una potenziale falla nello stack (mancanza di controllo sul limite dei dati) ma, secondo me, anche e soprattuto del sistema operativo.
Con questo post intendo spiegare le mie ragioni dietro a tale affermazione e vedere a grandi linee come ci si potrebbe difendere.

LA COLPA E' DEL SISTEMA OPERATIVO
Si e' detto che affinche' il buffer overflow di tipo stack funzioni e' necessario "iniettare" codice malevolo nello stack (o comunque nell'area dati - qui si pensi solo allo stack) e far saltare il controllo a tale codice (ossia modificare il registro IP). Cio' significa che il processore salta ed esegue codice in un'area di memoria scrivibile. Si presti attenzione: il processore manda in esecuzione dati da una zona di memoria scrivibile, che quindi potrebbe essere modificata in ogni momento. Sarebbe come dire che un demone di sistema abbia i permessi wx sulla sua immagine su disco stessa, e quindi che possa essere sostituito da qualunque programma si voglia. Apriti cielo! Il ritorno dei programmi automodificanti banditi fin dagli anni 50!
Come ci si potrebbe difendere? Beh, il canary e' una buona tecnica, anzi la migliore probabilmente: si inserisce un valore random nello stack che deve essere controllato al ritorno. Se il processore non trova tale valore corretto allora l'esecuzione e' abortita. Ma chi introduce il canarino? Anche qui ulteriore diatriba al corso: non e' il sistema operativo, e' il compilatore. O meglio, il compilatore inserisce nel prologo e nell'epilogo del metodo istruzioni per il controllo del canarino. Ora, se vogliamo dare ragione al docente del corso, il canarino viene controllato dal sistema operativo che esegue il programma...ma comunque senza la modifica al codice prodotto in fase di compilazione (Propolice) cio' non sarebbe possibile.

W^X
W^X e' un sistema concettualmente molto semplice, quasi disarmante nella sua semplicita', ad opera del team di OpenBSD incluso nella release 3.3 (si, la 3.3). L'idea e' quella di avere le pagine di memoria scrivibili private in toto del flag di esecuzione e viceversa: non e' quindi possibile eseguire lo stack poiche' lo stack e' scrivibile. Se l'architettura hardware supporta il flag NX (Not eXecutable) allora il trucco funziona direttamente: lo stack viene marcato come non eseguibile e quindi il buffer overlow e' evitato. Purtroppo non tutte le architetture supportano in hardware tale tecnica. Ma anche sulle architetture che supportano nativamente il flag la cosa si complica: lo stack utente ha tipicamente in cima un trampolino, denominato sigtramp, che serve come punto di lancio per l'intercettazione dei segnali unix. Tale zona puo' essere in sola lettura (il trampolino non cambia una volta che lo stack di chiamata si attiva) e quindi occorre muovere tale trampolino in una posizione non scrivibile, in modo da pulire lo stack. Inoltre c'e' il problema delle librerie condivise, che ad esempio nel loro spazio dati contengono i cosiddetti ctors e dtors, ossia i costruttori e distruttori c++. Quindi anche le librerie condivise hanno uno spazio dati che oltre ad essere scrivibile e' anche eseguibile. Perfino il GOT (Global Offset Table) e il PLT (Procedure Linkage Table) risultano scrivibili, permettendo quindi la modifica degli indirizzi di ritorno. W^X rende il GOT solo leggibile e il PLT (che deve essere eseguibile) non scrivibile, mettendo un po' di ordine nel caos delle librerie condivise. Analogamente i ctors e dtors vengono resi non scrivibili, garantendo anche in questo caso che salti di codice anomalo non siano possibili.
Nelle architetture che supportano il flag NX a livello di pagina il riordinamento di cui sopra e' sufficiente a garantire la protezione richiesta, nelle altre architetture occorre operare un ulteriore trucco. In sostanza si divide la memoria in due regioni (una scrivibile e una eseguibile) inserendo una linea di separazione virtuale. Compilatore e linker devono lavorare per spezzare i vari blocchi del programma e ordinarli in memoria al fine di inserire ogni pezzo nella giusta area di memoria.

RANDOMIZZAZIONE DEGLI INDIRIZZI
La randomizzazione degli indirizzi e' un'altra tecnica, meno efficace di W^X (secondo me), di protezione contro i buffer overflow. L'idea e' quella di inserire in ogni stack un gap random, cosi' da modificare l'effettivo inizio dei dati sullo stack. In questo modo diventa molto piu' complesso individuare dove il codice malevole e' stato piazzato, poiche' ad ogni esecuzione la sua locazione varia e quindi l'attacco ha meno possibilita' di riuscita. Secondo Theo de Raadt questa randomizzazione richiede 3 linee di codice di modifica nel kernel, e quindi non si vede come mai ancora molti vendor commerciali non l'abbiano inclusa.
La randomizzazione puo' essere anche rivolta alla allocazione della memoria: mmap e malloc solitamente funzionano con allocazioni contigue e quindi prevedibili. E' possibile randomizzare lo spazio di indirizzamento in modo che le aree di memoria siano addirittura intervallate fra loro e quindi che non sia possibile saltare da un'area all'altra.


Per maggiori informazioni consiglio di dare un'occhiata qui.