NetCat
Vicente González Ruiz
December 15, 2014
Contents
NetCat (nc, abreviando) es una aplicación que, básicamente, permite conectar
sockets con los pipes del shell stdin y stdout. NetCat, como veremos a
continuación, realiza algunas cosas más muy interesantes para un administrador de
sistemas.
En esta práctica vamos a aprender algunas de las posibilidades de NetCat y al
final, veremos cómo puede usarse para resolver nuestro problema universal, el de
acceder a un fichero remoto de forma que podamos transmitir sólo aquella parte del
mismo en la que estemos interesados.
Pero antes de empezar, una aclaración importante. NetCat puede encontrarse en
diferentes versiones. En su versión más usada, comúnmente llamada nc.openbsd,
NetCat carece de algunas de sus posibilidades más “peligrosas”. En Ubuntu, el
paquete que instala dicha versión de NetCat se llama netcat-openbsd, que es el
paquete que proporciona por defecto dicha utilidad. El paquete que instala la
versión más exótica (y peligrosa) de NetCat se llama netcat-traditional.
1 Chateando
NetCat puede configurarse para que escuche en cualquier puerto libre. Cuando otro
proceso se conecte a ese puerto como la parte cliente, todos los datos que son
enviados por el cliente serán recibidos por el servidor y éste los enviará a través
de la salida estándar (por defecto, el terminal). Igualmente, todos los datos que
lleguen al servidor a través de la entrada estándar (por defecto, el teclado) serán
enviados hacia el cliente. Ejemplos:
# Mediante un "Internet Socket":
server$ nc -l 1234
client$ nc server 1234
# Mediante un "Unix Domain Socket":
server$ nc -lU /tmp/udsocket
client$ nc -U /tmp/udsocket
2 Transfiriendo archivos
Como la entrada y la salida estándard en Unix pueden alimentarse con ficheros, es
fácil transferir entre dos hosts cualquier archivo. Ejemplos:
# server -> client
server$ nc -l 1234 < filename
client$ nc server 1234 > filename
# client -> server
server$ nc -l 1234 > filename
client$ nc server 1234 < filename
3 Hablando por la red
Con NetCat es muy sencillo hacer telefonía IP:
# Conferencia a dos bandas:
#
# +---------+ +---------+
# | [1] 1234|----->|? [4] |
# | | | |
# | host1 | | host2 |
# | | | |
# | [2] ?|<-----|1234 [3] |
# +---------+ +---------+
#
# La flecha indica la direcci\’on del flujo de datos.
#
host1$ arecord -t raw -f cd | oggenc -r - | nc -l 1234 # [1]
host1$ nc host2 1234 | mplayer - # [2]
host2$ arecord -t raw -f cd | oggenc -r - | nc -l 1234 # [3]
host2$ nc host1 1234 | mplayer - # [4]
# Multiconferencia a tres bandas:
#
# +---------------------+
# +---------+ | +--------------+ | +---------+
# | [2] 1235|--+ | | +->|? [B] |
# | [1] 1234|----->|? [7] [6] 1235|---->|? [C] |
# | host1 | | host2 | | host3 |
# | [3] ?|<-----|1234 [5] [8] ?|<----|1235 [A] |
# | [4] ?|<-+ | | +--|1234 [9] |
# +---------+ | +--------------+ | +---------+
# +---------------------+
#
host1$ mknod pipe p
host1$ arecord -t raw -f cd | oggenc -r - | tee pipe | nc -l 1234 # [1]
host1$ nc -l 1235 < pipe # [2]
host1$ nc host2 1234 | mplayer - # [3]
host1$ nc host3 1234 | mplayer - # [4]
host2$ mknod pipe p
host2$ arecord -t raw -f cd | oggenc -r - | tee pipe | nc -l 1234 # [5]
host2$ nc -l 1235 < pipe # [6]
host2$ nc host1 1234 | mplayer - # [7]
host2$ nc host3 1235 | mplayer - # [8]
host3$ mknod pipe p
host3$ arecord -t raw -f cd | oggenc -r - | tee pipe | nc -l 1234 # [9]
host3$ nc -l 1235 < pipe # [A]
host3$ nc host1 1235 | mplayer - # [B]
host3$ nc host2 1235 | mplayer - # [C]
4 Duplicando discos duros
En el siguiente ejemplo vamos a realizar una copia exacta de nuestro disco /dev/sda en otro disco
remoto /dev/sdb.
local$ dd if=/dev/sda | nc remote 1234
remote$ nc -l 1234 | dd of=/dev/sdb
5 Realizar peticiones a servidores conocidos
Con NetCat es sencillo interrogar a un servidor conocido, obteniendo, por supuesto,
las correspondientes respuestas.
# Interrogando a un servidor Web:
client$ echo -e "GET / HTTP/1.1\r\n\r\n" | nc.traditional www.ual.es 80
# o tambi\’en (copiar l\’{\i}nea a l\’{\i}nea):
client$ nc.traditional www.ual.es 80 << EOF
GET / HTTP/1.1
EOF
# Capturando la respuesta de un servidor DNS:
#
# Paso 1. Generamos una petici\’on DNS.
# En una consola ejecutar:
client$ nc -u -l 5300 > /tmp/dns-query.bin
# En otra consola diferente, ejecutar:
client$ dig @localhost -p 5300 www.google.es
# Detener el "nc" pulsando CTRL+C cuando "dig" haya terminado.
# Comprobar que la capura se ha producido:
client$ ls -l /tmp/dns-query.bin
#
# Paso 2: Capturar la respuesta de un servidor DNS:
client$ cat /tmp/dns-query.bin | nc -vv -q 5 -u 150.214.156.2 53 > /tmp/dns-reply.bin
client$ ls -l /tmp/dns-reply.bin
client$ hexdump -C /tmp/dns-reply.bin
6 Eligiendo el puerto de salida del cliente
Cuando un cliente se conecta a un servidor, el SO del host cliente selecciona un
puerto libre aleatoriamente. Si esto no es deseable, podemos instar a NetCat a usar
un puerto en concreto:
# En una consola escribir (ojo, las comillas simples son las que est\’an
# debajo de la tecla ?):
cliente$ watch -n 1 ’netstat --inet --extend --numeric --tcp | grep 31337’
# para ver el estado de la conexi\’on asociado al puerto 31337.
# En otra consola escribir:
client$ nc -v -p 31337 www.ual.es 80
7 Escaneando puertos
Ojo con esto, que alguien se nos puede mosquear ...
# www.ual.es -> servidor escaneado
# 20-80 rango de puertos escaneado
attacker$ nc.openbsd -v -z www.ual.es 20-80
attacker$ nc.traditional -v -z www.ual.es 20-80
attacker$ nc.traditional -vv -z www.ual.es 20-80
8 Conectando procesos remotos
Casi todos los procesos utilizan al menos dos flujos de datos que son la entrada
estándar y la salida estándar. Así, podemos ejecutar un proceso en una
máquina remota (un servidor), enviarle datos y obtener los resultados de dicho
proceso. Ejemplos:
# Cont\’ando l\’{\i}neas ...
server$ nc -l 5050 | cat -n | nc -l 5051
client$ nc server 5050 # Escribir algo
client$ nc server 5051 # Leer ... ese algo
# Accediendo remotamente al servidor v\’{\i}a un shell ...
server$ nc -l 5050 | bash | nc -l 5051
client$ nc server 5050 # Escribir algo
client$ nc server 5051 # Leer ... ese algo
# Lo anterior tambi\’en puede realizarse realizando las conexiones justo
# al rev\’es (n\’otese que esta forma tiene la ventaja de que las
# conexiones desde el servidor son salientes, lo que normalmente
# suele estar bien visto por los cortafuegos):
client$ nc -l 5050 # Escribir algo
client$ nc -l 5051 # Leer ... ese algo
server$ nc client 5050 | bash | nc client 5051
# Finalmente, usando s\’olo un socket (recordemos que son
# bidireccionales):
# Nota: Este ejemplo debe realizarse forzosamente entre hosts
# distintos porque un mismo puerto no puede abrirse por dos (o m\’as)
# procesos de forma simult\’anea.
# Nota2: Ojo de nuevo con las comillas!!
server$ nc.traditional -v -c ’cat -n’ -l -p 1234
client$ nc server 1234
Ejercicio 1: Usando los comandos tail y head, y nc, explique
cómo podría transferir un determinado subconjunto de líneas
de texto, por ejemplo, desde la 20 a la 30, de un archivo remoto
hasta su host.