[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]

186. Strumenti per il controllo della sicurezza

Alcuni programmi possono essere di aiuto nel contenimento dei rischi della sicurezza e nello studio del problema in generale. In questo capitolo ne vengono mostrati alcuni.

186.1 Protocollo IDENT

In quasi tutte le distribuzioni GNU/Linux, nel file /etc/inetd.conf appare una riga simile a quella seguente, per l'attivazione del servizio IDENT, corrispondente alla porta auth (113).

auth  stream  tcp  nowait  nobody  /usr/sbin/in.identd in.identd -l -e -o

In alternativa, se il proprio sistema GNU/Linux è configurato diversamente, la riga in questione potrebbe essere più simile a quella seguente:

ident  stream  tcp  nowait  nobody  /usr/sbin/identd identd -l -e -o

Il demone identd ha lo scopo di controllare i collegamenti per mezzo del protocollo TCP. In tal modo è in grado di informare il nodo all'altro capo del collegamento sul nominativo-utente di chi esegue quel collegamento. Si osservi la figura 186.1.

+-------------+ porta 1108        porta 23 +-------------+
|   Host A    |--------------------------->|   Host B    |
|  identd in  |      Connessione TCP       |             |
|  funzione   |<--+                        |             |
+-------------+   |                        +-------------+
                  |     Protocollo IDENT      |
                  +---------------------------+
         «Chi è che ha attivato la connessione 23,1108?»

Figura 186.1: Il protocollo IDENT serve a fornire alla controparte le informazioni necessarie a identificare l'utente che ha in corso una connessione TCP particolare.

Seguendo l'esempio della figura, se un utente del nodo «A» ha iniziato una connessione TCP con il nodo «B» (in questo caso si tratta di Telnet), dal nodo «B» può essere richiesto al nodo «A» di fornire le informazioni sull'utente che esegue il processo responsabile del collegamento. Come si vede, tale richiesta viene fatta usando il protocollo IDENT, e la risposta può essere fornita solo se l'origine gestisce tale servizio.

Fornire questo tipo di informazione è utile, al contrario di ciò che si potrebbe pensare, purché il demone identd non sia stato compromesso, e fornisca informazioni corrette. Se un utente di un sistema che fornisce il servizio IDENT, utilizzando il protocollo TCP, cercasse di aggredire un qualche nodo esterno, l'amministratore di questo potrebbe ottenere il nominativo-utente di questa persona attraverso il protocollo IDENT. Successivamente, tale amministratore avrebbe modo di essere più dettagliato nel riferire l'accaduto al suo collega del sistema da cui è originato l'attacco, e questo a tutto vantaggio di quest'ultimo.

186.1.1 $ identd

/usr/sbin/in.identd [<opzioni>]

Il demone identd è in grado di fornire alla controparte di una connessione TCP il nominativo-utente del proprietario del processo che l'ha avviata. identd può fornire anche altre informazioni, ma questo non rappresenta il suo scopo normale, che è invece quello di consentire il monitoraggio degli accessi da parte dei destinatari delle connessioni. *1*

È il caso di sottolineare che, per fornire esclusivamente le informazioni strettamente necessarie al raggiungimento di tale obbiettivo, si utilizzano normalmente le opzioni -l, -e e -o, ed eventualmente si può valutare la possibilità di aggiungere anche -n.

identd è in grado di conoscere esclusivamente l'utente «reale» del processo. Per cui, un processo avviato con il bit SUID attivo otterrà i privilegi dell'utente proprietario del file binario, e sarà questo utente a essere mostrato da identd.

Alcune opzioni

-b

Utilizzando l'opzione -b si permette l'avvio di identd in modo indipendente da inetd. In generale, si preferisce attivare il servizio IDENT attraverso inetd.

Se viene utilizzata questa opzione, è necessario indicarne delle altre per informare identd di una serie di cose che altrimenti sono gestite da inetd. Per conoscerle si può consultare la pagina di manuale identd(8).

-l

Attiva la registrazione delle richieste IDENT nel registro del sistema. Non si tratta della registrazione dei nomi degli utenti che si connettono, ma delle sole richieste fatte dai nodi remoti che chiedono «chiarimenti» sulle connessioni partite dal sistema locale verso di loro.

-o

Fa in modo che non venga rivelato il nome del sistema operativo. Al suo posto viene restituita la parola OTHER.

-e

Fa in modo di non specificare la motivazione degli errori. Senza questa opzione, identd potrebbe restituire informazioni del tipo: NO-USER, INVALID-PORT. Con questa opzione, l'unico messaggio di errore è UNKNOWN-ERROR.

-n

Utilizzando questa opzione, si fa in modo che identd non fornisca il nome dell'utente proprietario del processo che instaura la connessione, restituendo al suo posto il numero UID.

-N

Permette agli utenti di nascondersi attraverso la creazione di un file ~/.noident. È chiaro che per gli scopi in cui è utile tale servizio, questa opzione non deve essere usata; diversamente un aggressore che non vuole essere identificato potrebbe bloccare facilmente identd.

Esempi

# /etc/inetd.conf
#...
auth  stream  tcp  nowait  nobody  /usr/sbin/in.identd in.identd -l -e -o

Utilizzo normale di identd dichiarandone l'uso all'interno del file /etc/inetd.conf. In questo caso si osserva l'uso delle opzioni -l, -e e -o, con cui si attiva l'annotazione nel registro del sistema, si eliminano le informazioni sul sistema operativo e sul tipo di errori commessi durante l'interrogazione del servizio.

Si osservi l'assenza di tcpd, dal momento che questo servizio deve essere accessibile a tutti i nodi, e non solo a quelli che passano il filtro stabilito all'interno di /etc/hosts.allow e /etc/hosts.deny. Inoltre, tcpd non può essere utilizzato soprattutto perché esso stesso può essere configurato per interrogare l'origine di una richiesta attraverso il protocollo IDENT, e in tal caso si formerebbe un ciclo senza fine.

186.1.2 Interrogazione del servizio e librerie

A quanto pare manca un programma di utilità specifico per l'interrogazione del servizio IDENT; in pratica si deve utilizzare Telnet verso la porta 113 (auth).

Il primo problema è quello di scoprire le porte della connessione che si intende verificare alla fonte. Questo lo si fa con netstat. A titolo di esempio, si immagina di essere nel nodo «B» dello schema mostrato nella figura 186.1, e di volere verificare l'origine di una connessione Telnet proveniente dal nodo «A» (proprio come mostrava la figura).

Prima di tutto, si deve scoprire che esiste una connessione Telnet (sospetta), e questo avviene attraverso la lettura dei messaggi del registro del sistema. Purtroppo, se tcpd non è configurato correttamente, potrebbe mancare l'indicazione delle porte utilizzate, costringendo ad andare un po' per tentativi. Si suppone che sia in corso attualmente un'unica connessione di questo tipo, in tal caso la lettura del rapporto di netstat non può generare equivoci.

netstat -n

Il rapporto potrebbe essere piuttosto lungo. Per quello che riguarda questo esempio, si potrebbe notare l'estratto seguente:

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
...
tcp        0      0 192.168.254.1:23        192.168.1.1:1108        ESTABLISHED 
...

Di conseguenza, «noi» siamo 192.168.254.1 e il nodo remoto è 192.168.1.1. Per interrogare il servizio IDENT presso il nodo remoto si utilizza Telnet nel modo seguente (eventualmente, al posto del nome auth si può indicare direttamente il numero: 113).

telnet 192.168.1.1 auth[Invio]

Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.

1108 , 23[Invio]

1108 , 23 : USERID : OTHER :tizio
Connection closed by foreign host.

Così si viene a conoscere che la connessione è intrattenuta dall'utente tizio@192.168.1.1.

Un demone di un qualunque servizio potrebbe essere modificato in modo da utilizzare sistematicamente il protocollo IDENT per interpellare i client, e annotare nel registro del sistema gli utenti che accedono. Per questo, e per altri possibili utilizzi, esiste la libreria libident, disponibile con quasi tutte le distribuzioni GNU/Linux.

186.1.3 # identtestd

Probabilmente, solo la distribuzione Debian acclude il demone identtestd assieme alla libreria libident. Si tratta di un programma da collocare nel file /etc/inetd.conf, collegandolo a una porta non utilizzata, il cui scopo è solo quello di restituire le informazioni di chi dovesse fare un tentativo di Telnet su quella stessa porta.

In pratica, identtestd serve esclusivamente per verificare il funzionamento del proprio servizio IDENT.

Si attiva il servizio (diagnostico) attraverso una riga come quella seguente, nel file /etc/inetd.conf.

9999  stream  tcp  nowait  root  /usr/sbin/in.identtestd in.identtestd

