jueves, 13 de febrero de 2025

Operadores en Python para Ingenieros de Redes: Guia de Estudio (7)

  • El tipo de dato Booleano (Bullion) en Python: Fue añadido para simplificar la evaluación de condiciones como verdaderas o falsas.
  • Subclase de la clase integer: La clase Booleana es una subclase de la clase integer, lo que permite realizar operaciones matemáticas con valores booleanos.
  • La función bool(): Esta función evalúa si un valor dado es verdadero o falso.
    • Funcionamiento: Al pasar un valor a la función bool(), esta determinará si el valor se considera True o False.
    • Valores True y False: La función bool() retornará uno de estos dos valores.
  • Todo en Python es un objeto: Todos los objetos en Python pueden ser evaluados como True o False.
  • Comparaciones en Python:
    • Se utiliza == para comparar valores, no un solo =.
    • El operador = se usa para la asignación de objetos.
  • Ejemplos de la función bool():
    • bool(1 + 1 == 2) retorna True.
    • bool(2 + 2 == 5) retorna False.
  • El valor None:
    • Es un valor especial en Python que siempre se evalúa como False.
    • Es útil para pruebas de condiciones donde se necesita un valor que sea consistentemente falso.
    • Importante: La palabra clave None debe escribirse con la primera letra en mayúscula.



  • Evaluación de cadenas y listas:
    • Una cadena como John se evalúa como True.
    • Una lista con elementos, como [15, "VLAN"], también se evalúa como True.
    • Una lista vacía, o el valor "nada", se evalúa como False.



  • Reglas de evaluación: Python sigue reglas específicas para determinar si los valores son True o False. Estas reglas son específicas para cada tipo de dato.
  • Evaluación de Cadenas como Booleanos:

    • En Python, las cadenas pueden ser evaluadas como valores booleanos (verdadero o falso).
    • Generalmente, todas las cadenas se evalúan como True, a menos que sean una cadena vacía.
  • Cadenas No Vacías:

    • Cualquier cadena que contenga al menos un carácter, como "John", "access list", "F", "5", "VLAN", o "abracadabra" se evaluará como True.
    • Esto significa que la mayoría de las cadenas que encuentres en tu código se considerarán verdaderas cuando se utilicen en contextos que requieran un valor booleano.
  • Cadenas Vacías:

    • Una cadena vacía ( "" ), es la única excepción y se evalúa como False.
    • Esto es fundamental para entender cómo Python interpreta las cadenas en condiciones o evaluaciones booleanas.
  • Ejemplos:

    • Si defines una variable access_list1 = "access list" y la pasas a una función que evalúa valores booleanos, retornará True.
    • Si defines una variable test_string = "" (una cadena vacía), la evaluación de esta variable retornará False.


  • Reglas Clave:

    • La regla principal es que cualquier cadena con contenido se evalúa como True.
    • Solo las cadenas vacías se evalúan como False.
  • Listas No Vacías:
    • Una lista que contiene al menos un elemento, independientemente del tipo de dato de los elementos (cadenas, enteros, otros tipos), se evaluará como True.
    • Ejemplos de listas que se evalúan como True: ['VLAN 5', 'VLAN 10', 'VLAN 15'], ['VLAN 20', 45, 5, 'VLAN 99'], ['', '', ''].
    • Es importante notar que incluso una lista que contiene cadenas vacías se evalúa como True porque la lista en sí no está vacía.


    • Lo que importa es si la lista tiene elementos, no el contenido de esos elementos.

  • Listas Vacías:
    • Una lista vacía ( [] ) es la única condición en la que una lista se evalúa como False.
    • Este comportamiento es similar al de las cadenas vacías.

  • Valores Booleanos de Otros Tipos de Datos:
    • Números no cero (enteros y flotantes) se evalúan como True
    • El valor 0 (cero) y 0.0 (cero punto cero) se evalúan como False
    • Estos valores también pueden ser incluidos en listas, pero no afectan la evaluación de la lista en sí misma; una lista con estos valores se evalúa como verdadera si la lista no está vacía.
      • Por ejemplo, una lista como [0, 0.0] se evaluará como True
El método append se utiliza para añadir un elemento al final de una lista. Este método es muy útil para construir listas dinámicamente, añadiendo elementos uno a uno durante la ejecución del código.
Ejemplo de uso de append:

.


Vemos ahora cómo Python evalúa tuplas, diccionarios y conjuntos en contextos booleanos, similar a cómo lo hace con listas. Estos conceptos son importantes en la automatización de redes para escribir código más eficiente y legible [conversación].

Evaluación de Veracidad/Falsedad

En Python, los tipos de datos pueden ser evaluados como True o False basándose en si contienen o no elementos.

  • Tuplas
    • Una tupla no vacía es evaluada como True.
      mi_tupla = ("VLAN 1", "VLAN 2")
      print(bool(mi_tupla))  # Output: True
      
    • Una tupla vacía es evaluada como False.
      mi_tupla_vacia = ()
      print(bool(mi_tupla_vacia))  # Output: False
      
  • Diccionarios
    • Un diccionario no vacío es evaluado como True.
      mi_diccionario = {"version": "15.6", "obtain": 200, "platform": "Cisco_iOS"}
      print(bool(mi_diccionario))  # Output: True
      
    • Un diccionario vacío es evaluado como False.
      mi_diccionario_vacio = {}
      print(bool(mi_diccionario_vacio))  # Output: False
      
    • Un diccionario con claves y valores vacíos (ej. cadenas vacías) se considera no vacío y se evalúa como True.
      mi_diccionario_con_vacios = {"key": "", "value": ""}
      print(bool(mi_diccionario_con_vacios)) # Output: True
      
  • Conjuntos (Sets)
    • Un conjunto no vacío se evalúa como True.
      mi_set = {1, 2, 5, 7}
      print(bool(mi_set))  # Output: True
      
    • Un conjunto vacío se evalúa como False. Para inicializar un conjunto vacío, se debe usar set() en lugar de {}, ya que las llaves se utilizan para crear diccionarios.
      mi_set_vacio = set()
      print(bool(mi_set_vacio))  # Output: False

  • Lógica del Operador and
    • El operador and evalúa múltiples condiciones y devuelve True solo si todas las condiciones son verdaderas.
    • Si alguna de las condiciones es False, el operador and devuelve False.
      • Esta lógica se puede entender mejor con una analogía binaria:
        • 1 representa True
        • 0 representa False

