Escaneo de puertos TCP | TCP port scanning

Repo: https://github.com/umarquez/100DaysOfC0D3/tree/master/28-tcp-port-scanning

A port scanner is an application designed to probe a server or host for open ports. Such an application may be used by administrators to verify security policies of their networks and by attackers to identify network services running on a host and exploit vulnerabilities. Un escáner de puertos es una aplicación diseñada para detectar puertos abiertos en un servidor o equipo conectado a la red. Como aplicación es utilizada por administradores para verificar las políticas de seguridad de la red, y por atacantes para identificar los servicios que se encuentra en ejecución y poder explotar posibles vulnerabilidades. https://en.wikipedia.org/wiki/Port_scanner

De acuerdo a la misma referencia, existen diferente tipos de escaneo de puertos, en esta ocasión crearemos la aplicación más simple posible utilizando escaneo TCP, este tipo de escaneo utiliza las funciones de red estándar del sistema operativo para intentar conectarse a cada puerto dentro del rango a analizar, si la conexión es exitosa sabremos que el puerto se encuentra disponible.

Como se menciona en Wikipedia, este tipo de escaneo es MUY ruidoso por lo que es fácilmente reconocible por las herramientas de detección de intrusos que podrían tomar medidas para mitigarlo, por esta razón debemos ser muy cuidadosos de no apuntar una herramienta de este tipo a direcciones de red que no sean de nuestra propiedad o a de las que no tengamos premiso explícito pues podría causarnos problemas.

Implementación en Go

  • Crearemos una aplicación sencilla que simulará ser un servicio en la red a la espera de conexiones que pondremos a la escucha en un puerto, en este caso será el 31337 por default -testing-server-port, esta aplicación tomará los datos enviados y los retornará como respuesta para a continuación terminar la conexión
  • Enseguida comenzaremos un escaneo de puertos al host -host seleccionado, intentando conectarnos a cada puesto dentro del rango delimitado por el puerto inicial -start y final -end.
  • En cada puerto intentaremos realizar una conexión y mostraremos un mensaje si la conexión ha sido exitosa.
  • Adicionalmente mostraremos un mensaje de progreso cada 10% y cada vez que se presione la tecla ENTER.

Servidor de prueba

Función para probar cada puerto

Código fuente

Salida

Palabras finales

Este código puede ser optimizado de muchas maneras, una de ellas podría ser lanzar varias goroutines que tomen los puertos a probar de un channel y devuelvan los resultados a otro común que podríamos ir leyendo de manera secuencial para mostar los resultados; con esto reduciríamos el tiempo que nos tomaría recorrer cada rango.

Finalmente, me gustaría saber sus comentarios y sugerencias, especialmente que otros temas les gustaría leer por acá o si tienen alguna idea loca que les gustaría que probáramos.

-Uriel Márquez.