Una volta riavviato inetd, si può interpellare tale «servizio» con Telnet da un nodo in cui è presente IDENT, e se ne vuole verificare il funzionamento. Si osservi l'esempio.

telnet 192.168.1.1 9999[Invio]

Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
Welcome to the IDENT server tester, version 1.9

(Linked with libident-libident 0.21 Debian 4)

Connecting to Ident server at 192.168.254.1...
Querying for lport 2252, fport 9999....
Reading response data...
Userid response is:
   Lport........ 2252
   Fport........ 9999
   Opsys........ OTHER
   Charset...... <not specified>
   Identifier... root
Connection closed by foreign host.

186.2 Tcp wrapper più in dettaglio

L'uso di tcpd è già stato descritto in modo sommario nel capitolo 84. In quella fase sono state trascurate le sue potenzialià di controllo, che possono estendersi fino all'utilizzo del protocollo IDENT.

La configurazione di tcpd avviene esclusivamente attraverso i file /etc/hosts.allow e /etc/hosts.deny, all'interno dei quali si possono utilizzare direttive più complesse di quelle già viste in precedenza. In ogni caso, è bene ribadire che lo scopo di questi file è quello di trovare una corrispondenza con l'utente e il nodo che tenta di accedere a uno dei servizi messi sotto il controllo di inetd. La verifica inizia dal file /etc/hosts.allow e continua con /etc/hosts.deny, fermandosi alla prima corrispondenza corretta. Se la corrispondenza avviene con una direttiva del file /etc/hosts.allow, l'accesso è consentito; se la corrispondenza avviene con una direttiva di /etc/hosts.deny, l'accesso è impedito; se non avviene alcuna corrispondenza l'accesso è consentito.

186.2.1 Dichiarazione all'interno di /etc/inetd.conf

La dichiarazione di un servizio all'interno del file /etc/inetd.conf può avvenire fondamentalmente in due modi possibili: con o senza il filtro di tcpd. Si osservino i due esempi seguenti.

# /etc/inetd.conf
#...
telnet	stream  tcp 	nowait  root    /usr/sbin/in.telnetd	in.telnetd
#...

# /etc/inetd.conf
#...
telnet	stream  tcp 	nowait  root    /usr/sbin/tcpd	in.telnetd
#...

Nel primo caso, quando si instaura una connessione Telnet, inetd avvia direttamente il binario /usr/sbin/in.telnetd, senza altre intermediazioni. L'albero dei processi potrebbe apparire come nell'esempio seguente:

init-+-inetd---in.telnetd---login---bash---...
     |
     ...

Nel secondo caso, invece, un'eventuale connessione Telnet viene preceduta dalla verifica di tcpd, che potrebbe anche rifiutarla, oppure semplicemente aggiungere dei controlli. Ma una volta completati i controlli, se il server può essere avviato, tcpd si toglie di mezzo, e l'albero dei processi appare esattamente uguale a quanto già visto.

Quando si decide di utilizzare tcpd, si possono presentare altre possibilità. Per la precisione, perché funzioni quanto visto nell'ultimo esempio, occorre che l'eseguibile in.telnetd si trovi nella directory prevista da tcpd, secondo quanto definito in fase di compilazione dei sorgenti. In pratica, per GNU/Linux si tratta di /usr/sbin/.

Se il demone di un determinato servizio si trova in una collocazione differente rispetto a quella standard, questo potrebbe essere indicato utilizzando il percorso completo, come nell'esempio seguente:

# /etc/inetd.conf
#...
telnet	stream  tcp 	nowait  root    /usr/sbin/tcpd	/root/bin/in.telnetd
#...

In questo caso, viene specificato che il demone necessario a ricevere le connessioni Telnet è precisamente /root/bin/in.telnetd.

Nella documentazione di tcpd si mostra la possibilità di utilizzare questo programma solo a scopo di verifica dei tentativi di accesso, che vengono annotati nel registro del sistema, sostituendo il demone che dovrebbe essere avviato con una copia di tcpd stesso. Supponendo di volere eliminare il servizio Finger pur continuando a monitorare le richieste di questo, si potrebbe agire come segue:

mkdir /directory/segreta

mv /usr/sbin/in.fingerd /directory/segreta

cp /usr/sbin/tcpd /usr/sbin/in.fingerd

In alternativa, si può ottenere un risultato simile semplicemente togliendo il programma demone del servizio, lasciando però la dichiarazione nel file /etc/inetd.conf. La differenza che si può avvertire sta nelle ulteriori segnalazioni di errore che si ritrovano nel registro del sistema, che avvisano dell'impossibilità di avviare il programma corrispondente.

186.2.2 Limiti e particolarità di tcpd

In generale, le connessioni RPC non si riescono a controllare facilmente con tcpd. In particolare, i servizi annotati come rpc/tcp nel file /etc/inetd.conf non sono gestibili attraverso tcpd.

Alcuni demoni UDP e RPC rimangono attivi al termine del loro lavoro, in attesa di un'ulteriore richiesta eventuale. Questi servizi sono registrati nel file /etc/inetd.conf con l'opzione wait e così si possono riconoscere facilmente. Come si può intuire, solo la richiesta che li avvia può essere controllata da tcpd.

Alcuni dettagli di funzionamento di tcpd sono definiti in fase di compilazione dei sorgenti. Si tratta in particolare dell'opzione di compilazione -DPARANOID, con la quale è come se fosse sempre attivo il jolly PARANOID nei file /etc/hosts.allow e /etc/hosts.deny. Di solito, i pacchetti già compilati di tcpd sono stati ottenuti senza questa opzione, in modo da lasciare la libertà di configurare questo programma come si vuole.

Un altro elemento che può essere definito con la compilazione è il tipo di direttive che si possono accettare nei file /etc/hosts.allow e /etc/hosts.deny. Le due sintassi possibili sono descritte in due documenti separati: hosts_access(5) e hosts_options(5).

186.2.3 /etc/hosts.allow /etc/hosts.deny

In questa sezione viene mostrata in particolare la sintassi dei file /etc/hosts.allow e /etc/hosts.deny, quando nella fase di compilazione di tcpd non è stata abilitata l'estensione PROCESS_OPTIONS; in pratica quella più limitata. Negli esempi si mostreranno anche le corrispondenze con il secondo tipo di formato, che comunque offrirebbe molte possibilità in più, e queste possono essere approfondite leggendo hosts_options(5).

<elenco-di-demoni> : <elenco-di-client> [ : <comando-di-shell> ]

La sintassi mostrata, che si riferisce al tipo più semplice di formato delle direttive di questi file, potrebbe essere trasformata in quello più complesso nel modo seguente:

<elenco-di-demoni> : <elenco-di-client> [ : spawn <comando-di-shell> ]

Quando non si sa quale sia il formato giusto per il proprio tcpd, basta provare prima il formato più semplice. Se non va si vede subito la segnalazione di errore nel registro del sistema.

I primi due elementi, l'elenco di demoni e l'elenco di client, sono già stati descritti nel capitolo 84. Vale forse la pena di ricordare che questi «elenchi» sono semplicemente nomi o modelli separati da spazi orizzontali, e questo spiega la necessità di separare i vari campi delle direttive attraverso i due punti verticali.

Ciò che appare a partire dal terzo campo di queste direttive (nel caso mostrato si tratta di un comando di shell, ma con la sintassi più complessa si parla piuttosto di opzioni), può contenere delle variabili, rappresentate da un simbolo di percentuale (%) seguito da una lettera, che vengono espanse da tcpd ogni volta che viene verificata la corrispondenza con quella direttiva determinata che le contiene (tabella 186.1).

Variabile Contenuto
%a L'indirizzo del client.
%A L'indirizzo del server.
%c L'informazione completa del client per quanto disponibile.
%d Il nome del processo del demone.
%h Il nome del client o l'indirizzo se il nome non è disponibile.
%H Il nome del server o l'indirizzo se il nome non è disponibile.
%n Il nome del client o unknown o paranoid.
%N Il nome del server o unknown o paranoid.
%p Il numero del processo del demone.
%s Informazione completa del server per quanto disponibile.
%u Il nome dell'utente del client o unknown.
%% Un simbolo di percentuale singolo.

Tabella 186.1: Elenco delle variabili utilizzabili in alcune parti delle direttive dei file di controllo degli accessi.

Una direttiva può contenere il simbolo di due punti (:) all'interno di certi campi. In tal caso, per evitare che questi si confondano con la separazione dei campi, occorre precedere tale simbolo con la barra obliqua inversa: \:.

Una direttiva può essere interrotta e ripresa nella riga successiva se alla fine della riga appare una barra obliqua inversa, subito prima del codice di interruzione di riga.