1 and 1 resulta en 1 (True).

1 and 0 resulta en 0 (False).

0 and 0 resulta en 0 (False).


Strings:
Un string no vacío se evalúa como True. 

mi_string1 = "John" 

mi_string2 = "" 

print(bool(mi_string1)) # Output: True 

print(bool(mi_string2)) # Output: False

Cuando se usa el operador and, si una variable es False, la evaluación resulta en False. 

print(mi_string1 and mi_string2) # Output: False

Múltiples Condiciones: 

El operador and no se limita a dos condiciones, puede evaluar múltiples condiciones. 

nombre1 = "John" 

nombre2 = "Dave" 

nombre3 = "Michelle" 

nombre4 = "Ryan"

print(nombre1 and nombre2 and nombre3 and nombre4) # Output: True

Si cambiamos una variable a un valor vacío, la evaluación completa resulta en False: 

nombre1 = "John" 

nombre2 = "" 

nombre3 = "Michelle" 

nombre4 = "Ryan" 

print(nombre1 and nombre2 and nombre3 and nombre4) # Output: False


Listas: Una lista vacía se evalúa como False. 

mi_nombre = "John" 

mi_apellido = "Rambo" 

mi_lista = [] 

print(mi_nombre and mi_apellido and mi_lista) # Output: False

Ejemplos Prácticos con and

Verificación de Versión y Plataforma: 

Se pueden combinar múltiples condiciones para verificar que un dispositivo cumpla con ciertos criterios antes de ejecutar una acción. 




Condición de No-Ejecución: Si cualquiera de las condiciones evaluadas con and es False, el bloque de código condicional no se ejecuta. 



Uso en Automatización: El operador and es fundamental para asegurar que todas las condiciones necesarias se cumplen antes de realizar una acción, como recargar un dispositivo o actualizar una política.


Consideraciones Adicionales

El operador and evalúa las expresiones de izquierda a derecha, deteniéndose tan pronto como encuentra una condición False.
Se pueden combinar diferentes tipos de datos en las evaluaciones con el operador and.
Es crucial entender la evaluación booleana de los distintos tipos de datos para utilizar el operador and de manera efectiva.
El operador and se puede usar para validar que todos los valores requeridos son True, antes de ejecutar una acción especifica.
Conclusión


El operador and es una herramienta poderosa en Python para la toma de decisiones lógicas, especialmente útil en la automatización de redes. Permite verificar que todas las condiciones necesarias se cumplen antes de ejecutar una acción. Al comprender su funcionamiento y aplicarlo correctamente, se pueden escribir scripts más robustos y fiables.

Ejemplos practicos con NOT:

  • El operador NOT invierte la veracidad o falsedad de un valor. Si un valor es verdadero, el operador NOT lo cambiará a falso, y viceversa.

  • Ejemplo en Python:

    • Si name = "John" entonces bool(name) es verdadero.
    • not name invertirá ese valor a falso.
    • Si my_list = [] (una lista vacía) entonces bool(my_list) es falso.
    • not my_list invertirá ese valor a verdadero.


  • Uso del operador NOT en código Python:

    • El operador NOT puede hacer que el código sea más corto y conciso.
    • Es útil en pruebas de condiciones en automatización de redes.
  • Ejemplo de uso con una lista de protocolos:

    • Se crea una lista de protocolos: my_list_of_protocols = ["Rep", "EIGRP", "OSPF", "ISIS"].
    • Se verifica si "BGP" está presente en la lista.
    • Sin el operador NOT, la declaración ("BGP" in my_list_of_protocols) retorna False porque BGP no está en la lista.
    • Al usar el operador NOT, not ("BGP" in my_list_of_protocols) retorna True.
    • En este caso, se imprime el mensaje "no path vector protocols are present".



    • Si se cambia la lista para incluir "BGP", la declaración ("BGP" in my_list_of_protocols) retorna True.
    • Al usar el operador NOT, not ("BGP" in my_list_of_protocols) retorna False.
    • En este caso, se imprime el mensaje "path vector detected".
  • El operador NOT no es estrictamente necesario, pero puede hacer que el código sea más limpio y fácil de leer.

  • Recomendación: Familiarizarse con el uso del operador NOT para escribir código Python más eficiente.

martes, 4 de febrero de 2025

ICMP y la Seguridad de Redes

 

ICMP y la Seguridad de Redes

Introducción a ICMP

  • ICMP (Internet Control Message Protocol) es un protocolo de la capa 3. A menudo se pasa por alto en el mundo del escaneo de redes.
  • No es tan complicado como otros protocolos, y tiene encabezados de paquetes más cortos.
  • A pesar de su simplicidad, ICMP tiene usos críticos y es tan importante como TCP o UDP.
  • Es compatible tanto con IPv4 como con IPv6.

