netcat
netcat oppure, più brevemente, nc è uno strumento a linea di comando piuttosto utile e semplice, una sorta di telnet, ma con funzionalità avanzate. Viene, generalmente, usato per il debug e l'analisi delle reti, ma serve anche per creare ed usare connessioni TCP e UDP. Il suo punto di forza è nella scrittura di script per lavorare con socket TCP e UDP.
In questi appunti passeremo in rassegna alcuni tipici esempi pratici e scopriremo che si tratta di una specie di coltellino svizzero per le reti.
1 - Emulazione telnet
Una delle funzioni più semplici di netcat è quella di essere usato come telnet, digitando ad esempio il comando:
$ nc -v www.google.it 80
si ottiene una risposta del tipo:
DNS fwd/rev ....... ....... .net www.google.it [216.58.210.195] 80 (http) open
netcat è ora collegato alla porta 80 di www.google.it ed, a questo punto, è possibile interagire con la connessione richiedendo, ad esempio, la pagina index.html.
E' sufficiente scrivere:
GET index.html HTTP/1.1
oppure
GET / HTTP/1.1
e premere 2 volte enter, per avere una risposta del tipo:
HTTP/1.1 302 Found Cache-Control: private Content-Type: text/html; charset=UTF-8 Location: http://www.google.it/?gfe_rd=cr&ei=Dub5VLOlK6is8wfChoK4Dw Content-Length: 258 Date: Fri, 06 Mar 2015 17:38:22 GMT Server: GFE/2.0 Alternate-Protocol: 80:quic,p=0.08 <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>302 Moved</TITLE></HEAD><BODY> <H1>302 Moved</H1> The document has moved <A HREF="http://www.google.it/?gfe_rd=cr&ei=Dub5VLOlK6is8wfChoK4Dw">here</A>. </BODY></HTML>
L'output di google.it è stato ricevuto e mostrato a terminale.
Nota
L'opzione -v (verbose) consente di avere delle informazioni in risposta all'esecuzione del comando. Quando previsto, queste informazioni possono essere ancora più dettagliate scrivendo -vv.
2 - Attivazione socket
Per aprire un socket (ovvero una connessione) è sufficiente usare netcat in questo modo:
$ nc -v -l -p 5000
ottenendo in risposta:
listening on [any] 5000 ...
in questo caso netcat è in ascolto sulla porta 5000. L'opzione -v, come abbiamo già visto, mostra dati utili alla comprensione dell'output, l'opzione -l (listen) richiede la modalità ascolto, l'opzione -p (port) serve a specificare il numero di porta, nel nostro caso 5000.
E' utile ricordare che le porte sotto la 1024 sono riservate al sistema, e solo root può aprire un socket con questi indirizzi.
Aprendo un altro terminale possiamo verificare se la porta 5000 sia effettivamente aperta:
$ telnet localhost 5000
produrrà 2 risposte, una sul primo terminale (server):
connect to [127.0.0.1] from localhost [127.0.0.1] 39304
ed una sul secondo terminale (client):
Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'.
Questo messaggio indica che la porta è aperta. Adesso il funzionamento dei 2 terminali è assimilabile ad una semplicissima chat, quanto viene scritto su uno dei 2 terminali viene rimandato in eco sull'altro terminale.
Per disattivare la comunicazione occorre digitare Ctrl-C sul terminale server.
Possiamo replicare l'esperimento precedente della chat utilizzando anche il protocollo UDP, creando con netcat sia il terminale server:
$ nc -v -u -l -p 5000
sia il terminale client:
$ nc -u localhost 5000
Per usare il protocollo UDP è stato sufficiente inserire l'opzione -u sia nel comando server sia nel comando client.
3 - Trasferimento file
Supponiamo di avere un file di testo prova.txt che vogliamo trasferire al primo client che si connette.
Cominciamo con il verificare il contenuto del file con il comando:
$ cat prova.txt
produrrà sul display:
File di prova per trasferimento con netcat.
A questo punto tramite un pipe ('|') possiamo reindirizzare il contenuto del file, anzichè sul display, sulla rete tramite il comando:
$ cat prova.txt | nc -v -l -p 5000
ottenendo in risposta:
listening on [any] 5000 ...
Apriamo un secondo terminale e digitiamo il comando:
$ nc localhost 5000
otterremo in risposta sul secondo terminale (client):
File di prova per trasferimento con netcat.
e sul primo terminale (server):
connect to [127.0.0.1] from localhost [127.0.0.1] 39437
ncat invierà il file solo al primo client che si connetterà . Successivamente, come si potrà constatare, interromperà la connessione.
La situazione può essere invertita, nel senso che possiamo porre il server in attesa di un file che verrà , invece, spedito dal client.
Per il terminale server agiamo in questo modo:
$ nc -v -l -p 1234 > file.txt
ottenendo in risposta:
listening on [any] 1234 ...
Apriamo un secondo terminale, in funzione di client, e digitiamo il comando:
$ cat prova.txt | nc localhost 1234
ottenendo in risposta sul server:
connect to [127.0.0.1] from localhost [127.0.0.1] 41882
Dopo aver chiuso il server con Ctrl-C, eseguiamo sull'ex terminale server il comando:
$ cat file.txt
otterremo in risposta:
File di prova per trasferimento con netcat.
che conferma l'avvenuto trasferimento di prova.txt dal lato client in file.txt sul lato server.
4 - Opzione timeout
Ci sono delle situazioni in cui non vogliamo che una connessione rimanga aperta continuamente, in tali casi tramite l'opzione -w possiamo specificare il timeout (scadenza) di una connessione. Con l'opzione -w si può specificare dopo quanti secondi la connessione client si disconnetterà dal server.
Avviato il server:
$ nc -v -l -p 1234
Se attiviamo il client con il comando:
$ nc -w 15 localhost 1234
la connessione client si interromperà dopo 15 secondi.
Nota
L'opzione -w non ha efficacia se utilizzata per avviare un server, in quanto quest'ultimo rimmarrà sempre attivo fino a quando non verrà spento intenzionalmente o chiudendo il terminale o con la combinazione di tasti Ctrl-C.
5 - Scansione delle porte
Tra le tante cose, netcat ha la potenzialità di essere usato per effettuare la scansione delle porte. Teniamo, tuttavia, presente che ci sono appositi strumenti (nmap) progettati per questo genere di lavoro.
Un tipico comando per la scansione di un intervallo di porte potrebbe essere il seguente:
$ nc -v -n -z -w 1 192.168.1.1 10-700
dove l'opzione -n indica che l'indirizzo IP verrà indicato esclusivamente in modo numerico (no DNS), l'opzione -z fa in modo che non vengano inviate risposte dal server (zero-I/O mode), l'opzione -w 1 indica un timeout di 1 secondo (utile quando il sistema remoto ha un firewall), il parametro 10-700 indica l'intervallo delle porte scansionate all'indirizzo specificato.
Un possibile output potrebbe essere il seguente:
(UNKNOWN) [192.168.1.1] 631 (ipp) open (UNKNOWN) [192.168.1.1] 445 (microsoft-ds) open (UNKNOWN) [192.168.1.1] 443 (https) open (UNKNOWN) [192.168.1.1] 139 (netbios-ssn) open (UNKNOWN) [192.168.1.1] 80 (http) open
Per effettuare una semplice scansione di una porta UDP, ovvero se si vuole sapere se una porta UDP è aperta è sufficiente digitare un comando con questa forma:
nc -z -u ip porta
6 - Supporto a IPV6
Le versioni più recenti di netcat hanno il supporto per gestire anche gli indirizzi IP v6. Per eseguire i comandi seguenti, verificare se il proprio gestore di pacchetti dispone di una versione abilitata agli indirizzi IP v6. Nella schermata di help (nc -h) devono essere presenti le opzioni -4 e -6.
Recognized options are: -4 Use only IPv4 -6 Use only IPv6 -b, --bluetooth Use Bluetooth (defaults to L2CAP protocol) .........
Nota
Nel sistema usato per queste prove si trova installata la versione standard per ipv4, quindi, per potere svolgere gli esercizi di questo paragrafo, è stato momentaneamente installato il pacchetto netcat6. Il comportamento predefinito di netcat6 è, comunque, con indirizzi ipv4.
Per sperimentare un poco, attiviamo su 2 terminali diversi un server ed un client:
$ nc -v -4 -l -p 1234
$ nc -v -4 localhost 1234
Quindi su un terzo terminale, con lo scopo di vedere la situazione della porta 1234, eseguiamo il comando:
$ netstat | grep 1234
il cui output a video sarà :
tcp 0 0 localhost:59298 localhost:1234 ESTABLISHED tcp 0 0 localhost:1234 localhost:59298 ESTABLISHED
Ripetiamo lo stesso esercizio con l'opzione -6, avremo:
$ nc -v -6 -l -p 1234
$ nc -v -6 localhost 1234
$ netstat | grep 1234
tcp6 0 0 localhost:1234 localhost:58606 ESTABLISHED tcp6 0 0 localhost:58606 localhost:1234 ESTABLISHED
Come si può vedere, il comando netstat evidenzia, in questo caso, la presenza degli indirizzi ipv6 con l'indicatore tcp6 anzichè tcp.
Maxima debetur puero reverentia. (Al bambino è dovuto il massimo rispetto.)
Giovenale