Ogni volta che si modifica uno di questi file, è indispensabile verificare che nel registro di sistema non appaiano indicazioni di errori di sintassi. Un problema tipico che si incontra è dovuto al fatto che ogni direttiva deve terminare con un codice di interruzione di riga. Se alla fine di una direttiva terminasse anche il file, questo costituirebbe un errore che ne impedirebbe il riconoscimento.

186.2.3.1 Demoni e client specificati in modo più preciso

I primi due campi delle direttive di questi file, permettono di indicare con più precisione sia i demoni che i client che accedono.

Quando il server ha diversi indirizzi IP con cui può essere raggiunto, è possibile indicare nel primo campo un demone in combinazione con un indirizzo particolare dal quale proviene la richiesta. In pratica, il primo campo diventa un elenco di elementi del tipo seguente:

<demone>@<modello-server>

Il demone può essere indicato per nome, oppure può essere messo al suo posto il jolly ALL che li rappresenta tutti.

Il modello del server serve a rappresentare questi indirizzi per nome o per numero. Valgono anche in questo caso le regole con cui si possono definire i nomi e gli indirizzi di client, anche per quanto riguarda le indicazioni parziali (un intero dominio o un gruppo di indirizzi).

Più interessante è invece la possibilità di ottenere da tcpd la verifica del nominativo-utente del processo avviato dal client per la connessione. Si veda per questo, quanto già descritto in precedenza al riguardo del protocollo IDENT. Basta utilizzare nel secondo campo la sintassi seguente:

<modello-utente>@<modello-client>

Utilizzando questa forma, tcpd, prima di concedere l'accesso al servizio, interpella il client attraverso il protocollo IDENT, per ottenere il nome dell'utente proprietario del processo che ha instaurato la connessione.

Se il client non risponde a questo protocollo, si crea un pausa di ritardo di circa 10 secondi. Implicitamente si penalizzano tutti gli utenti che usano sistemi operativi diversi da Unix e derivati.

Una volta ottenuta la risposta, o quando scade il tempo, può essere fatto il confronto con la direttiva. In ogni caso, questo tipo di direttiva fa sì che venga aggiunta questa informazione nel registro del sistema.

Il modello dell'utente può essere un nome puro e semplice, oppure un jolly: ALL, KNOWN e UNKNOWN. Il significato è intuitivo: tutti gli utenti; solo gli utenti conosciuti; solo gli utenti sconosciuti.

Il modello del client è quello già visto in precedenza: nomi interi; nomi parziali che iniziano con un punto; indirizzi IP interi; indirizzi IP parziali che terminano con un punto; jolly vari.

È bene ribadire che l'informazione sull'utente restituita dal protocollo IDENT, non è affidabile. Un sistema compromesso potrebbe essere stato modificato in modo da restituire informazioni false.

186.2.3.2 Comandi di shell

Il terzo campo delle direttive di questi file, permette di inserire un comando di shell. Quando un accesso trova corrispondenza con una direttiva contenente un comando di shell, questo comando viene eseguito; mentre l'accesso viene consentito se la corrispondenza avviene all'interno del file /etc/hosts.allow.

Il comando può contenere le variabili descritte nella tabella 186.1, e queste sono utili per dare un senso a questi comandi.

Il comando viene eseguito utilizzando l'interprete /bin/sh, connettendo standard input, standard output e standard error al dispositivo /dev/null. Generalmente, alla fine del comando viene indicato il simbolo &, in modo da metterlo sullo sfondo, per evitare di dover attendere la sua conclusione.

Questi comandi non possono fare affidamento sulla variabile di ambiente PATH per l'avvio degli eseguibili, per cui si usando generalmente percorsi completi, a meno che questa variabile sia inizializzata esplicitamente all'interno del comando stesso.

186.2.3.3 Esempi e trappole

Seguono alcuni esempi che dovrebbero chiarire meglio l'uso delle direttive dei file /etc/hosts.allow e /etc/hosts.deny.

In tutti gli esempi mostrati si suppone che il file /etc/hosts.deny contenga solo la direttiva ALL:ALL, in modo da escludere ogni accesso che non sia stato previsto espressamente nel file /etc/hosts.allow.

# /etc/hosts.allow
#
ALL : ALL@ALL

Supponendo che questa sia l'unica direttiva del file /etc/hosts.allow, si intende che vengono consentiti esplicitamente tutti gli accessi a tutti i servizi. Tuttavia, avendo utilizzato la forma ALL@ALL nel secondo campo, si attiva il controllo dell'identità dell'utente del client, ottenendone l'annotazione del registro del sistema.

# /etc/hosts.allow
#
ALL : KNOWN@ALL

La direttiva combacia solo con accessi in cui gli utenti siano identificabili.

# /etc/hosts.allow
#...
in.telnetd : ALL : ( /usr/sbin/safe_finger -l @%h | \
	/bin/mail -s '%d-%u@%h' root ) &

Si tratta di una trappola con cui l'amministratore vuole essere avvisato di ogni tentativo di utilizzo del servizio Telnet. Il comando avvia safe_finger (una versione speciale del comando finger che accompagna tcpd) in modo da conoscere tutti i dati possibili sugli utenti connessi alla macchina client, e invia il risultato al comando mail per spedirlo a root.

Molto probabilmente, l'amministratore che prepara questa trappola, farà in modo che il demone in.telnetd non sia disponibile, in modo tale che la connessione venga comunque rifiutata.

Se fosse stato necessario utilizzare l'altro tipo di formato per le direttive di questi file, l'esempio appena mostrato sarebbe il seguente: si aggiunge la parola chiave spawn che identifica l'opzione corrispondente.

# /etc/hosts.allow
#...
in.telnetd : ALL : spawn ( /usr/sbin/safe_finger -l @%h | \
	/bin/mail -s '%d-%u@%h' root ) &

L'esempio seguente mostra un tipo di trappola meno tempestivo, in cui ci si limita ad aggiungere un'annotazione particolare nel registro del sistema per facilitare le ricerche successive attraverso grep.

in.telnetd : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
in.rshd    : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
in.rlogind : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
in.rexecd  : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
ipop2d     : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
ipop3d     : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
imapd      : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &
in.fingerd : ALL@ALL : ( /usr/bin/logger TRAPPOLA\: %d %c ) &

Trattandosi di servizi che non si vogliono offrire (altrimenti non ci sarebbe ragione di registrare tanto bene gli accessi), anche in questo caso è opportuno che i demoni corrispondenti non ci siano, oppure che i rispettivi eseguibili siano sostituiti da una copia dello stesso tcpd.

Si osservi in particolare che all'interno del comando appare il simbolo di due punti protetto da una barra obliqua. Se non si facesse così, potrebbe essere interpretato come l'inizio di un nuovo campo.

186.2.3.4 Comandi e servizi UDP

I servizi UDP non si prestano tanto per la creazione di trappole, a causa del fatto che non si instaura una connessione duratura come nel caso del protocollo TCP. Il caso più importante di questo problema è rappresentato dal servizio TFTP, che di solito viene indicato nel file /etc/inetd.conf nel modo seguente:

tftp	dgram	udp	wait	root	/usr/sbin/tcpd	in.tftpd

Se si creasse una direttiva come la seguente,

# /etc/hosts.allow
#...
in.tftpd : ALL : ( /usr/sbin/safe_finger -l @%h | \
	/bin/mail -s '%d-%u@%h' root ) &

si rischierebbe di avviare il comando di shell un gran numero di volte. Si può limitare questo problema modificando la riga contenuta nel file /etc/inetd.conf nel modo seguente:

tftp	dgram	udp	wait.2	root	/usr/sbin/tcpd	in.tftpd

In tal modo, si accetterebbero un massimo di due connessioni al minuto.

In generale, dovendo realizzare delle trappole per servizi UDP, conviene eliminare del tutto il demone dal filesystem.

186.2.4 # tcpdchk

tcpdchk [<opzioni>]

tcpdchk permette di controllare la configurazione del tcp wrapper, indicando problemi possibili ed eventualmente anche dei suggerimenti per la loro sistemazione.

tcpdchk analizza i file /etc/inetd.conf, /etc/hosts.allow e /etc/hosts.deny. Tra i vari tipi di verifiche che vengono eseguite, ci sono anche i nomi utilizzati per i nodi e i domini NIS. In tal senso, per avere un controllo più preciso, è opportuno utilizzare tcpdchk anche quando il sistema viene collegato in rete, avendo accesso alla configurazione reale del DNS e del NIS.

Alcune opzioni

-d

Esamina i file ./hosts.allow e ./hosts.deny, cioè quelli che si trovano nella directory corrente.