Estructura de un Paquete ICMP

  • El encabezado de ICMP es de solo 8 bytes de largo, y los primeros 4 bytes son la parte principal.
  • El byte de desplazamiento 0 es el tipo de mensaje.
  • Los tipos y códigos de ICMP son esenciales para entender la comunicación en la capa 3.
  • No incluye un número de puerto.


Usos de ICMP en la Seguridad de Redes

  • Identificación de la Red: ICMP ayuda a identificar switches y otros dispositivos en la red.
  • Mapeo de Red: Permite mapear la red, tanto interna como externamente, y ayuda a construir mejores patrones de ruta.
  • Herramientas de Análisis de Red: ICMP se traduce directamente en herramientas comunes para el análisis de redes, como ping y traceroute.
  • Traceroute: Esta herramienta utiliza ICMP para determinar las rutas que toman los paquetes a través de una red. Por ejemplo, traceroute google.com utiliza ICMP para rastrear la ruta. En Windows, se utiliza el comando tracert -4 google.com para obtener la respuesta de traceroute para IPv4.
  • Detección de Hosts: Se utiliza para verificar qué hosts están activos en una red.
  • Descubrimiento de Routers: ICMP también se usa para el descubrimiento de routers en redes Juniper.
  • Mensajes de Error: ICMP se utiliza para enviar mensajes de error, como "host inalcanzable".

ICMP y el Análisis de Paquetes

  • Filtrado en Wireshark: Se pueden utilizar filtros en Wireshark para centrarse solo en el tráfico ICMP usando ip.proto == 1 o escribir icmp
  • Análisis de la Carga Útil (Payload) ICMP: La carga útil de un paquete ICMP se puede analizar para obtener información adicional sobre la comunicación.
  • Tipos de ICMP Un tipo común de ICMP es el "echo ping request", con un valor hexadecimal de 0x08. Si se detecta un destino inalcanzable, el tipo de ICMP sera 3.
Mensaje de puerto inacesible

  • Checksum: Se puede verificar el checksum del payload ICMP para garantizar la integridad de los datos.
  • Secuencia de Eventos: ICMP proporciona información sobre la secuencia de eventos que ocurren durante la comunicación. Estos incluyen un identificador y un número de secuencia, que se utilizan para identificar de forma única las solicitudes y emparejarlas con las respuestas.



Ejemplo Práctico
Consideremos un host Linux que envía dos pings a 192.168.238.2 y otros dos a 69.21.118.171. Podríamos ver lo siguiente:
Identificador 47, Secuencia 1 (ping a 192.168.238.2)
Identificador 47, Secuencia 2 (ping a 192.168.238.2)
Identificador 48, Secuencia 1 (ping a 69.21.118.171)
Identificador 48, Secuencia 2 (ping a 69.21.118.171)

En contraste, un host Windows 10 enviando los mismos pings:
Identificador 1, Secuencia 1 (ping a 192.168.238.2)
Identificador 1, Secuencia 2 (ping a 192.168.238.2)
Identificador 1, Secuencia 3 (ping a 69.21.118.171)
Identificador 1, Secuencia 4 (ping a 69.21.118.171)

En combinación con el identificador, el número de secuencia ayuda a determinar si algún paquete se ha perdido o si se han recibido respuestas fuera de orden

  • Windows 10, el número de secuencia siempre creciente puede ser menos útil para distinguir entre conversaciones, pero aún sirve para el seguimiento de mensajes en general, siendo importante para detectar retransmisiones o pérdidas
  • Relación con otros protocolos: Dentro de la respuesta ICMP, es posible encontrar información de otros protocolos como IGMP, IGRP, GRE, OSPF, etc.


Variedad de Payloads en ICMP

  • Diversidad de Sistemas Operativos: Los payloads de los mensajes ICMP echo varían significativamente según el sistema operativo e incluso entre aplicaciones que se ejecutan en el mismo sistema. Esta diversidad es importante para los analistas de red porque puede ayudar a identificar el tipo de sistema que está enviando los mensajes ICMP.

  • Payloads por Defecto:

    • Linux: Generalmente, los sistemas Linux utilizan un payload que incluye una marca de tiempo, seguida de una secuencia de valores hexadecimales incrementales, comenzando desde 0x10.
    • Windows: Los sistemas Windows, en contraste, suelen utilizar una secuencia de caracteres ASCII incrementales, comenzando con la letra "a" y continuando hasta la "w", luego repitiendo "a" hasta "i".


  • Importancia de los Payloads por Defecto: Es fundamental que los analistas comprendan los payloads predeterminados y el comportamiento normal de los sistemas en su entorno de red. Esto permite detectar sistemas o aplicaciones que puedan ser anómalos o maliciosos. Por ejemplo, si en una red exclusivamente Windows se detectan payloads con el formato hexadecimal incremental típico de Linux, esto podría ser una señal de alerta.

