Continuando con las medidas de seguridad en capa 2 que hemos visto en entradas anteriores, en este post nos centraremos en STP (Spanning Tree Protocol), protocolo usado en la red para evitar bucles a nivel 2 en nuestra topología.
Es habitual ver tráfico similar a este cuando capturas tu propia interfaz (no entro a valorar si dispones de permisos de administrador o si el equipo es un servidor o un equipo de usuario):
13:44:16.651348 STP 802.1d, Config, Flags [none], bridge-id 8001.00:24:f7:31:65:00.8016, length 43 message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s root-id 8001.00:24:f7:31:65:00, root-pathcost 0 13:44:18.660589 STP 802.1d, Config, Flags [none], bridge-id 8001.00:24:f7:31:65:00.8016, length 43 message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s root-id 8001.00:24:f7:31:65:00, root-pathcost 0 13:44:20.661034 STP 802.1d, Config, Flags [none], bridge-id 8001.00:24:f7:31:65:00.8016, length 43 message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s root-id 8001.00:24:f7:31:65:00, root-pathcost 0 13:44:22.666010 STP 802.1d, Config, Flags [none], bridge-id 8001.00:24:f7:31:65:00.8016, length 43 message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s root-id 8001.00:24:f7:31:65:00, root-pathcost 0 13:44:24.670848 STP 802.1d, Config, Flags [none], bridge-id 8001.00:24:f7:31:65:00.8016, length 43 message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s root-id 8001.00:24:f7:31:65:00, root-pathcost 0
Como se puede ver en la captura, el tráfico se corresponde con tramas BPDU (Bridge Protocol Data Units) del protocolo STP.
Sin entrar en detalles en el funcionamiento del protocolo, recibir este tipo de tráfico implica que en los switches de capa de acceso no existen medidas de seguridad para gestionar dicho tráfico hacia los equipos finales, lo cual podría permitir a un atacante enviar a la red tramas BPDU falsas, de forma que los dispositivos tengan que recalcular sus rutas, consumiendo recursos y creando una inestabilidad en la red, la cual, en última instancia, podría provocar una denegación de servicio, o por el contrario, podríamos intentar cambiar la topología de la red para que parte del tráfico hacia el exterior se envíe hacia un equipo atacante, donde se inspeccione y se vuelva a enviar a la red. Por suerte, los dispositivos suelen disponer de unas medidas de seguridad que podemos aplicar para mitigar este tipo de ataques.
Para nuestra prueba, usaremos un switch Cisco 2960 y lanzaremos los ataques mediante Yersinia, aunque también podríamos intentar crear los paquetes de forma manual con Scapy si fuera necesario.
Posiblemente, a nivel de puerto de acceso, la funcionalidad relacionada con el protocolo STP más usada es el modo portfast (o edge port). Esta funcionalidad evita que se negocien las distintas operaciones de STP al conectar un dispositivo al puerto donde está configurado, de forma que evitamos el timeout durante el cual el puerto no está operativo. Esto suele ser necesario en equipos de arranque rápidos como VDI, que por ejemplo solicitan IP por DHCP antes de que acabe ese timeout por defecto.
En la situación inicial, el switch es la raíz (root) del árbol, y tenemos nuestro equipo conectado en la interfaz 24.
Switch# show spanning-tree VLAN0001 Spanning tree enabled protocol ieee Root ID Priority 32769 Address 0024.f731.6500 This bridge is the root Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Bridge ID Priority 32769 (priority 32768 sys-id-ext 1) Address 0024.f731.6500 Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Aging Time 300 Interface Role Sts Cost Prio.Nbr Type ------------------- ---- --- --------- -------- -------------------------------- Fa0/24 Desg LIS 19 128.24 P2p Switch# show spanning-tree root Root Hello Max Fwd Vlan Root ID Cost Time Age Dly Root Port ---------------- -------------------- --------- ----- --- --- ------------ VLAN0001 32769 0024.f731.6500 0 2 20 15
Lo que vamos a hacer es usar Yersinia para enviar tramas BPDU. Yersinia las envía cada dos segundos con la misma prioridad a nivel de root, pero con una dirección MAC numéricamente inferior, de forma que intentemos generar un cambio en la topología hacia el nuevo root.
Nos conectamos a la consola de Yersinia y tras modificar los parametros de STP, identificando la interfaz de red sobre la que queremos realizar el envío, lanzamos un ataque NONDOS attack Claiming Root Role (4), de forma que el switch registra un cambio de topología reflejado en la aparición de un nuevo root en el puerto 24.
Switch# show spanning-tree root Root Hello Max Fwd Vlan Root ID Cost Time Age Dly Root Port ---------------- -------------------- --------- ----- --- --- ------------ VLAN0001 32769 0024.f730.6500 19 2 20 15 Fa0/24
Como podemos ver, el identificador obtenido por la interfaz 24 es inferior al del propio switch, por lo que se convierte en el nuevo root.
bpduguard
Para evitar esto podemos activar la funcionalidad bpduguard, función que al detectar que se reciben tramas BPDU en un puerto lo deshabilita en modo err-disable, de forma que tengamos que habilitarlo de forma manual.
Switch(config)# interface fastEthernet 0/24 Switch(config-if)# spanning-tree bpduguard enable
Al lanzar de nuevo el ataque, el puerto queda deshabilitado:
*Mar 1 01:46:36.481: %SPANTREE-2-BLOCK_BPDUGUARD: Received BPDU on port Fa0/24 with BPDU Guard enabled. Disabling port. *Mar 1 01:46:36.481: %PM-4-ERR_DISABLE: bpduguard error detected on Fa0/24, putting Fa0/24 in err-disable state *Mar 1 01:46:37.487: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/24, changed state to down *Mar 1 01:46:38.494: %LINK-3-UPDOWN: Interface FastEthernet0/24, changed state to down
Switch#show interfaces fa 0/24 status Port Name Status Vlan Duplex Speed Type Fa0/24 err-disabled 1 auto auto 10/100BaseTX
Por lo tanto, el puerto queda sin servicio. No obstante, el problema de este modo de funcionamiento es que nosotros mismos estamos facilitando la denegación de servicio ya que el atacante puede ir conectándose a distintas interfaces, de forma que tras lanzar el ataque se van deshabilitando y el siguiente usuario (legítimo) no tendría conexión a la red (aquí entrarían otras medidas de seguridad adicionales como controles de seguridad físicos, port-security, 802.1x, etc).
Como esto puede generar un caos mientras se identifica el origen del problema, tenemos la opción de que la interfaz levante automáticamente después de un timeout, de forma que si el atacante se va o para el ataque, se recuperará el acceso normal a la red. Para ello, configuramos lo siguiente:
Switch(config)# errdisable recovery cause bpduguard Switch(config)# errdisable recovery interval 30 Switch# show errdisable recovery ErrDisable Reason Timer Status ----------------- -------------- bpduguard Enabled Timer interval: 30 seconds
De este modo la interfaz se levantaría 30 segundos después y si el ataque ha parado, quedaría operativa:
*Mar 1 01:52:21.445: %PM-4-ERR_RECOVER: Attempting to recover from bpduguard err-disable state on Fa0/24 *Mar 1 01:52:25.858: %LINK-3-UPDOWN: Interface FastEthernet0/24, changed state to up *Mar 1 01:52:26.864: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/24, changed state to up
Dado que nos interesa conocer este tipo de situaciones, deberíamos configurar el envío de un trap SNMP para alertarnos del ataque y analizar si es algo intencionado, como es el caso de nuestro ataque, o algo no intencionado como puede ser que un usuario conecte un switch para disponer de más conexiones (algo que debería venir previamente autorizado), sin pensar que pueda afectar al resto de la red.
guard root
Otra opción que podemos utilizar es la funcionalidad guard root. Esta opción es similar a la anterior, pero solo bloquea si se reciben tramas BPDU indicando la presencia de un equipo más prioritario el cual sería una nueva raíz del árbol.
Switch(config)# interface fastEthernet 0/24 Switch(config-if)# spanning-tree guard root *Mar 1 02:25:23.329: %SPANTREE-2-ROOTGUARD_CONFIG_CHANGE: Root guard enabled on port FastEthernet0/24.
De esta forma, si enviamos una BPDU de ataque de root, el puerto se bloquea:
*Mar 1 02:26:26.689: %SPANTREE-2-ROOTGUARD_BLOCK: Root guard blocking port FastEthernet0/24 on VLAN0001. *Mar 1 02:26:27.695: %LINEPROTO-5-UPDOWN: Line protocol on Interface Vlan1, changed state to down
Pero si paramos el ataque o lanzamos un ataque distinto con Yersinia como podría ser NONDOS attack Claiming Other Role (5), automáticamente volvemos a recuperar la conexión o no se llegaría a bloquear:
*Mar 1 02:27:01.719: %SPANTREE-2-ROOTGUARD_UNBLOCK: Root guard unblocking port FastEthernet0/24 on VLAN0001
Esta funcionalidad es interesante en los puertos troncales que conectan nuestro core con los equipos de acceso final, de forma que ningún switch de acceso pueda convertirse en la raíz del árbol, pero permitiendo que los switches de acceso participen en la topología.
bpdufilter
La última funcionalidad de la que hablaremos es bpdufilter, con la que conseguimos dejar de transmitir o recibir BPDU por el puerto donde está conectado el equipo final, de forma que en la captura de tráfico ya no aparecerán BPDU de STP:
Switch(config)# interface fastEthernet 0/24 Switch(config-if)# spanning-tree bpdufilter enable
Finalmente, si tenemos que aplicarlo a todos los puertos, podemos crearnos una macro para facilitarnos la tarea, donde podremos añadir nuevas medidas de seguridad adicionales en el futuro (como podría ser portsecurity):
Switch(config) macro name ProtectL2 Enter macro commands one per line. End with the character '@'. spanning-tree portfast spanning-tree bpduguard enable @ Switch# show parser macro name ProtectL2 Macro name : ProtectL2 Macro type : customizable spanning-tree portfast spanning-tree bpduguard enable Switch(config)# interface fastEthernet 0/24 Switch(config-if)# macro apply ProtectL2
y comprobamos que está aplicada correctamente:
Switch# show parser macro description Interface Macro Description(s) -------------------------------------------------------------- Fa0/24 ProtectSTP --------------------------------------------------------------
Siempre que apliquemos medidas de seguridad debemos probarlas previamente en un entorno controlado, conocer las diferencias entre aplicar una medida a nivel de interfaz o a nivel global, las diferencias en aplicarlo en un puerto de acceso o en un puerto troncal y por supuesto, tener claro el comportamiento deseado, ya que por ejemplo, si activamos bpdufilter, al no procesar tramas BPDU, podríamos crear un bucle en la red o por otra parte, si configuramos en una misma interfaz bpduguard y bpdufilter, este último tiene preferencia ya que filtrará las tramas BPDU y bpduguard no actuaría.
Espero que estas medidas de seguridad os ayuden a continuar avanzando en una red más eficiente y segura.