La sicurezza locale e i privilegi dell'utente
Da Wikipedia, l'enciclopedia libera.
Una delle cose a cui gli sprovveduti non pensano e' che un utente smaliziato potrebbe riavviare la macchina, mettere dentro un live CD, farlo partire e compromettere la sicurezza del sistema senza troppa fatica. Analogamente non tutti sanno che editando opportunamente una delle righe del bootloader GRUB cambiando il valore di init a /bin/sh e' possibile ottenere una completa shell di root. Sul piano puramente teorico una buona configurazione di sicurezza realizzata esclusivamente a livello di permessi di files e cartelle dovrebbe essere sufficiente a garantire la privacy dei propri dati e la loro protezione da accessi indesiderati, in quanto, indipendentemente dal sistema utilizzato per bootare la macchina, un software che permetta l'accesso a oggetti di file system con accesso esplicitamente limitato a determinati account utente e' un software illegale: il suo semplice utilizzo e' perseguibile a norma di legge. E' altresi' vero che non sempre e' agevole/possibile perseguire un reato, senza considerare che un utente inesperto o superficiale potrebbe essere tentato dall'affidare la propria sicurezza interamente al fatto che il suo account (protetto da password) e' l'unico utilizzato per loggarsi sulla macchina. Questo e' l'errore principale, exploitabile tramite il boot non autorizzato.
Contents |
Evitare i reboot non autorizzati
Disabilitare il boot da cd e mettere una password sul bios sono i primi passi per un corretto hardening della proprima macchina. La cosa che quasi tutti dimenticano e' quella di permettere solo a chi e' autorizzato di modificare i parametri di grub semplicemente scrivendo nel file /boot/grub/menu.lst
password mia_password
oppure mettendone l'hash MD5
password --md5 $1$gLhU0/$aW78kHK1QfV3P2b2znUoe/
Per evitare che la macchina venga comunque riavviata con la combinazione di tasti CTRL+ALT+DEL quello che un amministratore deve fare e' commentare la riga
ca::ctrlaltdelete:/sbin/shutdown -t3 -r now
nel file /etc/inittab in questo modo:
#ca::ctrlaltdelete:/sbin/shutdown -t3 -r now
o in questo modo:
ca::ctrlaltdelete:/bin/echo "Switch non permesso"
E' buona norma evitare che, nel caso al boot il sistema non trovi la root, parta con una shell con un messaggio del tipo
"ALERT! /dev/sda1 does not exist. Dropping to a shell! .
Aggiungendo in /boot/grub/menu.lst alla riga
kernel /boot/vmlinuz-2.6.17-11-generic root=/dev/hda2 ro quiet splash vga=791
il flag panic=0 in questo modo:
kernel /boot/vmlinuz-2.6.17-11-generic root=/dev/hda2 ro quiet splash vga=791 panic=0
si eviterà questo inconveniente.
La privacy
Per tutelare la nostra privacy e' consigliabile cancellare cio' che si è digitato fino al momento del logout. Di solito gli utenti non effettuano mai la procedura di pulizia perchè non pensano di aver scritto informazioni che a qualcuno torneranno utili.
Quindi editiamo il file /etc/profile aggiungendo:
trap clear 0
in questo modo la console verrà pulita dopo ogni logout.
E' buona norma in un sistema che gli utenti non possano leggere le home directory degli altri utenti. Per automatizzare il procedimento nei sistemi che usano adduser si edita il file /etc/adduser.conf modicando (e aggiungendo qualora manchi) il valore a 0700 di DIR_MODE:
DIR_MODE 0700
Monitoring e limitazioni per gli utenti
E' altrettanto importante per un buon amministratore monitorare i comandi lanciati da ogni utente editando opportunamente le seguenti righe del file /etc/login.defs
LOG_UNKFAIL_ENAB yes registra i login falliti
LOG_OK_LOGINS yes registra i login riusciti
SULOG /var/log/sulog registra chi ha dato il comando su
DEFAULT_HOME no non permette l'accesso ad utenti senza home
UMASK 027 impostazioni sicure dell'umask (TODO)
E' oltretutto inutile che tutti gli utenti possano utilizzare una shell dato che non tutti ne hanno bisogno. Ad esempio potrebbero dover solo fare copie remote su canale sicuro (scp) ed altri dovranno leggere solo la posta. Nel primo caso modificheremo, nel file /etc/passwd la riga
spawn:x:1000:1000:Andrea Ferraresi,,,:/home/spawn:/bin/bash
con
spawn:x:1000:1000:Andrea Ferraresi,,,:/home/spawn:/usr/bin/scponly
nel secondo con
spawn:x:1000:1000:Andrea Ferraresi,,,:/home/spawn:/bin/mutt
e cosi' via.
PAM e il login sicuro
PAM (Pluggable Authentication Module) e' la soluzione a tutto quanto riguardi il login. E' vastissimo e non proprio una semplice da utilizzare e configurare. PAM e' un backend di autenticazione, cioe' un insieme di librerie che servono a determinare come un utente viene identificato. Il numero di moduli per PAM e' immenso, esistono moduli per l'autenticazione biometrica (riconoscimento impronte digitali, scansione dellla retina), puo' essere settato per partizioni cifrate e cosi' via.
Essendo un tool estremamente potente vedremo solo alcuni degli aspetti modificabili tramite PAM ma prima di tutto ecco un briefing dei files piu' importanti:
- /etc/security/access.conf : sovrintende ai sistemi di autenticazione degli utenti. Grazie a questo file e' infatti possibile limitare l'accesso da parte di utenti da determinate reti o dispositivi.
- /etc/security/group.conf : come e' possibile intuire regola il comportamento dei gruppi di utenti
- /etc/security/time.conf : tramite il modulo pam_time si stabiliscono i termini di tempo del login (quando un utente puo' collegarsi e per quanto tempo)
- /etc/security/limits.conf : questo file, come suggerisce il nome, serve per impostare i limiti degli utenti, cioe' quanto un utente puo' sfruttare le risorse del nostro sistema allo scopo di evitare attacchi di tipo DOS.
Prima di intraprendere la parte della configurazione introdurremo il concetto di limite. (TODO)
No ai buffer overflows
Un buffer overflow e' un errore di programmazione che puo' essere sfruttato da un utente malizioso che consiste nell'immettere dei dati in modo da superare lo spazio stabilito in un buffer di dimensioni finite, il che puo' causare un'eccezione di memoria o una breccia nella sicurezza del sistema.
Esistono diversi tipi di buffer overflow: il piu' comune e pericoloso e' lo stack overflow, ovvero l'overflow di un buffer situato in una particolare area di memoria (denominata appunto stack) dedicata alla memorizzazione di informazioni estremamente sensibili: parametri ed indirizzi di memoria di chiamate di sistema. Esistono due modi di sfruttare uno stack overflow: il piu' semplice consiste nell'immettere nel buffer un flooding di dati (ovvero una grossa quantita' di dati casuali) che causa un crash del programma affetto dall'errore e un conseguente "Denial Of Service". Il secondo modo e' invece molto piu' pericoloso in quanto compromette potenzialmente la sicurezza dell'intero sistema o addirittura dell'intera rete locale che offre il servizio (questo pero' solo in casi di una cattiva configurazione generale -- e' il caso peggiore). Tale metodo consiste nell'immettere nel buffer dati non casuali, ma ben congegnati e tali da costituire vere e proprie chiamate di sistema, con tutti i parametri e gli indirizzi del caso. E' facile capire come uno stack overflow ben sfruttato possa quasi avvicinarsi all'esecuzione di codice arbitrario sulla macchina attaccata.
Quando poi un errore di stack overflow si verifica in condizioni particolari del programma, e' addirittura possibile scrivere nello stack un indirizzo che punti al contenuto stesso dei dati di overflow: questo porta all'esecuzione vera e propria di codice arbitrario nel sistema, che e' in assoluto l'attacco piu' dannoso possibile.
Un buon programmatore dovrebbe utilizzare strumenti che permettano di trovare errori del genere : sotto linux esiste la patch "SSP Stack Smashing Protection" per il GCC. Un buon amministratore deve prevenire che si verifichino buffer overflow ed e' possibile farlo con apposite patch del kernel come PaX, che permette ai programmi di sfruttare le pagine di memoria soltanto per lo scopo per cui sono state allocate. Un'altra buona pratica amministrativa per contenere gli effetti di un buffer overflow e' quella di far girare i processi "a rischio" (ovvero tipicamente quelli in comunicazione con l'esterno) nelle cosiddette "jails" (letteralmente "prigioni"). "Jailare" un processo significa segregarlo ad una determinata porzione del filesystem rendendogli di fatto invisibile ed inaccessibile tutto il resto del sistema. Si tratta di una feature tipicamente implementata a livello di kernel del sistema operativo e simile alla feature di cambiamento di root ("chroot"). Si notino tuttavia determinate limitazioni delle jails:
- non sono sempre attuabili -- per funzionare correttamente certi software *richiedono* l'accesso a determinate risorse privilegiate
- pur proteggendo il resto del sistema non impediscono comunque il crash del programma e il conseguente DoS in caso di sfruttamento del buffer overflow
Potete trovare una spiegazione piu' approfondita qui. PaX viene fornito di base insieme al pacchetto grsecurity che in adamantix (una versione sicura di debian) e' di base insieme al gcc opportunamente patchato.
--Spawn 20:56, Mar 4, 2007 (CET) Andrea Ferraresi<andrea.ferraresi@gmail.com>