-i <file-inetd>

Specifica il file da utilizzare al posto di /etc/inetd.conf.

186.2.5 # tcpdmatch

tcpdmatch [<opzioni>] <demone>[@<server>] [<utente>@]<client>

tcpdmatch permette di verificare il comportamento della configurazione simulando delle richieste. In pratica, verifica il contenuto di /etc/inetd.conf, /etc/hosts.allow e /etc/hosts.deny e mostra quello che succederebbe con una determinata richiesta di connessione.

È obbligatoria l'indicazione di un demone, con l'eventuale aggiunta dell'indicazione del server quando si possono distinguere per questo degli indirizzi diversi; ed è obbligatoria l'indicazione del client, con l'eventuale aggiunta dell'utente.

Nell'indicazione del server si possono usare anche i jolly UNKNOWN e PARANOID; il valore predefinito, se questa indicazione manca, è UNKNOWN.

L'utente può essere indicato per nome o per numero UID; anche in questo caso si ammette il jolly UNKNOWN, che è il valore predefinito in mancanza di questa indicazione.

Alcune opzioni

-d

Esamina i file ./hosts.allow e ./hosts.deny, cioè quelli che si trovano nella directory corrente.

-i <file-inetd>

Specifica il file da utilizzare al posto di /etc/inetd.conf.

Esempi

tcpdmatch in.telnetd localhost

Verifica il comportamento della configurazione per una richiesta di accesso al servizio Telnet, corrispondente al demone in.telnetd, da parte del nodo localhost.

tcpdmatch in.telnetd tizio@roggen.brot.dg

Verifica il comportamento della configurazione per una richiesta di accesso al servizio Telnet, corrispondente al demone in.telnetd, da parte dell'utente tizio dal nodo roggen.brot.dg.

tcpdmatch in.telnetd@dinkel.brot.dg tizio@roggen.brot.dg

Verifica il comportamento della configurazione per una richiesta di accesso al servizio Telnet, corrispondente al demone in.telnetd, proveniente dall'interfaccia corrispondente al nome dinkel.brot.dg, da parte dell'utente tizio dal nodo roggen.brot.dg.

186.2.6 $ safe_finger

safe_finger è un client Finger che, da quanto indicato nella documentazione originale, dovrebbe essere più adatto per la creazione di trappole attraverso i comandi di shell.

Le sue funzionalità sono le stesse del comando finger normale, e non viene indicato altro nella documentazione originale.

186.2.7 $ try-from

try-from permette di verificare il funzionamento del sistema di identificazione del server e del client. Si utilizza nel modo seguente:

rsh <host> /usr/sbin/try-from

Di solito, questo programma si utilizza per verificare il proprio sistema. Per fare un esempio, si immagina di essere l'utente caio che dal nodo dinkel.brot.dg si connette al suo stesso elaboratore per avviare try-from.

rsh dinkel.brot.dg /usr/sbin/try-from[Invio]

client address  (%a): 192.168.1.1
client hostname (%n): dinkel.brot.dg
client username (%u): caio
client info     (%c): caio@dinkel.brot.dg
server address  (%A): 192.168.1.1
server hostname (%N): dinkel.brot.dg
server process  (%d): try-from
server info     (%s): try-from@dinkel.brot.dg

Dal risultato che si ottiene, si può determinare che anche il servizio IDENT dell'elaboratore dinkel.brot.dg (visto come client) funziona correttamente.

186.3 Cambiare directory radice

GNU/Linux, come altri sistemi Unix, offre una funzione di sistema che permette di fare funzionare un processo in un filesystem ridotto, in cui una certa directory diventa temporaneamente la sua nuova directory radice.

Si tratta della funzione chroot(), e nel caso di GNU/Linux, può essere utilizzata solo da un processo che abbia i privilegi dell'utente root.

Le distribuzioni linux mettono normalmente a disposizione il programma chroot che permette di utilizzare in pratica questa funzione. In alternativa, ne esiste un'altra versione perfettamente funzionante con GNU/Linux (anche se non si trova nelle distribuzioni), che offre il vantaggio di fondere le funzionalità di chroot e di su; si tratta di chrootuid di Wietse Venema.

186.3.1 Principio di funzionamento

I programmi di utilità che si occupano di ridefinire la directory radice temporaneamente, per circoscrivere l'ambiente di un determinato processo (e dei suoi discendenti), richiedono l'indicazione della directory che diventerà la nuova directory radice e del programma da avviare al suo interno.

Il processo da avviare in questo ambiente deve trovare lì tutto quello che gli può servire, per esempio le librerie, o altri programmi se il suo scopo è quello di avviare altri sottoprocessi.

È la stessa situazione che si verifica quando si predispone la directory ~ftp/ per l'accesso al servizio FTP anonimo. A titolo di esercizio, può essere preparata una directory del genere riproducendo /bin/, /sbin/, /lib/ e /etc/.

mkdir /tmp/nuova_root

cp -dpR /bin /sbin /lib /etc /tmp/nuova_root

Con quanto preparato in questo modo, si può avviare una shell circoscritta all'ambito della directory /tmp/nuova_root/, che viene fatta diventare appunto la nuova directory radice.

chroot /tmp/nuova_root /bin/bash

Con questo comando, si fa in modo che venga utilizzata la funzione chroot() perché /tmp/nuova_root/ diventi la directory radice per il processo avviato con /bin/bash. È importante comprendere che /bin/bash va inteso qui come parte del sotto-filesystem, e si tratta in generale si /tmp/nuova_root/bin/bash.

Per concludere l'esempio, una volta verificato che si sta lavorando effettivamente in un ambiente ristretto, basta fare terminare il processo per cui è stata cambiata la directory radice, cioè bash.

exit

186.3.2 Possibilità di questo meccanismo

La definizione di un sotto-filesystem, permette di isolare il funzionamento di un programma che potrebbe costituire un pericolo di qualche tipo. Per esempio un servizio di rete che si teme possa consentire un qualche accesso non autorizzato.

Si potrebbe immaginare la possibilità di creare delle utenze in cui gli utenti non possano girovagare nel filesystem, limitandoli all'ambito di un sotto-filesystem appunto. Tuttavia, dal momento che GNU/Linux non permette l'utilizzo della funzione chroot() agli utenti comuni, di fatto non è possibile, almeno con i mezzi normali.

186.3.3 # chroot

chroot <directory> [<comando>]

chroot permette all'utente root di eseguire un comando utilizzando una directory particolare come una nuova directory radice. Il comando, deve essere indicato tenendo conto della situazione che ci si trova di fronte dopo che il cambiamento della directory radice è avvenuto.

Se non viene indicato alcun comando, viene eseguito /bin/sh, nel sotto-filesystem a cui ci si riferisce.

Al termine del funzionamento del processo avviato con il comando, si ritorna allo stato precedente, con il filesystem nelle condizioni in cui si trovava prima.

186.3.4 # chrootuid

chrootuid <directory> <utente> <comando>

chrootuid è un programma simile a chroot, in cui però è possibile indicare l'utente proprietario del processo che viene avviato nella nuova directory radice.

chrootuid non fa parte delle distribuzioni GNU/Linux standard, ma può essere ottenuto facilmente dalla sua origine, presso l'università di Eindhoven in Olanda, ftp://ftp.porcupine.org/pub/security/chrootuid1.2.shar.Z. Fortunatamente la compilazione dei sorgenti non crea problemi con GNU/Linux.

186.3.5 Un esempio pratico: Telnet

In questa sezione si vuole mostrare in che modo potrebbero essere create delle utenze per l'accesso remoto attraverso Telnet, in modo da escludere che gli utenti possano accedere a parti vitali del sistema. L'esempio viene indicato solo in linea di massima, trascurando dettagli che devono poi essere definiti da chi volesse utilizzare tale sistema realmente, e in modo serio.

Per semplificare le cose, si può creare una copia del sistema in funzione, a partire da una sottodirectory (ammesso che ci sia abbastanza spazio disponibile nel disco fisso). Si suppone di farlo nella directory /sicura/.

mkdir /sicura

cp -dpR /bin /dev /etc /home /lib /opt /root /sbin /usr /var /sicura

mkdir /sicura/tmp

chmod 1777 /tmp

mkdir /proc

chmod 0555 /proc

Quindi si «entra» in questo sistema e si fa un po' di pulizia, eliminando in particolare tutto quello che nella directory etc/ non serve. Infatti, si deve considerare che in questo ambientino non esiste una procedura di inizializzazione del sistema, non esiste l'avvio di programmi demone e non si configura la rete. L'unica attenzione deve essere data alla configurazione delle shell che si vogliono poter utilizzare.

chroot /sicura

...

exit

