Sicurezza nei sistemi Unix

Tempo di lettura: 9 minuti
Data pubblicazione: February 7, 2017

I sistemi operativi moderni sono implementati con una serie di protezioni specifiche per garantire la sicurezza dell’utente, come l’identificazione, il controllo dell’accesso e una serie di log che certificano gli stessi. Nello specifico, i sistemi Unix-like, sono:

  • multiutente: più utenti possono agire contemporaneamente, ma un utente con gli stessi privilegi di un altro non dovrebbe interferirè con le attività degli altri;
  • _multiprogrammati: _il kernel può supportare uno pseudo-parallelismo di processi;
  • aperti;
  • portabili.

Il design del sistema è quindi improntato sul proteggere gli utenti da altri utenti, oltre che da attacchi provenienti dalla rete.

Tipologie di account

Gli utenti possono classificarsi principalmente, in:

  • user account: utenti senza permessi di root;
  • root: utente con i permessi di amministrazione.

Il superuser o root può accedere praticamente a tutto. Ad esempio, può modificare le password, impersonificare altri utenti, o cambiare le impostazioni del sistema di sicurezza (come l’accesso ai file).

Ogni utente è identificato univocamente dallo UID (User Identifier) salvato nel file _/etc/passwd, _il quale contiene le informazioni su tutti gli account salvati nel sistema. Gli utenti possono appartenere anche a gruppi (definiti dall’amministratore) e vengono identificati dal GID (Group identifier), un intero che identifica un particolare gruppo (come può essere mail). Tutti i gruppi sono salvati nel file /etc/group.

Il file /etc/passwd è composto da:

nomeutente:password:UID:GID:nomecompleto:cartellahome:shelldilogin

mentre il file /etc/group:

nomegruppo:password:GID:listadegliutenti

Le password sono cifrate con l’algoritmo crypt(3), il quale riprende una versione leggermente modificata di DES, ripetendo il processo 25 volte (approfondimento). Tutt’oggi non è stato trovato un metodo per invertire il processo e l’unica modalità per trovare la stringa originale è tramite un attacco di forza bruta o tramite un attacco a dizionario. Proprio per questo, anche se un utente possiede i permessi di amministratore non potrà mai visualizzare le password ma potrà “solamente” cambiarle (con il comando passwd).

I moderni sistemi Unix-like non salvano più le password in _/etc/passwd _ma in un altro file, /etc/shadow.

Processi

In Unix ogni processo ha un ID detto PID (process ID) e può creare altri processi tramite _exec _o una fork. Essi hanno diversi attributi, tra i quali:

  • PID: come detto, identifica univocamente il processo;
  • parent ID: identifica il processo padre;
  • Session ID: identifica la sessione di cui il processo fa parte;
  • real UID: identifica il reale utente proprietario;
  • real GID: identifica il gruppo principale reale;
  • elenco dei descrittori;
  • inode.

Per vedere tutti i processi attivi nel sistema basta digitare ps e gli argomenti che si necessitano. Ad esempio

root@kali:~# ps -eF | grep "firefox"
UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
root      1683     1 19 474694 595800 1 21:05 tty2     00:21:52 firefox-esr

File

Ogni file ha un proprietario, solitamente chi ha creato il file. Con il comando ls -l è possibile vedere le informazioni principali

che sono:

  • il primo carattere identifica il tipo di file:
    1. _"-" _per un file;
    2. _“d” _per una cartella;
    3. _“b” _per un dispositivo a blocchi;
    4. c” per un dispositivo a caratteri;
    5. “l” per un link_._
  • i successivi nove caratteri identificano i permessi che un file possiede;
  • il campo numerico conta il numero di link pointers al file;
  • le due stringhe indicano, rispettivamente, il nome del proprietario e il gruppo del file;
  • il campo numerico successivo la grandezza in bytes;
  • tempo di ultima modifica (per vedere il tempo di ultime accesso il comando è ls -la);
  • ed infine, nome del file.

I permessi sono raggruppati in tre triplette che definisco la lettura, la scrittura e l’esecuzione per il proprietario, il gruppo e tutti gli altri. Quindi, ad esempio

rw-r--r--

è un file leggibile e scrivibile per il proprietario, e di sola lettura per i gruppi e gli altri. I permessi in Unix possono essere anche definiti con una rappresentazione ottale, e combinando la somma dei vari permessi si ottiene una semplificazione della rappresentazione simbolica

Ad esempio, con un permesso di 750, il proprietario del file ha 7 (4+2+1), ossia lettura, scrittura ed esecuzione, il gruppo ha 5 (4+1) quindi lettura ed esecuzione e gli altri non hanno permessi. Altri permessi (ed esempi) si possono trovare su Wikipedia.

Unix quando crea un file utilizza tipicamente 666, e 777 quando crea una nuova cartella.

I permessi per una cartella sono molto simili ai file normali:

  • Read: si possono vedere quali file sono nella directory;
  • Write: si possono aggiungere o rimuovere file;
  • Execute: si può entrare nella cartella o aprire file all’interno di essa.

Per modificare il bit dei permessi di un file, il comando è chmod. Esso accetta come permessi, sia argomenti numerici che stringhe.

Il proprietario di un file può essere invece modificato con chown, mentre il gruppo con chgrp.

Uno dei programmi più utili di Unix per controllare permessi e informazioni di un file o di una cartella è stat. Esso, oltre ai file, può ritornare anche informazioni in merito al filesystem. Per verificare chi ha il possesso di un determinato file

root@kali:~#  stat -c "%a %U:%G %n" /usr/bin/passwd 
4755 root:root /usr/bin/passwd

Per verificare le informazioni di un file

root@kali:~/Desktop# stat Main.java 
  File: Main.java
  Size: 291       	Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d	Inode: 3279174     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-02-04 09:25:21.695844089 +0100
Modify: 2017-02-01 11:15:59.182770663 +0100
Change: 2017-02-01 11:15:59.234770660 +0100
 Birth: -

Servizi di rete

Durante una qualsiasi sessione vengono aperte decine di connessioni verso la rete. I programmi principali per verificare i servizi di rete sono:

  1. _ss: _ottima utility per investigare le socket del sistema. I comandi principali sono **_ss -s _**che permesse di vedere il numero attuale di socket presenti e _ss -l _(molto più prolisso e dettagliato);
  2. netstat: stampa le connessioni di rete, statistiche sulle interfaccie e le connessioni in corso. Il comando **_netstat -s _**stampa, ad esempio, le statistiche di tutti i protocolli del sistema.

Log

I sistemi Unix-like hanno diverse tool per verificare gli ultimi accessi o tentativi di accesso non autorizzati. Alcuni, tra i tanti;

  • who: registra le informazioni dell’account al momento loggato;
  • finger: registra l’ultimo accesso al sistema;
  • last: registra ogni volta che un utente effettua un login o un logout.

Conclusioni

Ovviamente questo capitolo non vuole sostituirsi ad un corso di sicurezza dei sistemi Unix. Per quello ci sono decine di libri, sicuramente migliori di questo articolo (ad esempio, Pratical Unix Security).

Come ultimi due suggerimenti, consiglierei di studiarsi bene lsof, una delle utility che trovo più complete per verificare la sicurezza di un sistema in un determinato momento, systemctl e ogni tanto un’occhiata alla cartella /var/log, contenente tutti i log del sistema, non fa mai male.