
OPNsense 26.7.6 - Alta - Remota - Omisión de acceso a la red - captive lastseen roam
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · opnsense-captive-lastseen-roam
Clase: Elusión de control de acceso a red Alcance: Remoto
OPNsense core 26.7.6 (a842fe48) - opnsense.org
El roaming del portal cautivo todavía hereda una sesión para el IPv4 más reciente de hostwatch en una MAC, más todos los IPv6. GHSA-864r (26.7.3) detuvo "añadir todos los IPv4". El IPv4 residual es list_hosts.py ORDER BY last_seen DESC. La IP primaria se asigna luego desde current_ips[0] sin filtrar. Un ARP gratuito attacker_IP is-at victim_MAC actualiza last_seen. Después de 26.7.3 ese IPv4 no es uno entre muchos; es el IPv4 que el filtro conserva si es más reciente que el propio ARP de la víctima. El NDP de IPv6 nunca estuvo limitado. Roaming y hostwatch activados por defecto.
Este paquete de GitHub permanece privado hasta la divulgación coordinada.
| ID | aún sin CVE |
| Clase | Elusión de control de acceso a red |
| Alcance | Remoto (adyacente a L2, zona de portal cautivo) |
| CWE | CWE-345 / CWE-863 |
| CVSS | Alto: 7.4 CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:N |
| Producto | OPNsense core |
| Afectado | 26.7.6 (a842fe48c21288d11a422cb944678e8eb308becf) roaming del portal cautivo |
| Autenticación | Host no autenticado adyacente a L2 en una zona de portal cautivo; roaming activado |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
Fijé la etiqueta 26.7.6 peel a842fe48. El laboratorio es un gadget de Python de las líneas fijadas de _filter_addresses / list_hosts.py / arp.py, espera en loopback en 127.0.0.1:18820.
| Método | Destino | Privilegio |
|---|---|---|
| IPv4 más reciente de hostwatch para una MAC con roaming=1 | fijar _filter_addresses / list_hosts.py ORDER BY last_seen DESC; primaria desde current_ips[0] sin filtrar | Integridad (probado en laboratorio): atacante 192.0.2.99 conservado, víctima 192.0.2.10 descartada, primaria=192.0.2.99. Laboratorio: attacker-ipv4-kept=192.0.2.99 victim-ipv4-dropped=yes roaming=1. |
| Misma MAC, roaming=0 | _filter_addresses devuelve [addresses[0]] | Negativo (probado en laboratorio): primer IPv4 192.0.2.10 conservado. |
| IPv6 en la misma MAC, roaming=1 | _filter_addresses conserva todo lo que no sea v4 | Integridad (probado en laboratorio): todos los IPv6 conservados (2001:db8::10 y 2001:db8::99). |
| GARP / NDP falsificado que hostwatch almacena bajo la MAC de la víctima | PF.add_to_table / IPFW.add_accounting en vivo sobre __captiveportal_zone_N | Integridad (inferido): la IP de origen del atacante coincide con la tabla de paso del portal. El nombre de usuario y la cuota de la sesión siguen siendo de la víctima. El GARP en vivo en el cable y el paso en vivo de la tabla de zona no se ejecutan en este gadget. |
| Misma adición a la tabla | número de regla de contabilidad de ipfw por sesión | Integridad (inferido): los bytes del atacante cuentan en la sesión de la víctima. |
| El IPv4 de la víctima ya no es el primero | _remove_client / eliminación pf de direcciones que no están en list_session_ips | Disponibilidad (inferido): el IPv4 de la víctima puede salir de la tabla de zona mientras el IPv4 del atacante permanece. |
Probado en laboratorio vs inferido: conservación/descarte del IPv4 de last_seen, primera IP con roaming=0, y todos los IPv6 son ÉXITO en laboratorio. El GARP falsificado en el cable, el paso en vivo de pf/ipfw y la contaminación de contabilidad son inferidos. Gadget, no una VM FreeBSD completa de OPNsense.
Requiere: host no autenticado adyacente a L2 en una zona de portal cautivo. Roaming activado (por defecto). Hostwatch activado (por defecto). Una sesión ya autorizada en esa zona.
| Superficie | Laboratorio |
|---|---|
| GHSA-864r añadir-todos-los-IPv4 | cerrado en 26.7.3; este residual es el IPv4 de last_seen más todos los IPv6 |
| roaming=0 | primer IPv4 conservado; IPv4 del atacante no seleccionado |
Suplantación de XFF / X-Real-Ip de una IP de inicio de sesión distinta | el proxy de zona lo añade; no es un CIDR pf limpio |
logon no autenticado de la IP del llamante | inicio de sesión documentado del portal de getClientIp() |
| Fuerza bruta de voucher sobre CSPRNG por defecto de 8+10 | no es este residual |
| zip-slip de plantilla | realpath más carga de administrador |
| XSS del splash del portal al origen de WebGUI | puerto / chroot diferente |
| WAN no autenticado | adyacente a L2 en la zona |
| WebGUI / root / emisión de voucher | permanece cerrado |
Sin WebGUI no autenticado. Sin root. Sin omisión del portal desde WAN.
cd lab
./run.sh
Espera en loopback 127.0.0.1:18820. Proyecto de Compose opnsense-captive-lastseen-roam. Etiqueta de imagen de ese compose. Testigo OPNSENSE-CAPTIVE-LASTSEEN-ROAM-WITNESS. Última línea:
SUCCESS opnsense-captive-lastseen-roam attacker-ipv4-kept=192.0.2.99 victim-ipv4-dropped=yes roaming=1 OPNSENSE-CAPTIVE-LASTSEEN-ROAM-WITNESS
Lanzador raíz: python3 opnsense-captive-lastseen-roam-Abraxas-Labs.py.
Elegir el IPv4 que la sesión ya autorizó, no la fila más reciente de hostwatch para esa MAC. Limitar IPv6 de la misma manera, o exigir NDP que el kernel todavía mantenga. No asignar la primaria desde current_ips[0] sin filtrar cuando el filtro ya eligió una dirección diferente. Tratar un GARP que solo actualiza last_seen como observación no confiable, que es la invariante de GHSA-864r.
a842fe48c21288d11a422cb944678e8eb308becfcp-background-process.py _filter_addresses y reescritura de IP primarialist_hosts.py ORDER BY last_seen DESClib/arp.py get_all_addresses_by_mac