Payloads Inusuales y su Significado

  • Aplicaciones Específicas: Algunas aplicaciones pueden utilizar payloads no estándar para el tráfico ICMP echo. Por ejemplo, se han observado payloads extraños, pero no maliciosos, como los de Microsoft Outlook Autodiscover y Microsoft Telemetry Data.

  • Ejemplos de Payloads Inusuales:

    • Microsoft Outlook Autodiscover: Puede enviar payloads que contienen la palabra "Running".
    • Microsoft Telemetry Data: Envía mensajes con payloads muy cortos (2 bytes) y valores TTL (Time to Live) inusuales (30).
    • Tunelización SSH: Algunos payloads pueden ser usados para tunelizar otros protocolos, como SSH, sobre ICMP echo/echo reply. Esto es una clara señal de actividad sospechosa.
  • Actividad Maliciosa:

    • Aplicaciones maliciosas y canales de comando y control (C2) pueden utilizar ICMP echo/echo reply con payloads no estándar para comunicarse o pasar desapercibidos. Un payload inusual en un mensaje ICMP podría indicar la presencia de malware o una conexión de un C2, lo cual requiere una investigación adicional.


ICMP Echo Reply

  • Similitud con el Echo Request: En general, un mensaje ICMP echo reply debe tener un payload idéntico al del mensaje echo original. La única excepción son los casos en los que haya timestamps, que deberían ser actualizados en la respuesta.
  • Diferencias por Sistema Operativo: Como vimos en la conversación anterior, al enviar un mensaje ICMP tipo 8 con código 4, los sistemas Linux responden cambiando el tipo a 0 y manteniendo el código en 4, mientras que Windows cambia ambos valores a 0. Esta diferencia de implementación puede ser usada para identificar el sistema operativo, aunque no sea un cambio en el payload.

Mensajes ICMP de Tiempo Excedido (Time Exceeded)

  • Estos mensajes tienen el tipo 11.
  • Se utilizan para informar al emisor cuando un paquete no puede llegar a su destino debido a un problema de tiempo de vida (TTL) o tiempo de reensamblaje de fragmentos.
  • Hay dos códigos posibles:
    • Código 0: "Tiempo de vida excedido en tránsito". Se envía cuando el campo TTL de un paquete IP llega a cero, y el sistema descarta el paquete. Esto puede suceder en un enrutador o en el host de destino.
    • Código 1: "Tiempo de reensamblaje de fragmentos excedido". Se envía cuando un host no recibe todos los fragmentos de un paquete fragmentado antes de que se agote el tiempo de espera. El primer fragmento debe haberse recibido para que se envíe este mensaje.
  • Los campos 4 a 7 del encabezado ICMP no se utilizan en estos mensajes y permanecen en cero.
  • La carga útil incluye el encabezado IP y al menos los primeros 64 bits del paquete que causó el error.
  • El comando tracert de Windows utiliza mensajes de tiempo excedido para descubrir la ruta que siguen los paquetes hacia un destino. Aumenta el TTL en cada serie de paquetes ICMP echo, y al llegar a cada enrutador, este decrementa el valor TTL del paquete hasta que llega a 0 y genera un error de tipo tiempo excedido de código 0.

