Umpf spialaspia@inventati.org v0.01, 08/05/2002 Abstract Cifrare files in maniera trasparente senza patchare il kernel, senza privilegi particolari. Table of Contents 1 Panoramica ed utilizzo 2 Una sessione di esempio 1 Panoramica ed utilizzo L'idea e' ingegnosa si tratta di intercettare le chiamate alle syscall read e write attraverso una shared library e quindi determinare se il files e' stato cifrato oppure no, nel primo caso decifrarlo o cifrarlo, nel secondo semplicemente leggere o scrivere come farebbe la normale read o write di sistema. Riprendendo i concetti uno ad uno: una syscall puo' essere immaginata come l'interfaccia tra l'applicazione ed il sistema operativo. Per esempio ogni operazione di lettura, scrittura di un file in ultima istanza esegue rispettivamente le funzioni read o write. Una libreria condivisa si compone di una serie di funzioni generali che possono cosi' venire richiamate da programmi diversi. Ora se in una libreria condivisa venissero riscritte le due funzioni sopra citate, e questa libreria si trovasse in condizione di essere eseguita prima di tutte le altre, si otterrebbe di intercettare le chiamate read e write, ed eseguire il proprio codice. Attraverso la variabile d'ambiete LD_PRELOAD e' possibile indicare una serie di librerie condivise da caricare al volo. In pratica nella propria home directory, nel file .bash_profile, o in un file chiamato all'avvio di ogni shell a vostro piacimento, dovranno essere inserite queste 2 righe LD_PRELOAD=$LDPRELOAD:~/bin/umpf.so export LD_PRELOAD umpf.so: e' la libreria condivisa che contiene la ridefinizione della read e della write. Dunque ogni tentativo di leggere o scrivere su di un file finira' per determinare una chiamata alle funzioni della libreria umpf.so. Quest'ultime eseguono il seguente algoritmo cosi' come viene descritto dall'autore del codice, vecna, e presentato nel README.it fornito con il programma: READ(file, dato, lunghezza) { se il file e` un file ti tipo umpf { leggi, decritta, ritorna il buffer decrittato } altrimenti { leggi e torna come sempre } } WRITE(file, dato, lunghezza) { se il file e` di tipo umpf { critta, scrivi, ritorna il numero di byte scritti come normale da write } altrimenti { scrivi come sempre visto che non c'e` da crittare, e torna } } In concreto una volta procuratisi i sorgenti del programma (http://www.s0ftpj.org/tools/umpf.tar.gz) sara' sufficiente seguire le semplici istruzioni per la compilazione e l'installazione per trovare gia' tutto il meccanismo predisposto nella propria home directory. Nella propria home verra' infatti creata una directory bin, nella quale saranno riposti: la libreria condivisa, umpf.so, i programmi keyd e umpf. keyd dovra' essere avviato prima di poter cifrare o decifrare qualsiasi file, datosi che si occupa di richiedere una password e mantenerla in memoria, con essa verra' attivato l'algortimo crittografico utilizzato, una modifica di RC5. Per cifrare uno o piu' file sara' necessario lanciare il programma umpf con parametro il nome del/i file/s. umpf setta un particolare bit dei permessi del file in questione, lo sticky bit. Ad un ls -la un file cifrato si presenta dunque cosi' -rw------T 1 ginox users 10 Jul 28 20:10 test Questo bit permette di riconoscere i files cifrati con umpf dagli altri e di comportarsi di consegenza come da algoritmo illustrato. 2 Una sessione di esempio Viene riportato qui di seguito una semplice sessione di esempio Avviato il demone keyd vi verra' richiesta una password ginox@girinox:~$ keyd insert umpf key: retype umpf key: ginox@girinox:~$ echo "prova" > umpf_prova ginox@girinox:~$ umpf umpf_prova ginox@girinox:~$ ls -la -rw------T 1 ginox users 6 Jul 28 20:14 umpf_prova Il file e' accessibile ginox@girinox:~$ cat umpf_prova prova Verra' ucciso il demone keyd, che mantiene in memoria la chiave, rilanciato. Questa volta pero' verra' inserita la chiave sbagliata ginox@girinox:~$ killall keyd ginox@girinox:~$ keyd insert umpf key: retype umpf key: il risultato non puo' essere riprodotto qui di seguito poiche' non tutti i caratteri sono stampabili, data l'errata decifratura causata dall'inserimento di una chiave sbagliata.