Il sistema circoscritto appena creato, può avere delle difficoltà a funzionare, a causa della mancanza del contenuto della directory proc/ che dovrebbe essere montato anche lì. Questo montaggio può essere definito convenientemente una volta per tutte nel file /etc/fstab del filesystem normale, avendo così due punti di innesto diversi e simultanei.

# /etc/fstab
#...
none	/proc                   proc    defaults        0 0
none    /sicura/proc		proc    defaults        0 0
#...

Si potrebbe valutare la possibilità di non lasciare l'accessibilità alle informazioni di questa directory. Si può provare a vedere se le attività che si vogliono concedere agli utenti sono compromesse dalla sua mancanza. Se il disagio è tollerabile, è meglio evitare di fare questo montaggio quando tutto sarà pronto.

Una volta sistemato questo particolare, tutto funziona meglio nel sistema che si articola dalla directory /sicura/. Per fare in modo che il servizio Telnet utilizzi questo spazio riservato, si deve modificare il file /etc/inetd.conf del filesystem normale, in un modo simile a quello seguente:

telnet	stream  tcp 	nowait  root    /usr/sbin/tcpd	/sicura/telnetd

Come si vede, per l'avvio del servizio è stato indicato l'eseguibile /sicura/telnetd, che in pratica è uno script di shell che contiene la chiamata del comando chroot, prima dell'avvio del vero demone in.telnetd.

#! /bin/sh
chroot /sicura /usr/sbin/in.telnetd

In questo caso, quanto indicato come /usr/sbin/in.telnetd, è in realtà /sicura/usr/sbin/in.telnetd.

