Parte: 0 — Fundamentos y prerrequisitos · Fuente: Seitz & Arnold, Black Hat Python (2ª ed.) ⏱️ Duración estimada: 120 min · Nivel: Fundamentos
Programar comunicaciones de red desde cero con la librería socket. Al terminar podrás construir clientes y servidores TCP/UDP, un escáner de puertos y un cliente/servidor tipo banner grabber, entendiendo cómo se traduce la teoría TCP/IP a código. Es la base de casi cualquier herramienta ofensiva de red.
Al finalizar, el alumno podrá:
socket.| # | Tema | Por qué importa |
|---|---|---|
| 1 | API de sockets | socket, connect, bind, listen |
| 2 | Cliente TCP | Conectar y enviar/recibir datos |
| 3 | Servidor TCP | Aceptar conexiones |
| 4 | UDP | Envío sin conexión |
| 5 | Timeouts | Evitar bloqueos indefinidos |
| 6 | Escáner de puertos | Aplicación práctica directa |
| 7 | Banner grabbing | Identificar servicios y versiones |
| 8 | Concurrencia | Hilos para escanear rápido |
AF_INET (IPv4) + SOCK_STREAM (TCP) o SOCK_DGRAM (UDP).connect exitoso implica puerto abierto (base del connect scan).Solo necesitas Python 3 y la stdlib (socket, threading, concurrent.futures). Trabaja en tu laboratorio aislado con Kali y una VM víctima. Ten nc (netcat) a mano para levantar servicios de prueba y comparar comportamientos.
python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(3)
s.connect(("10.10.10.6", 22))
print(s.recv(1024).decode(errors="replace"))
s.close()
python
srv = socket.socket(); srv.bind(("0.0.0.0", 9000)); srv.listen(1)
conn, addr = srv.accept(); print("Conexión de", addr)
conn.sendall(conn.recv(1024)); conn.close()
Pruébalo con nc 10.10.10.5 9000.
3. UDP. Envía un datagrama con SOCK_DGRAM y observa que no hay handshake.
4. Escáner de puertos secuencial. Recorre un rango con connect_ex() (que devuelve 0 si abre):
python
for port in range(1, 1025):
s = socket.socket(); s.settimeout(0.5)
if s.connect_ex(("10.10.10.6", port)) == 0:
print(f"[+] {port} abierto")
s.close()
recv() y guarda el banner.concurrent.futures.ThreadPoolExecutor y compara tiempos.⚠️ Nota ética: los escáneres y clientes se ejecutan únicamente contra tus VMs de laboratorio o sistemas autorizados. Escanear infraestructuras ajenas sin permiso es ilegal.
socket.gethostbyname.HEAD / HTTP/1.0\r\n\r\n y capturar la respuesta de un servidor web.ConnectionRefusedError, socket.timeout y OSError.Construye pyscan.py, un escáner de puertos TCP multihilo que reciba un objetivo y un rango de puertos, use timeouts, haga banner grabbing de los puertos abiertos y muestre un informe ordenado (puerto → estado → banner). Debe manejar errores de red y ser notablemente más rápido que la versión secuencial.
Criterio de aceptación: contra tu VM víctima detecta correctamente los puertos abiertos conocidos y captura al menos un banner (p. ej. SSH), completa el escaneo de 1024 puertos en una fracción del tiempo de la versión secuencial, y no se cuelga ante puertos filtrados. Comparable con la salida de nmap.
| Síntoma / mensaje | Causa y cómo arreglar |
|---|---|
| El escáner se cuelga en algunos puertos | Falta settimeout. Fija un timeout corto por socket. |
OSError: Too many open files |
No cierras los sockets. Usa with o close() y limita hilos. |
| Todos los puertos parecen "abiertos" o "cerrados" | Confundes connect_ex (0 = abierto) con excepciones. Revisa el código de retorno. |
| Banner vacío en puertos abiertos | El servicio espera que hables tú primero (HTTP). Envía una petición antes de recv. |
| Datos ilegibles al imprimir | Son bytes. Decodifica con errors="replace" o trabaja en hex. |
❓ ¿Por qué mi escáner en Python es más lento que nmap? nmap está en C, usa raw sockets y técnicas avanzadas (SYN scan, temporización adaptativa). El objetivo aquí es entender el mecanismo, no superar a nmap.
❓ ¿connect scan o SYN scan en Python? Con socket haces connect scan (completa el handshake). Para SYN scan necesitas raw sockets/Scapy, que veremos en la Clase 017.
❓ ¿Hilos o asyncio? Para I/O de red ambos sirven. Los hilos son más sencillos de entender al principio; asyncio escala mejor a miles de conexiones.
❓ ¿Puedo escanear UDP con sockets? Sí, pero es poco fiable: la falta de respuesta no distingue "abierto" de "filtrado". Por eso el escaneo UDP es difícil incluso para nmap.
socket — https://docs.python.org/3/library/socket.htmlconcurrent.futures — https://docs.python.org/3/library/concurrent.futures.htmlClase 015 — Python para seguridad: fundamentos del lenguaje
Clase 017 — Python para seguridad: manipulación de paquetes con Scapy