La comunicación entre dispositivos de una misma red se basa en el concepto de sockets. Este, es un concepto abstracto que se designa como punto final de una comunicación, por lo que todos los programas utilizan sockets para comunicarse con otros programas que pueden estar en la misma máquina, red o en otra red diferente.
Los sockets son librerías que utilizan capacidades del sistema operativo para producir una comunicación entre diferentes puertos y servicios de una máquina en local o en red. Es decir, que producen un punto de comunicación entre dos máquinas o servicios mediante los protocolos internos del sistema operativo.
En esta clase vamos a aprender a manejarnos sobre los sockets en python viendo los tipos más usados como es el socket.SOCK_STREAM, que es un socket de flujo para conexiones TCP, y los socket de datagramas socket.SOCK_DGRAM, que son sockets utilizados para conexiones UDP.
El constructor de socket es socket.socket() y como parámetros escogeremos entre los socket para TCP o UDP, dependiendo del servicio que activará nuestra comunicación. Además, por defecto los sockets en Python suelen utilizar la familia AF_INET siendo el protocolo más utilizado el SOCK_STREAM (TCP). Una sintáxis más basica de un socket en python es la siguiente:
En cuanto a los socket de familia, existen tres tipos fundamentales:
● socket.AF_UNIX: Son los primeros que se crearon y se basan en ficheros.
● socket.AF_INET: Son los más utilizados hoy en día.
● socket.AF_INET6: Para IPv6.
Para conocer más sobre los socket y su estructura puedes consultar la ayuda de python desde tu consola, ya que socket viene integrado con tu Python3.

Funciones y parámetros de SOCKET.
Sockets TCP.
En la consulta anterior puedes ver todas las funciones con las que puedes trabajar con sockets. Aquí se exponen las piezas necesarias para escribir tanto clientes como servidores TCP y UDP.
En esta clase vamos a utilizar socket de tipo TCP porque son los más extendidos y porque este tipo de servicios TCP más utilizados en la mayoría de las redes de todas las empresas y la mayoría de nuestros servicios localhost.
Abrir un socket.Para abrir un socket en una máquina tenemos que utilizar el constructor de la clase socket que acepta como parámetros:
● Familia: (AF_UNIX, AF_INET o AF_INT6).
● Tipo de socket: (SOCK_STREAM, SOCK_DGRAM).
● El protocolo: Opcional.
La forma anterior es la forma más habitual de crear un socket, llamando a la clase socket y como parámetros le pasamos la familia y el tipo de socket.
Aunque la mayoría de los sockets que usaremos en este curso estarán centrados en las aplicaciones de cliente y servidor, con la clase socket, podemos ir mucho más lejos de esta acción ya que al ser una librería especializada en conexiones entre dispositivos podemos utilirlo para interrogar a las máquinas que ejecuten nuestros scripts y sacar información sobre el estado de sus puertos, servicios o dispositivos. Mas adelante veremos algunos de estos servicios, pero en este curso utilizaremos NMAP para realizar dichas actividades, por lo que lo que expongo aquí es puramente informativo.
crear un servidor HTTP con socket.Vamos a crear un servidor de tipo socket TCP que nos permita recibir conexiones desde nuestra propia máquina usando un puerto específico; por ejemplo el puerto 8080, que me gusta usarlo mejor que el puerto 80 (HTTP), que requiere de privilegios de root.
Para crear un servidor de socket en python, necesitamos los siguientes métodos:
● socket.bind(dirección, puerto).
● socket.listen(número_de_conexiones).
● socket.accept().
El primer método nos permite establecer la comunicación entre la dirección entre parámetros y el puerto por el cual se va a realizar la comunicación. Con socket.listen(), establecemos el máximo número de clientes que vamos a aceptar (las conexiones máximas que tratará el servidor), iniciando la escucha TCP de las conexiones entrantes. El último método socket.accept(), nos permite aceptar conexiones de los clientes, devolviendonos la dirección del cliente y un objeto client_socket, que usaremos para recibir y enviar datos al cliente.
El código completo de un servidor en python con socket lo tienes a continuación:
# socket TCP puerto 8080 desde nuestra máquina virtual Kali Linux 192.168.1.108
miSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
miSocket.bind(('192.168.1.108', 8080))
miSocket.listen(5)
# ACEPTAMOS CONEXIONES ENTRANTES. DEVOLVEMOS UN HTML
while True:
print("\nEsperando conexiones... ")
(recvSocket, address) = miSocket.accept()
print(f"Conexión establecida desde: {address}")
# Recibimos la petición del cliente
peticion = recvSocket.recv(1024)
print("Recibida petición HTTP:")
print(peticion.decode('utf-8', errors='ignore'))
respuesta = (
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=utf-8\r\n"
"Connection: close\r\n"
"\r\n" # Línea en blanco obligatoria que separa cabeceras de cuerpo
"<html><body><h1>Hola, bienvenido al servidor de python!!</h1></body></html>\r\n"
)
recvSocket.send(bytes(respuesta, 'utf-8'))
recvSocket.close()
Cabe mencionar que el método recv() nos sirve para leer los datos entrantes. Para responder con una página HTTP, usamos el método send().
Copiate éste código de python y abre tu editor preferido y pega el código para guardartelo con el nombre de servidor.py. Yo voy a utilizar el nano integrado en mi Kali Linux virtualizado. Lo único que tienes que cambiar es la dirección IP de tu máquina Kali Linux.