Mensajes ICMP de Destino Inalcanzable (Destination Unreachable)

  • Estos mensajes tienen el tipo 3.
  • Se envían cuando un destino no está disponible, ya sea el host, el puerto o el protocolo.
  • Existen muchos códigos asignados a este tipo de mensaje, del 1 al 15. Estos incluyen notificaciones cuando un puerto o protocolo no está disponible, o cuando el host o red son inalcanzables.
  • El código 4 se utiliza cuando se necesita fragmentar un paquete, pero el bit "no fragmentar" (Don't Fragment - DF) está activado.
  • Al igual que los mensajes de tiempo excedido, estos mensajes no utilizan los bytes de la posición 4 a la 7 del encabezado ICMP y la carga útil incluye el encabezado IP y los primeros 64 bits del paquete original.



Relevancia para el Monitoreo y la Seguridad

  • Los mensajes de error ICMP, como los de tiempo excedido y destino inalcanzable, pueden ser utilizados para el reconocimiento de la red. Por ejemplo, un escaneo de puertos y protocolos puede revelar información sobre los servicios en ejecución de un sistema.
  • Los mensajes de destino inalcanzable podrían revelar información sutil, como el hecho de que un sistema está activo y responde.
  • Es importante entender que tanto tcpdump como tshark pueden obtener resultados diferentes al analizar los mensajes de error ICMP debido a cómo procesan los encabezados de la carga útil. Tshark incluye los encabezados de la carga útil en las búsquedas de filtros, mientras que tcpdump no.
  • Estos mensajes de error pueden revelar información sensible, como direcciones IP internas que no deberían ser visibles desde el exterior.
  • Se pueden utilizar para mapear hosts y redes, identificando enrutadores mediante mensajes de tipo tiempo excedido y servicios no disponibles con mensajes de destino inalcanzable.
  • En condiciones normales, los mensajes ICMP no se deben enviar en respuesta a otros mensajes de error ICMP, paquetes de difusión o fragmentos que no sean el inicial.

Existen ciertas condiciones en las que no se deben enviar mensajes ICMP. Estas condiciones se establecen para evitar bucles de mensajes de error, tráfico innecesario y posibles ataques de denegación de servicio. Aquí están las condiciones principales:

  • En respuesta a otro mensaje de error ICMP: No se debe enviar un mensaje de error ICMP como respuesta a otro mensaje de error ICMP. Esto se hace para evitar un bucle infinito de mensajes de error entre dos hosts. Por ejemplo, si un host recibe un mensaje de "puerto inalcanzable" y trata de responder con otro mensaje de error, se podría generar una cadena sin fin de errores entre los hosts.
  • A una dirección de broadcast de destino: No se deben enviar mensajes de error ICMP en respuesta a un paquete IP con una dirección de broadcast de destino. Si se enviara un paquete UDP a una dirección de broadcast, múltiples hosts podrían responder con errores de "puerto inalcanzable", creando tráfico innecesario en la red.
  • Desde una dirección de origen de broadcast o loopback: No se deben enviar mensajes de error ICMP en respuesta a paquetes con una dirección de origen de broadcast o loopback. Generalmente, los paquetes con estas direcciones de origen son maliciosos y enviar mensajes de error podría llevar a un ataque de denegación de servicio.
  • A fragmentos que no sean el fragmento inicial (offset 0): Solo el fragmento inicial o con offset 0 de un paquete fragmentado debe generar un mensaje de error ICMP. Los fragmentos subsiguientes solo contienen datos, y no tienen el encabezado de protocolo necesario para asociar el error al paquete original.
  • Condiciones temporales: Los mensajes ICMP deben enviarse solo para condiciones no transitorias, es decir, problemas que no es probable que se resuelvan por sí solos. Problemas como corrupción de datos en tránsito no son reportados por ICMP ya que se consideran transitorios y se resuelven si el paquete se envía nuevamente.
  • Paquetes con checksum incorrecto: No se debe enviar un mensaje ICMP de error cuando se recibe un paquete con un checksum incorrecto.

Es importante tener en cuenta que estas condiciones están definidas en el RFC 1122. Estas reglas ayudan a asegurar que los mensajes ICMP se utilicen de manera efectiva y evitar problemas de red.

ICMPv6 

ICMPv6 presenta cambios sustanciales en comparación con ICMP en IPv4. Aquí están las características principales de ICMPv6:

  • Funcionalidades Adicionales: ICMPv6 incluye funcionalidades adicionales como el Protocolo de Descubrimiento de Vecinos (NDP) y funciones de membresía de grupos multicast (MLD).

    • Protocolo de Descubrimiento de Vecinos (NDP): NDP reemplaza a ARP y ofrece funciones para descubrir nodos en la red local, determinar la alcanzabilidad de los nodos y detectar cambios en las direcciones de la capa de enlace. NDP también permite detectar direcciones IP duplicadas en la misma red y posibilita que los hosts soliciten direcciones de routers y que los routers anuncien su presencia.
    • Multicast Listener Discovery (MLD): MLD se incorpora a ICMPv6 para determinar los receptores multicast en un enlace. Las direcciones y funcionalidades multicast se usan más en IPv6 que en IPv4.
  • Cambios en los Tipos de Mensajes: Los valores de tipo de los mensajes ICMP han cambiado significativamente en ICMPv6.

    • Mensajes de error: Tienen valores de tipo entre 0 y 127 y no se deben bloquear.
    • Mensajes informativos: Tienen valores de tipo entre 128 y 255 y pueden bloquearse de manera más segura tanto en la entrada como en la salida.
    • ICMP Echo request: Tipo 128.
    • ICMP Echo reply: Tipo 129.
  • Checksum: A diferencia de ICMP en IPv4, el cálculo de la suma de comprobación en ICMPv6 incluye el pseudo-encabezado. Esto es porque IPv6 no incluye un checksum en el encabezado IP, por lo que se requiere el pseudo-encabezado para el checksum de ICMPv6.

  • Organización de Tipos de Mensajes: Los rangos de tipo están diseñados de tal manera que el bit de orden superior indica si el mensaje es de error (0) o informativo (1).

  • Número de protocolo: ICMPv6 tiene el número de protocolo 58.

En resumen, ICMPv6 no solo mantiene las funciones básicas de ICMP como el reporte de errores y los intercambios de información, sino que también integra nuevas funciones para adaptarse a las necesidades de IPv6. Los cambios más notables son la inclusión de NDP y MLD, la modificación de los tipos de mensajes y el cambio en el cálculo del checksum. Estos cambios hacen que ICMPv6 sea más robusto y funcional en el contexto de las redes IPv6.

lunes, 3 de febrero de 2025

Analisis de bloqueo de página WEB

 




Durante un tiempo me he preguntado como se bloquean las página que comparten ficheros que incumplen con alguna norma legislativa. En este caso se trata de mejortorrent una web que contenía enlaces de ficheros torrent que permitían la descarga ilegal de software y películas. Normalmente el bloqueo a las páginas WEBs se suele hacer a nivel de DNS, pero en este caso veremos un caso diferente ya que seguramente el servidor ha sido intervenido. A continuación, analizaremos el flujo de conexión del equipo con la dirección IP 192.168.18.141 al sitio web mejortorrent.com y cómo finalmente es redirigido a a.policia.es. Este análisis se basa en  este archivo mejortorrent.pcap y a continuación se detalla cada paso del proceso.

1. Resolución de DNS

El proceso comienza con la resolución de DNS para obtener la dirección IP de mejortorrent.com.

  • Paquete 1 y 2: El cliente (192.168.18.141) envía consultas DNS al servidor DNS (212.166.210.80) para resolver tanto la dirección IPv4 (tipo A) como la dirección IPv6 (tipo AAAA) de mejortorrent.com.
  • Paquete 3 y 4: El servidor DNS responde que no hay una dirección IPv6 disponible, pero proporciona la dirección IPv4 69.16.230.165.



2. Establecimiento de la Conexión TCP

Una vez obtenida la dirección IP, el cliente inicia una conexión TCP con el servidor.

  • Paquete 5: El cliente envía un paquete SYN al servidor mejortorrent.com en el puerto 443 (HTTPS).
  • Paquete 7: El servidor responde con un paquete SYN-ACK.
  • Paquete 8: El cliente confirma la conexión con un paquete ACK.

jueves, 23 de enero de 2025

Loops en Python para Ingenieros de Redes: Guia de Estudio (6)

 

Bucles en Python para Novatos: ¡Automatizando tu Red Paso a Paso!

Si como yo estás empezando a meterte en el mundo de Python, vamos a conocer otro elemento nuevo. Hoy vamos a hablar de algo súper útil: los bucles (o loops en inglés). Imagina que tienes que hacer la misma tarea una y otra vez... ¡Con los bucles, Python lo hace por ti sin que te canses!

¿Qué son los Bucles?

Piensa en un bucle como un carrusel: da vueltas y vueltas hasta que le dices que pare. En Python, los bucles son pedazos de código que repiten acciones. Si algo se puede "iterar" (como una lista de cosas), ¡podemos hacer un bucle sobre ello! La palabra "iterar" es una forma elegante de decir que vamos a dar vueltas por cada elemento de algo.

El Bucle for: Tu Primer Amigo en la Automatización

El bucle for es como un explorador que va de un elemento a otro en una lista, un conjunto, o una tuple.

  • Cómo se escribe: Primero, pones la palabra for. Luego, inventas un nombre para la variable que va a "guardar" cada cosa de la lista (por ejemplo, device si tienes una lista de equipos). Después, pones in y, por último, la lista sobre la que quieres hacer el bucle. ¡No olvides los dos puntos : al final! Y muy importante, ¡deja cuatro espacios de sangría en la línea siguiente!.

    for item in lista:
        # Aquí va el código que se repetirá
    
  • Ejemplo Práctico: Digamos que tienes una lista de nombres de equipos de red:

    my_list_of_devices = ["R1", "R2", "R3", "R4", "core Switch", "Dist_1", "Dist_2 2", "Access_1", "Access_2"]
    
    for device in my_list_of_devices:
        print(f"¡Tengo el equipo {device} en mi red!")
    

    En este ejemplo, la variable device va tomando cada nombre de la lista en cada vuelta del bucle. La f antes de las comillas te permite poner variables dentro del texto fácilmente.



martes, 21 de enero de 2025

Network Monitoring and Analysis: TCP/IP

  • El análisis de alertas como punto de partida: Una alerta de un IDS/IPS no debe ser considerada como una conclusión final, sino como un inicio para una investigación más profunda. Es esencial que un analista de tráfico examine los paquetes asociados, los registros y otros eventos relacionados para determinar la severidad real de la alerta. Por ejemplo, una alerta de "Zero length padN option" puede ser una señal de compromiso, un falso positivo o simplemente un mensaje informativo. El contexto es crucial.

  • Priorización de alertas:

    • No todas las alertas tienen la misma importancia. Inicialmente, una alerta de "ICMP tunnel" puede parecer más grave que un "ICMP ping sweep", pero el análisis de paquetes podría revelar lo contrario.
    • La prioridad debe ajustarse después de analizar los detalles de los paquetes, la actividad asociada, y la información de otras fuentes de datos. Por ejemplo, un simple "nmap SYN scan" podría ser menos preocupante que un "ICMP tunnel" si este último está exfiltrando datos.

Condicionales en Python para Ingenieros de Redes: Guia de Estudio (5)

Sentencias Condicionales en Python: Tu Guía Definitiva

En esta entrada se revisarán las sentencias condicionales. Estas estructuras nos permiten tomar decisiones en nuestro código, ejecutando diferentes bloques de instrucciones dependiendo de si se cumplen ciertas condiciones. Es como darle cerebro a nuestros scripts.

Los Tres Pilares de las Sentencias Condicionales

En Python, tenemos tres tipos principales de sentencias condicionales que podemos utilizar:

  • if: La base de todo. Es la única sentencia obligatoria cuando trabajamos con condicionales. Usamos if para evaluar una condición inicial y ejecutar un bloque de código si esa condición es verdadera.
  • elif: ¿Qué pasa si la primera condición no se cumple? Ahí es donde entra elif ("else if"). Esta sentencia es opcional y nos permite añadir condiciones adicionales a evaluar. Se ejecutará solo si la condición del if y cualquier elif anterior es falsa.
  • else: El comodín. Esta sentencia también es opcional y se utiliza como un "catch-all". Si ninguna de las condiciones if o elif se cumple, entonces se ejecutará el bloque de código dentro de else.

La Estructura: Clave para el Éxito

La sintaxis de estas sentencias es crucial:

  1. Comenzamos con if, elif o else, seguido de una condición (en el caso de if y elif).

  2. Después de la condición (o de la palabra clave else), ponemos dos puntos (:).

  3. ¡La indentación es fundamental! El código que se ejecutará si la condición es verdadera debe estar indentado. La convención en Python es usar cuatro espacios para cada nivel de indentación.

    • VS Code y otros editores inteligentes suelen indentar automáticamente a 4 espacios cuando creas sentencias condicionales.
    • Recuerda, ¡la indentación es la base de la estructura en Python! Si la olvidas o la haces mal, tu programa fallará.

viernes, 17 de enero de 2025

Strings en Python para Ingenieros de Redes: Guia de Estudio (4)


En esta serie de artículos, exploraremos a fondo el manejo de cadenas de texto (strings) en Python, un concepto fundamental para cualquier persona interesada en la programación, y especialmente crucial para la automatización de redes

  • Definición de Cadenas (Strings) en Python:
    • Las cadenas son secuencias ordenadas de caracteres.
    • Se crean utilizando comillas simples o dobles. Por ejemplo, "Rambo" o 'wifispainreles'.
    • El orden de los caracteres en una cadena es importante. "Rambo" no es lo mismo que "obmar".
    • Podemos acceder a cada uno de los caracteres  mediante su posició:

lunes, 13 de enero de 2025

Datos Mutable e Inmutables en Python para Ingenieros de Redes: Guia de Estudio (3)

 

Tipos de datos mutables:

  • Los tipos de datos mutables son aquellos que se pueden actualizar sin alterar la ubicación de los datos en la memoria.
  • Los ejemplos de tipos de datos mutables en Python son listas, diccionarios y conjuntos.

Listas:

  • Las listas se crean usando corchetes [].
  • Los elementos de una lista se separan con comas.


  • El primer elemento de una lista se encuentra en la posición 0.
  • Las listas se pueden actualizar usando el método append() para agregar nuevos elementos. Por ejemplo: my_routes.append("8.8.8.8/32").


  • Se puede acceder a elementos específicos de una lista usando su posición entre corchetes. Por ejemplo, my_routes[0] accede al primer elemento.

miércoles, 8 de enero de 2025

Tipos de Datos en Python para Ingenieros de Redes: Guia de Estudio (2)



Guía de Estudio: Tipos de Datos en Python para Ingenieros de Redes

Introducción En Python, los tipos de datos son fundamentales porque determinan qué tipo de valores pueden almacenar las variables y qué operaciones se pueden realizar con ellas. Aunque Python es un lenguaje de escritura dinámica, donde no es necesario declarar explícitamente el tipo de dato de una variable, es crucial entender los diferentes tipos para escribir un código eficiente y sin errores. Este post servirá como una guía para comprender los tipos de datos más comunes en Python, especialmente en el contexto de la automatización de redes.

Tipos de Datos Primitivos Estos son los tipos de datos básicos que se utilizan para representar valores individuales:

  • Texto (str): Este tipo de dato se utiliza para representar texto y cadenas de caracteres. Es una secuencia ordenada de caracteres.

    • Ejemplos: "VLAN", "show version", "show ip interface brief".
    • Este tipo de dato es muy común en la automatización de redes.
  • Numéricos (int, float):

    • int: Representa números enteros.
      • Ejemplos: 1, 500, 5324.
    • float: Representa números con decimales.
      • Ejemplos: 15.8, 15.0.
      • Es importante notar que 15.0 es un float debido al punto decimal, no un int.
    • complex: Aunque Python soporta números complejos, estos son menos relevantes en la automatización de redes y se utilizan más en campos como el aprendizaje automático y la ciencia de datos.
  • Booleanos (bool): Representan valores lógicos que pueden ser True o False.

    • Son esenciales para la lógica condicional en programas.

Tipos de Datos de Secuencia Estos tipos de datos se utilizan para almacenar colecciones de elementos:

  • Listas (list): Son secuencias ordenadas y mutables de objetos.
    • Ordenadas: La posición de cada elemento importa.
      • Por ejemplo, una lista de instrucciones debe seguir un orden lógico.
    • Mutables: Los elementos de una lista pueden ser modificados después de su creación.
  • Tuplas (tuple): Similar a las listas, son secuencias ordenadas de objetos.
    • Inmutables: Una vez creadas, no se pueden modificar.

Tipos de Datos de Mapeo

  • Diccionarios (dict): Son colecciones de pares clave-valor no ordenados.
    • Son muy útiles en automatización de redes.
    • Permiten acceder a información específica mediante una clave.
    • A diferencia de las listas y tuplas, los diccionarios no tienen un orden inherente.

Tipos de Datos de Conjuntos

  • Conjuntos (set): Son colecciones mutables de objetos únicos y no ordenados.
    • No permiten duplicados.
  • Conjuntos Congelados (frozenset): Similar a los conjuntos, pero inmutables.

Importancia de los Tipos de Datos Comprender los tipos de datos en Python es vital porque cada tipo tiene sus propias características y comportamientos. Esto permite:

  • Manejar datos de manera efectiva: Saber si un dato es un entero, un texto, una lista o un diccionario permite utilizar las operaciones correctas.
  • Escribir código eficiente: Los distintos tipos de datos están optimizados para diferentes usos.
  • Evitar errores: Intentar realizar una operación no válida en un tipo de dato (como sumar texto y números) puede generar errores.

Conclusión Este post te proporciona una base sólida para entender los tipos de datos más comunes en Python, lo cual es esencial para programar y especialmente en el contexto de la automatización de redes. Familiarízate con la diferencia entre strings, ints, floats, lists, tuples, dictionaries, sets y booleans. Entender cómo se almacenan y manipulan los datos es fundamental para cualquier proyecto de automatización que quieras emprender. Sigue aprendiendo y experimentando con estos tipos de datos, y verás cómo la programación en Python te será más intuitiva y eficiente.

martes, 7 de enero de 2025

Variables en Python para Ingenieros de Redes: Una Guía de Estudio


 



Variables en Python para Ingenieros de Redes: Una Guía de Estudio

¡Hola a todos! En esta guía, exploraremos un concepto fundamental en Python: las variables. Como ingenieros de redes, usarán variables constantemente para la automatización, por lo que es crucial entenderlas bien. Aunque hay algunos conceptos en Python que tal vez no se utilicen en este campo, las variables son esenciales.

¿Qué son las variables?

Las variables son contenedores que se utilizan para almacenar datos temporalmente en la memoria de la computadora. Los datos pueden ser de diferentes tipos, como números o texto.

Una característica importante de Python es que es un lenguaje dinámicamente tipado. Esto significa que no es necesario especificar el tipo de dato que se almacenará en una variable antes de guardarlo. Python manejará el tipo de dato de forma automática. Esto le da flexibilidad y facilidad de uso.

Ejemplos prácticos en Ipython

Para entender mejor cómo funcionan las variables, podemos usar la terminal interactiva Ipython:

  1. Asignación de un valor a una variable:
  • Para crear una variable, se le da un nombre y se usa el signo igual (=) para asignarle un valor.
  • Por ejemplo, podemos crear una variable llamada name y asignarle el valor "Juan": name = "Juan".
  • Para verificar el valor de la variable, simplemente se escribe su nombre en Ipython y se presiona enter
     2. Otros ejemplos de variables:

  • Podemos crear otra variable llamada a_random_number y asignarle el valor 5: a_random_number = 5.
Al igual que antes, si escribimos a_random_number en Ipython y presionamos enter, veremos que su valor es 5.


     3. ID único de un objeto:

  • Python asigna un ID único a cada objeto en memoria.
  • Podemos inspeccionar el ID de una variable utilizando la función id().


  • Si comparamos los ID de diferentes variables, veremos que son distintos.

     4. Actualización de variables:

  • El valor de una variable puede ser cambiado.
  • Por ejemplo, si cambiamos el valor de la variable name de "Juan" a "Laura", el valor anterior se sobreescribirá. name = "Laura"
  • Si escribimos name nuevamente en Ipython, el valor mostrado ahora será "Laura".
  • El ID del objeto también cambia, lo que indica que se ha creado un nuevo objeto en memoria.
  • Lo mismo aplica para las variables numéricas. Si actualizamos a_random_number de 5 a 16, el valor anterior se sobreescribe y el ID también cambiará.

     5. Ejemplos de uso con VLANs:

  • En la práctica, se usan variables para almacenar información como nombres de VLANs.
  • Por ejemplo: my_vlan = "marketing VLAN" y my_new_vlan = "human resources department".
  • Luego, se pueden usar estas variables en funciones como print() para mostrar los valores en la pantalla.

Importancia de las variables

Aunque al principio el uso de variables puede no ser tan obvio, a medida que se comience a escribir scripts, se apreciará su utilidad. Las variables permiten almacenar información que puede ser usada y modificada a lo largo de un programa.

Puntos clave a recordar:

  • Las variables almacenan datos temporalmente en la memoria del computador.
  • Python es un lenguaje dinámicamente tipado, lo que facilita el trabajo con variables.
  • El valor de una variable puede cambiar.
  • Cada variable tiene un ID único.
  • Las variables son fundamentales en la programación y la automatización de redes.
Reglas y Convenciones Clave
  • Uso de Mayúsculas y Minúsculas: En general, las variables deben escribirse en minúsculas o mayúsculas. Aunque Python permite mezclar mayúsculas y minúsculas, se recomienda mantener una sola convención para mejorar la claridad. 
Por ejemplo, usa router o ROUTER, pero evita RoUtEr.
  • Caracteres Permitidos: Los nombres de las variables pueden contener letras (mayúsculas o minúsculas), guiones bajos (_), y dígitos.Ejemplos válidos: router_1, numberOfRoutes, DeviceR2.
  • Restricción de Dígitos al Inicio: Los nombres de las variables no deben comenzar con un dígito.
Ejemplo incorrecto: 1router. Ejemplo correcto: router1.
  • Guiones Bajos para Separar Palabras: Los guiones bajos se utilizan para separar palabras en nombres de variables, lo cual facilita la lectura.
Ejemplo: number_of_routes.
  • Prohibición de Caracteres Especiales: No se deben utilizar caracteres especiales como @, $, %, etc., en los nombres de las variables.○
Ejemplos incorrectos: my-email, number$, percentage%.
Estos caracteres especiales causarán errores de sintaxis.
  • Convenciones de Estilo: Aunque Python no impone ciertas restricciones, seguir las convenciones de estilo es vital para un código limpio y profesional.

Ejemplo: Prefiere router en lugar de ROUTER para variables genéricas.
Ejemplos Prácticos Para ilustrar mejor las reglas, veamos algunos ejemplos de cómo nombrar variables correctamente:

router_name = "R1" (Correcto: minúsculas y guiones bajos).

NUMBER_OF_PORTS = 24 (Correcto: mayúsculas para constantes).
deviceR2 = "Cisco" (Correcto: mezcla de mayúsculas y minúsculas con un número pero no comienza con un número).
number_of_routes = 20 (Correcto: guiones bajos para separar palabras).
SO1_router = "R1" (Incorrecto: comienza con un dígito).
my_email = "user@example.com" (Incorrecto: contiene un caracter especial).
network_down_2_percent = 2 (Correcto: dígitos en el medio del nombre).

Conclusión:
 Aunque Python tiene cierta flexibilidad en el nombramiento de variables, es importante adherirse a las reglas básicas y las convenciones de estilo para mejorar la legibilidad y el mantenimiento del código. Recuerda: no empieces con un dígito, no uses caracteres especiales, y usa guiones bajos para separar palabras. Al seguir estas pautas, asegurarás que tu código Python sea profesional y fácil de entender. El poder y la utilidad de las variables se harán más claros a medida que sigas aprendiendo


Operadores en Python para Ingenieros de Redes: Guia de Estudio (7)

El tipo de dato Booleano (Bullion) en Python: Fue añadido para simplificar la evaluación de condiciones como verdaderas o falsas. Subclase...