Uso avanzato di NetCat
by admin on Mar.28, 2009, under Hacking, Linux, Networking, Tools
Uno dei tools di rete maggiormente celebrati ma normalmente sotto-utilizzati è nc (o netcat). Netcat può creare un socket TCP in modalità listening (server socket) oppurre un socket in grado di connettersi ad un server (client mode).
Ne ho raccolto alcuni esempi per mostrarne la notevole elasticità di utilizzo:
Copia di un File da un Sistema ad un altro
Supponiamo di voler copiare il file config.tar.gz da host_1 a host_2.
Per farlo potremmo per esempio impartire
su host_2 (server):
# nc -lp 3434 > config.tar.gz
host_2 diviene in tal modo disponibile ad accettare il file sulla porta 3434 (3434 si riferisce ad una porta non in uso ed è quindi sostituibile con un qualsiasi altro valore).
su host_1 (client):
# nc -w 1 host_2 3434 < config.tar.gz
e avviare così il trasferimento.
Un modo alternativo di effettuare lo stesso trasferimento può essere poi:
su host_1 (server):
# cat config.tar.gz | nc -lp 3434 -q 1
su host_2 (client):
# nc host_1 3434 > config.tar.gz
Utilizzare netcat nel modo appena descritto implica che i dati traversino la rete in chiaro. Questo può essere accettabile nel caso di una rete locale, ma, nel caso di un attraversamento in internet, è sicuramente preferibile un tunnel SSH:
- I dati vengono trasferiti attraverso un tunnel criptato, e la loro riservatezza è ben protetta.
- Non vi è alcuna necessità di tenere aperta alcuna porta nel firewall per la macchina che fa da server, se non l’usuale SSH.
Il file viene incanalato a un socket in ascolto sulla macchina server esattamente come in precedenza. Si assume che un server SSH sia pure in esecuzione su questa macchina.
$ cat config.tar.gz | nc -lp 3434 -q 1
E sulla macchina client connettersi al socket in ascolto attraverso un tunnel SSH:
$ ssh -R 23333:host1:3434 root@host1 nc 127.0.0.1 23333 > config.tar.gz
Questo modo di creare ed utilizzare il tunnel SSH presenta il vantaggio che il tunnel viene automagicamente chiuso al termine del trasferimento.
Redirezione
netcat è in grado di operare perfettamente *sotto* inetd come redirector di un connessione TCP per richieste di servizio in ingresso. Questo risulta molto utile per cose come la redirezione del traffico verso nodi esterni. Basta mettere netcat dietro inetd e tcp_wrappers, tipicamente:
www stream tcp nowait nobody /etc/tcpd /bin/nc -w 3 realwww 80
in inetd.conf e si sarà ottenuto un semplice ed efficace “application relay” con controllo d’ accesso e logging. Si noti l’ uso del parametro wait time come accorgimento per evitare che l’inoltro si blocchi nel caso in cui realwww non risulti raggiungibile oppure l’utente che ha fatto la richiesta abortisca la connessione.
Proxying avanzato
Abbiamo un server netcat in ascolto sulla porta 1111. Potremmo poi impostare un client netcat a raggiungere il web server reale sulla porta 81. Se si passino vicendevolmente tutti i dati che ricevono, insieme formano un proxy; Qualcosa che si pone nel mezzo di una connessione di rete. Questi sono i comandi che useremo:
# mknod backpipe p
# nc -l -p 1111 0<backpipe | tee -a inflow | nc localhost 81 | tee -a outflow 1>backpipe
Siccome le normali pipes bash trasportano i dati in una sola direzione, avremo bisogno di un modo per trasmettere indietro le risposte. Per trasportare i dati nella direzione opposta abbiamo creato una named pipe nel filesystem locale col comando mknod.
Le richieste che giungono al proxy da un qualsiasi client arrivano al primo processo nc, in ascolto sulla porta 1111. Vengono intercettate dal comando “tee”, che le registra nel file inflow, quindi continuano verso il secondo processo nc che le indirizza al reale web server. Quando arriva una risposta dal server, essa torna al secondo processo nc, viene registratata dal secondo comando tee nel file outflow, e poi reindirizzata alla named pipe “backpipe” nel filesystem locale. Dal momento che il primo netcat ha lo standard input rediretto da quella named pipe, le risposte tornano al primo netcat, che poi le inoltra al client originale.
Oltre che agli streams TCP diretti e provenienti da un web server, la tecnica precedente si rivela utile per controllare qualsiasi connessione tcp. Inoltre, dal momento che nc opera anche con pacchetti udp dovrebbe essere possibile impostare in questo modo anche proxies tipo udp.
Clonazione di dischi e partizioni
E’ possibile usare netcat anche per clonare intere partizioni di disco attraverso la rete. In questo esempio, intendo clonare /dev/sda da server1 a server2. Logicamente, per essere clonate, le partizioni devono essere smontate, per cui, dovendo clonare la partizione di sistema, occorre avviare il sistema target (server2) da un Live-CD come Knoppix.
L’indirizzo IP di server2 in questo esempio è 192.168.0.12.
Impartiamo su server2:
# nc -l -p 1234 | dd of=/dev/sda
Quindi, su server1:
# dd if=/dev/sda | nc 192.168.0.12 1234
per avviare il processo di clonazione, che può impiegare un certo tempo, a seconda della dimensione dell’ hard drive o partizione.
Copia remota di una directory:
Ad una estremità:
# tar zcfp - /path/to/directory | nc -w 3 172.16.0.5 1234
Il comando tar prima della pipe archivia e comprime (usando gzip) ogni file presente nella directory indicata, producendo il proprio output su stdout (lo schermo). Viene quindi passato dalla pipe a nc che, in questo esempio, si connette a 172.16.0.5 sulla porta 1234 e gli invia i dati che normalmente raggiungerebbero lo schermo. Lo switch -w 3 fa in modo che nc attenda un timeout di 3 secondi (Nell’eventualità di una temporanea disconnessione).
Dall’altra parte:
# nc -l -p 1234 | tar xvfpz -
Questo fa in modo che nc si ponga in attesa di connessioni sulla porta 1234, e passi ogni dato ricevuto a tar. Utilizzando la opzione - possiamo stampare i filenames dell’archivio a schermo:
Port Scanning
Da server1, si può scandire server2.esempio.it alla ricerca di porte open nel modo seguente:
# nc -v -w 1 server2.esempio.it -z 1-1000
(1-1000 significa: scansione delle porte dalla numero 1 alla porta numero 1000.)
La stessa scansione porte nel sistema locale:
# nc -v -w 1 localhost -z 1-1000
localhost [127.0.0.1] 993 (imaps) open
localhost [127.0.0.1] 631 (ipp) open
localhost [127.0.0.1] 143 (imap2) open
localhost [127.0.0.1] 80 (www) open
localhost [127.0.0.1] 25 (smtp) open
Server Web
Si può usare netcat per simulare un web server:
# while true; do nc -l -p 80 -q 1 < somepage.html; done
fornirà la pagina somepage.html alle richieste http.
Spoofing degli HTTP Headers
Si può usare netcat per richiedere pagine web:
# nc ispconfig.org 80
Digitando direttamente gli headers come segue:
GET / HTTP/1.1
Host: ispconfig.org
Referrer: mypage.com
User-Agent: my-browser
Come si può notare, questo consente di mascherare referrer e browser (User-Agent). Dopo aver specificato i propri headers di fantasia, basta premere ENTER due volte, e la pagina richiesta verrà restituita (inclusi gli headers) dal server remoto:
server2# nc example.com 80
GET / HTTP/1.1
Host: example.com
Referrer: mypage.com
User-Agent: my-browser
HTTP/1.1 200 OK
Date: Fri, 28 Nov 2008 14:11:49 GMT
Server: Apache/2.2.3 (Debian) mod_ssl/2.2.3 OpenSSL/0.9.8c
Last-Modified: Wed, 26 Nov 2008 19:34:17 GMT
ETag: “228c707-21b1-b6b7e040″
Accept-Ranges: bytes
Content-Length: 8625
Content-Type: text/html
[...]
Chatting
Si può adoperare netcat per stabilire una chat a riga di comando tra due sistemi.
Si digiti
# nc -lp 1234
su server2.
server2 attenderà che server1 si connetta sulla porta 1234.
Su server1 invece si esegua:
# nc server2 1234
E’ ora possibile introdurre messaggi su uno qualsiasi dei due sistemi e premere ENTER, ed essi appariranno sull’altro sistema. Per chiudere la chat, basta premere CTRL+C su un sistema qualsiasi.
Continuazione di un trasferimento file interrotto: dd e netcat
Problema: Vi è un file di nome 200511032230.dmp.gz su host06 di grandezza 3877579206 bytes. Questo file era in corso di trasferimento a host02 tramite ftp e la rete è caduta. Il vecchio ftp server non prevede il recupero di un trasferimento interrotto. 3343810560 bytes (3.3GB) erano stati copiati. Come completare il trasferimento?
Soluzione: nc è stata la scelta per il frasferimento. Ma vi era bisogno di un qualche tool in grado di puntare a una specifica posizione nel file. dd serve proprio per questo.
server side (host06) ho dato:
# dd if=200511032230.dmp.gz iseek=3265440 bs=1024 | ~/nc -l -p 2005
mentre, client side (host02):
# ./nc host06 2005 | dd of=200511032230.dmp.gz seek=3265440 bs=1024
Così ho calcolato il parametro seek richiesto:
bytes copiati=3343810560 => blocchi copiati=3265440
Il block size avrebbe potuto anche essere differente. Per esempio se i bytes copiati fosser stati 3343810570 invece di 3343810560 (10 bytes in più), avrei potuto utilizzare lo stesso numero di blocchi e sovrascrivere 10 bytes. Non proprio un grosso problema.
Alcune osservazioni sul precedente trasferimento:
dd lato server riporta:
521258+1 records transferred i.e. 521258 full and 1 partial block
dd lato client riporta:
500678+42702 records transferred i.e. 500678 full and 42702 partial blocks.
Il lato Server mostra solo 1 bocco parziale e questo a causa del fatto che il file size non è completamente divisibile per 1024.
Un fine aggiustamento del block size (qualcosa in sintonia col MSS della rete) dovrebbe migliorare notevolmente la velocità dell’operazione di trasferimento.