Servidor en Python.
Implementar un Cliente socket.Para comprobar que el servidor nos devuelva la página web, debemos de conectarnos al servidor desde un cliente. Vamos a crar un cliente, pero esta vez lo vamos a ejecutar desde nuestra máquina de Windows 10, y así probaremos la conexión puente de nuestra máquina virtual Kali Linux. Este es el código:
##Selecciona la IP del servidor
wh='192.168.1.108'
##Selecciona el puerto de conexión
wp=8080
print("contactando %s on port %d ..." %(wh, wp))
wc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
wc.connect((wh,wp))
##envia el echo de petición
wc.send(bytes("GET / HTTP/1.1\r\nHost:192.168.1.108\r\n\r\n".encode('utf-8')))
reply = wc.recv(4096)
print("Respuesta desde %s: " %wh)
print(reply.decode())
Ahora que tenemos el cliente y el servidor, lo primero es poner al servidor a la escucha con python servidor.py. En cuanto esté el servidor escuchando, puedes ejecutar el cliente.py:

Conectando varias máquinas a través de la red.
Otras funciones de socket.
Con la clase socket de python no solo podemos establecer conexiones entre una máquina u otra, sino que además, nos permite realizar una gran serie de consultas o herramientas que nos ayudarán en nuestro pentesting. Y como puedes darte cuenta, debido al contenido de todos los métodos y funciones que tiene dicha clase, no es viable dar a conocer todo su contenido en una única clase, por lo que iremos dividiendo en varias prácticas su uso explícito.
Como socket se centra en la conexiones entre dispositivos usando maquínas en las redes, los métodos y las propiedades de estos están centradas en favorecer la comunicación y el entendimiento entre protocolos. Por lo que podemos manejar direcciones IPs, interrogar DNS, comprobar puertos, etc., etc.
Para agilizar las cosas vamos a pedirle a la IA que nos hagas un script de python para que podamos ejecutar las diferentes opciones de redes con socket. Este es el prompt:
Utiliza cualquier IA que te guste. Entre los detalles que le estamos pidiendo a la IA es que nos devuelva funciona básicas como:
● socket.gethostname() y gethostbyname(): Son las funciones nativas que mapean los nombres de red a direcciones IP (lo que hace el protocolo DNS).
● socket.getservbyport(): Consulta el archivo interno del sistema operativo (como /etc/services en Linux/Kali) para saber a qué protocolo conocido pertenece un puerto.
● socket.connect_ex(): A diferencia de connect(), que lanza una excepción y rompe el programa si el puerto está cerrado, connect_ex() simplemente devuelve un código de error (un número). Si devuelve 0, significa que la conexión tuvo éxito y el puerto está escuchando.
● s.settimeout(1.5): Es crucial al escanear puertos. Si un puerto está cerrado o protegido por un firewall, el script podría quedarse esperando minutos por cada puerto. Con esto, si en segundo y medio nadie responde, asume que está cerrado y continúa.

Usos de socket realizado con IA.
Aquí abajo te dejo la descargas de archivos. Compara el script socket_basico.py que te bajas de mi página con el que te ha hecho tu IA.