Una volta definito questo, dopo aver montato anche la directory /sicura/proc/ e dopo aver riavviato inetd, si può fare un Telnet nel proprio sistema locare, come utente root per sistemare le cose (per farlo, temporaneamente, occorre che il file /sicura/etc/securetty preveda anche i dispositivi /dev/ttyp*, oppure quelli che sono utilizzati effettivamente per l'accesso attraverso Telnet).

Una volta sistemate le cose come si desidera, si dovrà avere cura di impedire l'accesso remoto da parte dell'utente root, e al limite questo utente potrebbe anche essere cancellato all'interno di /sicura/etc/passwd

telnet localhost

...

Una volta entrati nel mini sistema, dopo essersi accertati che funziona (basta creare un file e su un'altra console virtuale vedere che si trova collocato a partire dalla directory /sicura/), si comincia a disinstallare tutto quello che non serve e che non si vuole lasciare usare agli utenti. Probabilmente, tutto quello che riguarda la configurazione della rete dovrebbe essere eliminato, mentre qualche client particolare potrebbe essere lasciato a disposizione degli utenti.

Anche la directory dev/ dovrebbe essere controllata, lasciando al suo interno solo i dispositivi indispensabili. Di certo non servono i dispositivi che permettono l'accesso a unità di memorizzazione: gli utenti remoti non devono avere la possibilità di montare o smontare dischi.

Gli stessi file etc/passwd e etc/group (ed eventualmente etc/shadow) possono essere modificati per eliminare tutti gli utenti di sistema, compreso root che potrebbe essere aggiunto nel momento in cui si volesse fare qualche modifica dall'interno). In pratica, si tratterebbe di lasciare solo gli utenti del servizio Telnet.

186.4 Tripwire

Tripwire è un programma per la verifica dell'integrità dei file attraverso il confronto con le informazioni accumulate precedentemente in un file. Vengono segnalate le aggiunte, le rimozioni e le alterazioni di file e directory. Se usato correttamente, Tripwire può aiutare a scoprire problemi dovuti a un uso improprio del sistema, comprendendo eventualmente l'azione di un virus.

Tripwire utilizza un file di configurazione (collocato in una directory da definire), che qui verrà indicato come tw.config, in modo da seguire la convenzione della documentazione interna di Tripwire.

Come si può intuire, una volta generato il file con le informazioni della situazione attuale del filesystem, è necessario proteggerlo dalle alterazioni, collocandolo in un filesystem in sola lettura (come potrebbe essere un dischetto, dove la protezione dalla scrittura viene fatta con un'azione manuale e non può essere modificata elettronicamente). Meglio sarebbe se potesse essere anche nascosto in qualche modo. Nello stesso modo, se possibile, sarebbe opportuno nascondere il file di configurazione.

Tripwire non è un pacchetto che si possa trovare in tutte le distribuzioni GNU/Linux. È decisamente improbabile che possa trovarsi all'interno delle distribuzioni di origine USA. Tuttavia, data la particolarità del programma, non è molto importante disporre di un pacchetto specifico per la propria distribuzione; l'eseguibile tripwire e il file di configurazione andranno collocati da qualche parte, in modo da non essere individuati facilmente.

186.4.1 Configurazione di Tripwire: tw.config

Per comprendere il funzionamento di Tripwire, è più conveniente vedere prima la sua configurazione attraverso il file tw.config (o qualunque altro nome si decida di utilizzare).

Lo scopo di questo è di elencare i file e le directory che si vogliono tenere sotto controllo, e quali dettagli considerare su questi elementi. Nel file di configurazione possono essere usate anche direttive di pre-elaborazione, per selezionare elenchi differenti in presenza di situazioni determinate. In questa sezione viene ignorata tale particolarità; eventualmente si può consultare la pagina di manuale tw.config(5).

Il formato delle direttive attraverso cui si dichiara l'inclusione o l'esclusione di un file o di una directory, è quello seguente. In particolare, i commenti sono preceduti dal simbolo # e conclusi dal codice di interruzione di riga; le righe bianche e quelle vuote sono ignorate.

[!|=] <voce> [<parametro-riassuntivo>][+<parametri-di-selezione>-<parametri-di-selezione>]

Dal momento che si tratta di qualcosa di insolito rispetto alle solite direttive che si possono incontrare nei file di configurazione di altri programmi, conviene vedere subito un paio di esempi, senza descriverli.

# Include la directory /
/ +pinugsm12-ac3456789

# Esclude la directory /tmp/
!/tmp

Il simbolo iniziale, facoltativo, serve a:

Se non viene indicato alcuno di questi due simboli, si intende verificare il file, o la directory e tutto il suo contenuto in modo ricorsivo.

I parametri di selezione sono dei simboli rappresentati attraverso una singola lettera alfabetica minuscola, o una singola cifra numerica. Ognuno di questi simboli rappresenta l'utilizzo o meno di un'analisi particolare sull'oggetto da verificare: i simboli sono preceduti dal segno +, o dal segno -, a seconda che si voglia includere o escludere quell'analisi particolare.

Solitamente vengono posti inizialmente i simboli da includere, tutti assieme, dopo un segno +, e quindi quelli da escludere, dopo un unico segno -, come nel caso di +pinugsm12-ac3456789. La tabella 186.2 elenca questi simboli.

Simbolo Descrizione
p Verifica dei bit dei permessi.
i Verifica del numero di inode.
n Numero di collegamenti fisici.
u Utente proprietario.
g Gruppo proprietario.
s Dimensione.
a Data-orario dell'ultimo accesso.
m Data-orario dell'ultima modifica.
c Data-orario della creazione/modifica dell'inode.
0 Firma nulla.
1 MD5, RSA Data Security, Inc. Message Digesting Algorithm.
2 Snefru, Xerox Secure Hash Function.
3 CRC-32, POSIX 1003.2.
4 CRC-16
5 MD4, RSA Data Security, Inc. Message Digesting Algorithm.
6 MD2, RSA Data Security, Inc. Message Digesting Algorithm.
7 SHA, NIST Secure Hash Algorithm (NIST FIPS 180).
8 Haval (128-bit).
9 Firma nulla (riservato per uso futuro).

Tabella 186.2: Elenco dei parametri di selezione.

I parametri di selezione riassuntivi, sono identificati attraverso una sola lettera maiuscola, e non sono preceduti dal segno + o -. Possono essere usati da soli, o al massimo seguiti da una serie di parametri di selezione che ne modificano l'effetto. La tabella 186.3 elenca questi simboli.

Simbolo Descrizione
R Sola lettura (+pinugsm12-ac3456789), predefinito.
L File delle registrazioni (+pinug-samc123456789).
N Verifica tutto (+pinugsamc123456789).
E Ignora tutto (-pinugsamc123456789).
> Incremento monotonico (+pinug>-samc123456789).

Tabella 186.3: Elenco dei parametri di selezione riassuntivi.

Esempi

/etc +pinugsm12-ac3456789

Verifica la directory /etc/ e tutto il suo contenuto in modo ricorsivo, verificando: i bit dei permessi, i numeri di inode, i riferimenti agli inode, i numeri UID e GID, le date di modifica, e la firma in base al tipo MD5 e Snefru. Viene ignorata la data di accesso, la data di creazione dell'inode, e tutti gli altri tipi di firma.

/etc R

Esattamente come nell'esempio precedente, dal momento che il parametro riassuntivo R rappresenta le stesse cose.

/etc

Esattamente come nell'esempio precedente, dal momento che il parametro riassuntivo R è quello predefinito.

/home/pippo E+ug

Verifica esclusivamente la proprietà dei file (utente e gruppo), come eccezione del parametro riassuntivo E, che da solo escluderebbe tutti i controlli.

/home/pippo E

Esclude tutti i controlli, ma continua a verificare l'aggiunta o la cancellazione di file.

!/home/pippo

Esclude qualunque verifica, ignorando anche l'aggiunta o la cancellazione di file.

=/tmp

Verifica esclusivamente la directory /tmp/, senza analizzarne il contenuto.

186.4.2 # tripwire

tripwire [<opzioni>]

tripwire è l'eseguibile che svolge il compito di scansione e verifica dell'integrità dei file e delle directory specificati nel file di configurazione. Si distinguono tre situazioni: la creazione del file contenente le informazioni sulla situazione attuale di ciò che si vuole tenere sotto controllo; l'aggiornamento di queste informazioni in presenza di modifiche volontarie da parte dell'amministratore; la verifica di integrità, cioè il confronto di queste informazioni con la situazione attuale.

A seconda di come viene compilato il programma, si stabilisce la collocazione predefinita e il nome del file di configurazione e del file di registrazione delle informazioni. In generale, conviene utilizzare le opzioni necessarie a specificare tali file.

Alcune opzioni

Se non vengono utilizzate le opzioni -initialize e -update, tripwire si mette automaticamente a verificare l'integrità dei file secondo le informazioni accumulate in precedenza.

-initialize

Genera il file delle informazioni da conservare, in base alle specifiche della configurazione.

-update <percorso-completo>

Aggiorna le informazioni già esistenti per quanto riguarda la directory o il file indicato come argomento.

-interactive

Inizia la verifica dell'integrità dei file secondo le informazioni accumulate in precedenza e chiede all'utente la conferma o meno della modifica di queste in modo conforme alla nuova situazione trovata.

-loosedir

Può essere utilizzato in fase di verifica per annullare il controllo delle directory, pur mantenendo il controllo del loro contenuto, se questo è indicato nella configurazione. Ciò serve per ridurre la quantità di segnalazioni che si presentano, quando questo può generare solo confusione. In generale, il rischio di perdere informazioni importanti aumenta, ma alle volte l'eccesso può essere dannoso.

-d <file>

In fase di verifica dell'integrità dei dati, permette di specificare il file contenente le informazioni raccolte in precedenza. Si può utilizzare un trattino singolo - per fare riferimento allo standard input.

-c <file-di-configurazione>

Permette di specificare il file di configurazione, sia in fase di generazione e aggiornamento delle informazioni da conservare, sia in fase di verifica. Si può utilizzare un trattino singolo - per fare riferimento allo standard input.

-v

Emette l'elenco dei nomi di file nel momento in cui avviene la scansione.

Esempi

tripwire -initialize -c /root/tw.config

Genera il file di raccolta delle informazioni, utilizzando un nome predefinito in base alla compilazione dei sorgenti, e collocandolo probabilmente nella directory ./databases/ (cioè a partire dalla directory corrente nel momento dell'avvio del programma). Il file di configurazione utilizzato è /root/tw.config.

tripwire -update /etc -c /root/tw.config

Aggiorna il file di raccolta delle informazioni (si fa sempre riferimento al nome predefinito in base alla compilazione dei sorgenti, e collocato probabilmente nella directory ./databases/) per le variazioni fatte nella directory /etc/. Il file di configurazione utilizzato è /root/tw.config.

tripwire -interactive -c /root/tw.config -d /root/tw.db

Esegue una verifica di integrità interattiva, utilizzando il file di configurazione /root/tw.config e il file /root/tw.db per il confronto rispetto alla situazione attuale.

tripwire -interactive -c /root/tw.config -d - < /mnt/floppy/tw.db

Esegue una verifica di integrità interattiva, utilizzando il file di configurazione /root/tw.config e il file /mnt/floppy/tw.db (che probabilmente si trova in un dischetto protetto contro la scrittura) per il confronto rispetto alla situazione attuale.

186.4.3 Configurazione e utilizzo in pratica

Per poter usare Tripwire in modo utile, la prima cosa da fare è studiare la sua configurazione, tenendo conto delle peculiarità del filesystem. Volendo un controllo generalizzato, bisogna però tenere conto delle aree in cui i dati cambiano continuamente per motivi fisiologici. Quello che segue è un esempio, un po' approssimativo, di una configurazione funzionante, anche se un po' blanda.

# Include il controllo di tutto il filesystem.
/ +pinugsm14-ac2356789

# Esclude i file di dispositivo
!/dev

# Esclude alcuni file dinamici nella directory /etc/.
!/etc/issue
!/etc/issue.net
!/etc/ioctl.save
!/etc/mtab
!/etc/ntp.drift
!/etc/ld.so.cache
!/etc/snmpd.agentinfo
!/etc/ssh_random_seed
!/etc/mail/sendmail.st

# Esclude le directory personali.
!/home

# Esclude i file riferiti ai moduli che vengono aggiornati a ogni
# avvio del sistema.
!/lib/modules/preferred
!/lib/modules/2.0.34-1/modules.dep

# Esclude la directory /proc/.
!/proc

# Esclude la directory /root/, ma poi aggiunge qualcosa che è
# comunque opportuno controllare.
!/root
/root/bin
/root/.ssh

# Esclude la directory temporanea.
!/tmp

# Esclude i file whatis.
!/usr/X11R6/man/whatis
!/usr/lib/perl5/man/whatis
!/usr/local/man/whatis
!/usr/man/whatis

# Esclude la directory /var/.
!/var

Di sicuro, si potrebbe fare meglio, studiando in modo più dettagliato ogni directory e file del filesystem da controllare.

Quando si utilizza Tripwire per difendersi da una possibile intrusione nel sistema, è necessario nascondere il file di configurazione, anche se non sempre è facile farlo. Di certo, un modo è quello di conservarlo in un dischetto. Anche il file di registrazione delle informazioni dovrebbe essere archiviato in un posto sicuro e inaccessibile agli «intrusi», e ancora, il dischetto è l'unica possibilità concreta che hanno tutti.

A titolo di esempio si suppone di avere collocato il binario tripwire e il file di configurazione tw.config nella directory /root/adm/tripwire/.

cd /root/adm/tripwire[Invio]

./tripwire -initialize -c ./tw.config[Invio]

### Phase 1:   Reading configuration file
### Phase 2:   Generating file list
### Phase 3:   Creating file information database
###
### Warning:   Database file placed in ./databases/tw.db_dinkel.brot.dg.
###
###            Make sure to move this file and the configuration
###            to secure media!
###
###            (Tripwire expects to find it in '/var/adm/tripwire/db'.)

Come si può osservare dal messaggio che si ottiene, è stato creato il file ./databases/tw.db_dinkel.brot.dg contenente le informazioni raccolte, dove la parte finale del nome del file (dinkel.brot.dg) è il nome del nodo. Nel messaggio stesso, viene ricordato di spostare sia il file di configurazione che il file di registrazione delle informazioni (viene chiamato database) in un'unità «sicura». Per esempio, si potrebbe comprimere questo file per poterlo contenere in un dischetto, come nell'esempio seguente:

gzip ./databases/tw.db_dinkel.brot.dg[Invio]

mount /mnt/floppy[Invio]

cp ./databases/tw.db_dinkel.brot.dg.gz /mnt/floppy[Invio]

rm ./databases/tw.db_dinkel.brot.dg.gz[Invio]

cp ./tw.config /mnt/floppy[Invio]

rm ./tw.config[Invio]

umount /mnt/floppy[Invio]

L'esempio è soltanto esplicativo. Il dischetto non è un supporto tecnicamente affidabile, di conseguenza occorre conservare in qualche modo migliore almeno il file di configurazione.

Nel momento del controllo, si può rimontare il dischetto ed eseguire una scansione di controllo.

mount /mnt/floppy[Invio]

gzip -d < /mnt/floppy/tw.db_dinkel.brot.dg.gz | tripwire -c /mnt/floppy/tw.config -d -[Invio]

### Phase 1:   Reading configuration file
### Phase 2:   Generating file list
### Phase 3:   Creating file information database
### Phase 4:   Searching for inconsistencies
###
###			Total files scanned:		10650
###			      Files added:		0
###			      Files deleted:		0
###			      Files changed:		10650
###
###			After applying rules:
###			      Changes discarded:	10649
###			      Changes remaining:	2
###
changed: drwxr-xr-x root         3072 Sep 29 12:17:45 1998 /etc
changed: -rw-r--r-- root           62 Sep 29 12:17:45 1998 /etc/exports
### Phase 5:   Generating observed/expected pairs for changed files
###
### Attr        Observed (what it is)	      Expected (what it should be)
### =========== ============================= =============================
/etc
      st_mtime: Tue Sep 29 12:17:45 1998      Tue Sep 29 12:13:30 1998      

/etc/exports
        st_ino: 4100                          4150                          
       st_size: 62                            22                            
      st_mtime: Tue Sep 29 12:17:45 1998      Tue Sep 29 12:13:30 1998      
    md5 (sig1): 3TsxXpVgza:NQutDYSbVIm        1QLSacLNpOIOF6iUqeUo.m        
  crc16 (sig4): 0008f5                        0007e.                        

L'esempio mostra che dal controllo di integrità risulta variato il file /etc/exports: il numero di inode è cambiato, e così anche la data di modifica, la dimensione è aumentata e le firme utilizzate (MD5 e CRC-16) sono ovviamente differenti. Anche la directory /etc/ risulta modificata, ma questo sembra essere solo una conseguenza dell'alterazione di questo file.

186.4.4 Uso delle firme

La firma, utilizzando uno o più dei vari metodi elencati nella descrizione della configurazione di Tripwire, serve a verificare che il file o la directory siano sempre gli stessi. La scelta della complessità della firma dipende dalla gravità o meno del problema che ha la sicurezza nel contesto per il quale si utilizza. Di solito ne vengono usate almeno due, e se ci si accontenta, si possono usare anche firme piuttosto piccole e semplici. La scelta di firme elementari, riduce il livello di sicurezza, ma anche il peso dell'elaborazione necessaria.

186.5 SATAN o SANTA

SATAN (Security Administration Tool for Analyzing Networks, ovvero SANTA, per chi lo preferisce), è un applicativo in grado di scandagliare uno o più elaboratori connessi in rete allo scopo di verificarne le debolezze. Per sua natura, si tratta di uno strumento di aggressione, ma il suo scopo è quello di aiutare gli amministratori a eliminare gli errori comuni di configurazione e a scoprire difetti conosciuti di programmi determinati.

In qualità di strumento di aggressione, SATAN non può essere usato contro sistemi al di fuori della propria amministrazione o per i quali non si è ottenuta l'autorizzazione a farlo. L'utilizzo di SATAN produce normalmente delle tracce nel registro del sistema del nodo analizzato, e queste azioni possono essere considerate un'attività ostile e scatenare la reazione degli amministratori rispettivi.

A parte queste considerazioni, il difetto maggiore di SATAN è quello di essere un lavoro piuttosto vecchio, e di conseguenza obsoleto. In pratica, potrebbe non essere aggiornato su delle nuove tecniche di attacco per le quali si vorrebbe poter verificare la solidità dei propri sistemi. Quindi, SATAN va bene come verifica di massima, e questo aiuto non è trascurabile.

SATAN è un pacchetto applicativo composto da una serie di eseguibili binari, ognuno specifico per un tipo di verifica, una serie di programmi Perl e una serie di moduli HTML. In teoria si potrebbe usare SATAN esclusivamente attraverso un programma per la navigazione, ma per ottenere questo si va incontro a una serie di complicazioni che forse non è il caso di affrontare, per il semplice fatto che non ne vale la pena, e il risultato pratico non cambia. In queste sezioni verrà mostrato come utilizzare SATAN specificando quanto serve per avviare la scansione attraverso la riga di comando, e come analizzare il risultato ottenuto attraverso un navigatore web.

186.5.1 Preparazione

SATAN non viene distribuito in forma già compilata. Si tratta di un pacchetto rivolto a persone esperte, e reperire SATAN in forma già compilata e pronta da installare, è solo un sintomo sospetto di una possibile manomissione.

La versione originale di SATAN potrebbe offrire delle difficoltà impreviste alla compilazione nei sistemi GNU/Linux. A questo proposito esistono delle versioni accompagnate da file di differenze appositi (patch), che risolvono i problemi. A titolo di esempio si suppone di avere ritrovato il pacchetto satan-1.1.1.linux-3.src.rpm. Chi dovesse preferire un pacchetto analogo per la distribuzione Debian, dovrebbe agire in modo simile a quanto mostrato qui, tenendo conto del funzionamento di dpkg.

SATAN è un pacchetto particolare, e la sua destinazione predefinita nel filesystem è al di fuori delle collocazioni normali. Dovendo essere uno strumento esclusivamente nelle mani dell'amministratore, la sua collocazione più conveniente dovrebbe essere /root/satan/. La ricompilazione del pacchetto potrebbe non giungere alla collocazione definitiva dei file, lasciando l'amministratore libero di scegliere.

cd /tmp

rpm --recompile /usr/src/redhat/SRPMS/satan-1.1.1.linux-3.src.rpm

Al termine della compilazione, SATAN potrebbe essere stato collocato nella sua destinazione finale predefinita, oppure in una directory transitoria, a partire da quella corrente. Nel caso particolare del pacchetto indicato come esempio, SATAN si trova collocato sotto ./satantmp/root/satan/. Il tutto viene spostato nella directory /root/.

mv ./satantmp/root/satan /root

186.5.1.1 Navigatore web

Il programma satan che è scritto in Perl, se viene utilizzato senza argomenti avvia un navigatore; precisamente avvia quanto determinato in fase di configurazione prima della compilazione dei sorgenti. Se è stato installato Netscape, sarà questo il navigatore predefinito, ma Netscape può creare qualche problema, a causa delle particolarità dell'organizzazione di SATAN.

Lynx sarebbe più che sufficiente per il lavoro che si vuole fare con SATAN, e a tale proposito, conviene modificare il file /root/satan/config/paths.pl.

$MOSAIC="/usr/bin/netscape";

La riga mostrata va modificata come nel modo seguente:

$MOSAIC="/usr/bin/lynx";

186.5.1.2 Perl

SATAN dipende dall'interprete Perl, che quindi deve essere installato. Se per qualche motivo non si riesce ad avviare i programmi Perl, conviene controllare l'intestazione ed eventualmente provvedere a rendere disponibili i collegamenti necessari. In generale, questo problema non dovrebbe esistere, dal momento che in fase di compilazione dei sorgenti vengono modificate queste intestazioni in modo da puntare all'interprete Perl installato effettivamente.

Un altro problema che può essere generato da questi programmi Perl è la configurazione delle variabili per la localizzazione: LANG e la serie LC_*. Se la loro configurazione non è corretta in base all'impostazione del proprio sistema, Perl mostra una segnalazione di errore per ogni programma avviato, attraverso lo standard error.

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LC_ALL = "mia_locale",
	LANG = "it_IT.ISO-8859-1"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

Nell'esempio si mostra che Perl ha scoperto una definizione impropria della variabile LC_ALL, dal momento che non esiste il tipo di localizzazione mia_locale.

Per risolvere il problema, se non si trova la definizione giusta per la localizzazione, conviene eliminare la configurazione del variabili di localizzazione, oppure impostare LC_ALL al valore C.

export LC_ALL=C

186.5.2 Configurazione

La configurazione di SATAN è contenuta in alcuni file collocati nella directory satan/config/.

Tra tutti questi file, merita attenzione satan/config/satan.cf. Dalla sua corretta configurazione dipende il buon funzionamento di SATAN. Si tratta di un pezzo di file Perl, all'interno del quale si annotano una serie di assegnamenti a variabili di vario tipo (scalari, array, hash), secondo le regole di Perl. Di seguito vengono indicate alcune direttive più importanti.

# Where do we keep the data? This is just a default.
$satan_data = "satan-data";

La variabile $satan_data permette di definire il nome della directory all'interno della quale inserire i file contenenti il rapporto delle scansioni fatte da SATAN. Questa directory discenderà da satan/results/, e solitamente, come mostra l'esempio, si tratta di satan/results/satan-data/.

# Default attack level (0=light, 1=normal, 2=heavy).
$attack_level = 2;

Il livello dell'attacco, definito attraverso la variabile $attack_level, permette di specificare tre valori, da 0 a 2. L'attacco più pesante è rappresentato dal numero 2.

# status file; keeps track of what SATAN is doing.
$status_file = "status_file";

SATAN accumula la registrazione sommaria delle operazioni compiute all'interno di un file. Generalmente si tratta di satan/status_file, come mostra l'esempio in cui si definisce la variabile omonima.

# How far out from the original target do we attack? Zero means that we only
# look at the hosts or network that you specify. One means look at neighboring
# hosts, too. Anything over two is asking for problems, unless you are on the
# inside of a firewall.
$max_proximity_level = 1;

La variabile $max_proximity_level permette di definire il cosiddetto livello di prossimità, cioè quali nodi scandire. In pratica, 0 significa limitare la scansione all'unico nodo indicato come punto di inizio, ed è la scelta migliore fino a quando non si conosce l'uso di SATAN; 1 indica a SATAN di provare tutti i nodi vicini. Usando un valore superiore a 2, si inizia in pratica una scansione su tutto ciò che è raggiungibile attraverso la rete (cosa da evitare).

# Attack level drops by this much each proximity level change
$proximity_descent = 1;

Per evitare la proliferazione degli attacchi, si può stabilire la riduzione del livello dell'attacco, ogni volta che si passa a uno strato più esterno di nodi, cioè ogni volta che si attraversa un livello di prossimità.

# when we go below zero attack, do we stop (0) or go on (1)?
$sub_zero_proximity = 0;

Attraverso la variabile $sub_zero_proximity è possibile dire a SATAN cosa fare quando il livello di attacco è arrivato sotto il numero zero. Assegnando 0 si intende concludere la scansione; assegnando 1 si intende proseguire fino all'esaurimento degli strati di prossimità.

# a question; do we attack subnets when we nuke a target?
# 0 = no; 1 = primary target subnet
$attack_proximate_subnets = 0;

È possibile dire a SATAN di attaccare l'intera sottorete di un nodo individuato. Generalmente, non si utilizza questa possibilità, a meno che si stia tentando di individuare un possibile elaboratore collocato nella propria rete locale senza permesso. Assegnando il valore 1 alla variabile $attack_proximate_subnets si ottiene l'attacco alla sottorete.

# Does SATAN run on an untrusted host? (0=no; 1=yes, this host may appear
# in the rhosts, hosts.equiv or NFS export files of hosts that are being
# probed).
#
$untrusted_host = 1;

Attraverso questa variabile, è possibile richiedere a SATAN una verifica della «fiducia» accordata al sistema locale presso quelli che vengono scandagliati. In pratica, se si assegna 1 alla variabile $untrusted_host, SATAN tenta di accedere attraverso rsh presso i nodi da verificare, e tenta anche di eseguire il montaggio se questi offrono l'esportazione NFS.

# If $only_attack_these is non-null, *only* hit sites if they are of this
# type.  You can specify a domain (podunk.edu) or network number
# (192.9.9). You can specify a list of shell-like patterns with domains
# or networks, separated by whitespace or commas.
$only_attack_these = "brot.dg, 192.168";

Per evitare di sconfinare oltre la propria sottorete o il proprio dominio, è possibile utilizzare la variabile $only_attack_these, a cui assegnare una stringa contenente un elenco di domini e di indirizzi IP parziali, come si vede nell'esempio.

# Stay away from anyone that matches these patterns.
#
$dont_attack_these = "gov, mil";

Nello stesso modo, è possibile evitare esplicitamente domini e indirizzi IP, attraverso l'uso della variabile $dont_attack_these. Nell'esempio si vogliono evitare i domini gov e mil.

# Set the following to nonzero if DNS (internet name service) is unavailable.
#
$dont_use_nslookup = 0;

Per SATAN è importante che il servizio DNS sia disponibile. Se non è così, si deve assegnare il valore 1 alla variabile $dont_use_nslookup.

# Should SATAN ping hosts to see if they are alive?
#
$dont_use_ping = 0;

SATAN utilizza ping per verificare la presenza dei nodi. Nel caso si volesse evitare il suo utilizzo, si può assegnare il valore 1 alla variabile $dont_use_ping.

Il file di configurazione termina con la riga seguente. Si tratta di qualcosa che riguarda Perl, e non deve essere cambiato.

1;

186.5.3 # satan

satan [<opzioni>] [<obbiettivo-primario>]

satan è il programma Perl che si utilizza per la scansione dei nodi da verificare, e anche per avviare l'interfaccia HTML, attraverso un navigatore come definito attraverso la variabile $MOSAIC nel file satan/config/paths.pl.

Se satan viene avviato con l'indicazione di un nodo da controllare (attaccare), inizia l'operazione in base alla configurazione contenuta nel file satan/config/satan.cf, con le varianti apportate attraverso le opzioni della riga di comando. Ciò che si ottiene alla fine dell'elaborazione è l'aggiornamento dei file contenuti a partire dalla directory satan/results/. Per la lettura dei risultati, si utilizza normalmente il sistema HTML, avviato attraverso satan senza argomenti.

Per utilizzare satan, non occorre sistemare la variabile di ambiente PATH. Tuttavia, è necessario che la directory corrente corrisponda alla posizione iniziale del pacchetto. Per esempio, se il tutto si trova a partire da /root/satan/, occorrerà che questa sia la directory corrente prima dell'avvio del programma.

Alcune opzioni

-a {0|1|2}

Permette di ridefinire il livello di attacco: 0 è il minimo, 2 è il massimo.

-l {0|1|2}

Definisce il livello di prossimità: 0 rappresenta solo il nodo di partenza; 1 i nodi prossimi. Non è conveniente usare un valore superiore a 2, perché questo rappresenta implicitamente qualunque nodo raggiungibile.

-s

Allargamento alla sottorete: con questa opzione, ogni volta che si individua un nodo si allarga la ricerca anche a tutta la sottorete (l'ultimo ottetto dell'indirizzo IP).

-v

Visualizza le azioni compiute da satan durante la sua scansione.

Esempi

./satan roggen.brot.dg

Inizia la verifica del nodo roggen.brot.dg in base alla configurazione stabilita nel file satan/config/satan.cf.

./satan -s roggen.brot.dg

Come nell'esempio precedente, espandendo la scansione a tutta la sottorete a cui appartiene il nodo indicato.

./satan

Avvia il navigatore con l'interfaccia HTML.

186.5.4 Verifica del risultato

Il risultato dell'elaborazione (degli attacchi) di SATAN viene memorizzato all'interno di file collocati a partire dalla directory satan/results/. Si tratta di file di testo che potrebbero essere interpretati così come sono, con qualche piccola difficoltà.

In alternativa, si può usare convenientemente un navigatore, avviato tramite l'eseguibile satan. La figura 186.2 mostra il menu principale che si ottiene all'inizio.

                          SATAN Control Panel
                                       
          (Security Administrator Tool for Analyzing Networks)
   
   * SATAN Data Management
   * SATAN Target selection
   * SATAN Reporting & Data Analysis
   * SATAN Configuration Management
   * SATAN Documentation
   * SATAN Troubleshooting
   
   * Getting the Latest version of SATAN
   * Couldn't you call it something other than "SATAN"?
   * 'Bout the SATAN image
   * 'Bout the authors

Figura 186.2: Il menu principale che si ottiene quando l'eseguibile satan viene avviato in modo da utilizzare il navigatore.

Dal menù principale, si seleziona normalmente il riferimento Reporting & Data Analysis, per visualizzare il rapporto sulla scansione eseguita. Si ottiene un altro menu, con il quale selezionare il tipo di informazione desiderata.

                     SATAN Reporting and Analysis

   Vulnerabilities 
     * By Approximate Danger Level 
     * By Type of Vulnerability 
     * By Vulnerability Count 
       
   Host Information 
     * By Class of Service
     * By System Type
     * By Internet Domain
     * By Subnet
     * By Host Name
       
   Trust
     * Trusted Hosts
     * Trusting Hosts

Figura 186.3: Il menu che permette di accedere alle informazioni accumulate.

A titolo di esempio, la figura 186.4 mostra il responso di una scansione che ha rivelato alcuni elementi di vulnerabilità. In corrispondenza di ognuna delle due voci si trova un riferimento che porta a delle spiegazioni più dettagliate.

                      Vulnerabilities - By Type
   
  Number of hosts per vulnerability type.
  
     * unrestricted NFS export - 1 host(s)
     * remote shell access - 1 host(s)
       
   Note: hosts may appear in multiple categories. 

Figura 186.4: Esempio del responso di vulnerabilità di un nodo, distinto in base al tipo.

---------------------------

Appunti Linux 1999.09.21 --- Copyright © 1997-1999 Daniele Giacomini --  daniele @ pluto.linux.it


1.) Se la propria distribuzione GNU/Linux distingue un pacchetto specifico per il demone identd, questo potrebbe chiamarsi Pidentd. In altri casi, potrebbe far parte del pacchetto di base per la gestione dei servizi di rete.


[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]