En este tutorial se va a hablar sobre una herramienta de red muy potente Netcat, comúnmente abreviada como nc. Esta herramienta se utiliza a través de línea de comandos y su sintaxis es muy sencilla. Nos va a permitir escribir y recibir datos a través de sockets (TCP o UDP). Cuenta con muchas características y por lo tanto la podemos usar de muchas maneras. Es importante conocer su funcionamiento, ya que nos permitirá debuggear, testear e investigar en la red.
Netcat puede operar de 2 modos:
Vamos a aprender el funcionamiento de Netcat o nc a través de ejemplos prácticos, que es la mejor forma de aprender. Para ello voy a utilizar el sistema operativo Ubuntu 16.04.
Lo primero que vamos a ver es la sintaxis de netcat:
nc [opciones] [objetivo] [puerto]Netcat tiene muchas opciones, veamos algunas:
- -l: Indica a netcat que debe permanecer a la escucha.
- -p: Para indicar el puerto de origen.
- -s: Para indicar la dirección origen.
- -k: Para que permita “infinitas” conexiones el listener (se usa con -l).
- -u: Netcat abre el puerto como UDP en vez de TCP (que es por defecto).
- -v: Con esta opción nos mostrará información de la conexión.
- -i: Para indicar el retraso para enviar y recibir. (En segundos).
- -4: Sirve para que Netcat solo use IPv4.
- -6: Al igual que la anterior pero fuerza a usar IPv6.
Existen más opciones las cuales podemos ver ejecutando el siguiente comando:
nc -hA continuación se puede ver en la imagen:
Vamos a empezar con los ejemplos, primero irán los más sencillos, para ir complicándolos, pero solo un poco, verás que es muy fácil de utilizar.
Poner a escuchar mi máquina en el puerto 87:
sudo nc -l -p 87
Ahora vamos a establecer una conexión desde otra terminal, como la ejecuto en la misma máquina, utilizo localhost como dirección:
nc localhost 87Si escribimos algo desde el cliente que acabamos de abrir lo veremos también en la terminal que está escuchando, y así verificamos que la conexión funciona correctamente. Pero si escribimos en el listener, la primera terminal, también le llega al cliente. A continuación dejo una imagen del listener y otra del cliente:
Vemos que se comunican como queríamos en este ejemplo, vamos a por otro.
Podemos hacer que el servidor o listener guarde los datos que le manda el cliente en un archivo, para ello el comando a ejecutar no difiere mucho del visto en el primer ejemplo:
sudo nc –l 87 > test
En el lado del cliente el comando será igual que antes:
nc localhost 87En la siguiente imagen se ve lo ejecutado en el cliente (el listener está escuchando antes que se conecte, si no, no tendría efecto):
Y en el lado servidor podemos ver que aparentemente no se recibe nada, pero lo único cierto es que no se muestra por pantalla y se guarda en el fichero test:
Continuemos con otro ejemplo.
Vamos a comprobar si un rango de puertos, para saber si están abiertos o no, en este ejemplo el rango será 80-90. Primero abrimos un servidor en el puerto 80 como hicimos en el primer ejemplo (así veremos cómo funciona cuando esté abierto, y cuando no):
sudo nc -l 87Y en el cliente ejecutaremos:
nc -z -v localhost 80-90El parámetro -z se utiliza para escanear, y el -v como vimos antes para que muestre información (si esto no lo ponemos no mostrará que puerto está abierto y cual no), a continuación la imagen del cliente:
Vamos a pasar a ver un ejemplo en UDP.
Este ejemplo también es sencillo, vamos a poner a escuchar por UDP en el puerto 2016, y vamos a obligar a que sea dirección IPv4:
sudo nc -l -u -4 2016Y ahora hacemos al cliente conectarse:
nc -u -4 2016No facilito imagen, ya que la captura será igual a la del ejemplo 1, cambiando claro está la parte del comando. Vamos a pasar a algún ejemplo en el que utilicemos código en Python.
Vamos a poner un código lo más sencillo posible en Python para que escuche una conexión, reciba un dato y termine.
import socket s = socket.socket() s.bind(("192.168.56.1", 1987)) s.listen(1) conn, addr = s.accept() data = conn.recv(1024).decode("utf-8") print(data)Este código lo voy a ejecutar en Windows y luego desde Linux conectaré con él a través de netcat, la siguiente imagen muestra el lado cliente en Linux:
Y lo que se vería en Windows:
Si modificamos algo el código podemos hacer que ejecute un comando y nos mande su contenido, pero también podemos que nos devuelva una shell, que nos permitirá hacer muchas cosas, así que pasemos al siguiente ejemplo.
En este ejemplo voy a ejecutar un código Python en la misma máquina de Linux, y me voy a conectar con netcat, vamos a comprobar que nos devuelve una Shell (/bin/bash). A continuación dejo el código de Python, lo más sencillo y corto posible, solo para el ejemplo.
import socket, subprocess s = socket.socket(socket.AF_INET) s.setsockopt(socket.IPPROTO_IP, socket.SO_REUSEADDR, 1) s.bind(("", 1987)) s.listen(1) conn, addr = s.accept() p = subprocess.Popen(["/bin/bash"], stdin = conn, stdout = conn, stder = conn)Se ejecuta el código de Python y se ve lo siguiente (la imagen muestra como queda al conectarse desde netcat):
Vemos que se mantiene a la escucha al ejecutarlo, pero cuando se conecte un cliente se cierra la conexión, y tenemos una Shell para nosotros.
También podríamos hacer un código que se conectara a nuestra máquina, que la pondremos a escuchar en un puerto determinado, en general hay muchas posibilidades, ahora te toca investigar y “jugar” con netcat, que como has podido ver nos puede ayudar en muchos momentos.