
OPNsense 26.7.6 - Alta - Remota - Bypass de acesso à rede - captive lastseen roam
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · opnsense-captive-lastseen-roam
Classe: Bypass de acesso à rede Alcance: Remoto
OPNsense core 26.7.6 (a842fe48) - opnsense.org
O roaming do portal cativo ainda herda uma sessão para o IPv4 mais recente do hostwatch em um MAC, além de todos os IPv6. O GHSA-864r (26.7.3) interrompeu o "adicionar todo IPv4". O IPv4 remanescente é o ORDER BY last_seen DESC do list_hosts.py. O IP primário é então atribuído a partir do current_ips[0] não filtrado. O ARP gratuito attacker_IP is-at victim_MAC atualiza o last_seen. Após o 26.7.3, esse IPv4 não é um entre muitos; é o IPv4 que o filtro mantém se for mais recente que o próprio ARP da vítima. O NDP IPv6 nunca foi limitado. Roaming e hostwatch ativados por padrão.
Este pacote do GitHub permanece privado até a divulgação coordenada.
| ID | ainda sem CVE |
| Classe | Bypass de acesso à rede |
| Alcance | Remoto (adjacente à L2, zona de portal cativo) |
| 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 |
| Produto | OPNsense core |
| Afetado | 26.7.6 (a842fe48c21288d11a422cb944678e8eb308becf) roaming do portal cativo |
| Autenticação | Host não autenticado adjacente à L2 em uma zona de portal cativo; roaming ativado |
| Licença | GNU Affero GPL v3.0 |
| Lab | somente 127.0.0.1 |
Fixe a tag 26.7.6 peel a842fe48. O lab é um gadget Python das linhas fixadas de _filter_addresses / list_hosts.py / arp.py, espera em loopback em 127.0.0.1:18820.
| Método | Sink | Privilégio |
|---|---|---|
| IPv4 mais recente do hostwatch para um MAC com roaming=1 | fixar _filter_addresses / list_hosts.py ORDER BY last_seen DESC; primário a partir do current_ips[0] não filtrado | Integridade (comprovada em lab): atacante 192.0.2.99 mantido, vítima 192.0.2.10 descartada, primário=192.0.2.99. Lab: attacker-ipv4-kept=192.0.2.99 victim-ipv4-dropped=yes roaming=1. |
| Mesmo MAC, roaming=0 | _filter_addresses retorna [addresses[0]] | Negativo (comprovado em lab): primeiro IPv4 192.0.2.10 mantido. |
| IPv6 no mesmo MAC, roaming=1 | _filter_addresses mantém todo não-v4 | Integridade (comprovada em lab): todos os IPv6 mantidos (2001:db8::10 e 2001:db8::99). |
| GARP / NDP forjado que o hostwatch armazena sob o MAC da vítima | PF.add_to_table / IPFW.add_accounting ao vivo em __captiveportal_zone_N | Integridade (inferida): o IP de origem do atacante corresponde à tabela de passagem do portal. O nome de usuário e a cota da sessão permanecem os da vítima. GARP ao vivo no fio e passagem ao vivo na tabela de zona não são executados neste gadget. |
| Mesma adição à tabela | número da regra de contabilização do ipfw por sessão | Integridade (inferida): os bytes do atacante contam na sessão da vítima. |
| IPv4 da vítima não é mais o primeiro | _remove_client / exclusão pf de endereços que não estão em list_session_ips | Disponibilidade (inferida): o IPv4 da vítima pode sair da tabela de zona enquanto o IPv4 do atacante permanece. |
Comprovado em lab vs inferido: manter/descartar IPv4 por last_seen, primeiro IP com roaming=0 e todos os IPv6 são SUCCESS no lab. GARP forjado no fio, passagem pf/ipfw ao vivo e contaminação da contabilização são inferidos. Gadget, não uma VM FreeBSD completa do OPNsense.
Requer: host não autenticado adjacente à L2 em uma zona de portal cativo. Roaming ativado (padrão). Hostwatch ativado (padrão). Uma sessão já autorizada nessa zona.
| Superfície | Lab |
|---|---|
| GHSA-864r adicionar-todo-IPv4 | fechado no 26.7.3; este remanescente é o IPv4 de last_seen mais todos os IPv6 |
| roaming=0 | primeiro IPv4 mantido; IPv4 do atacante não selecionado |
Spoof de XFF / X-Real-Ip de um IP de logon diferente | o proxy da zona acrescenta; não é um CIDR pf limpo |
logon não autenticado do IP do chamador | login documentado do portal de getClientIp() |
| Força bruta de voucher no CSPRNG padrão 8+10 | não é este remanescente |
| Zip-slip de template | realpath mais upload de admin |
| XSS do splash do portal para a origem do WebGUI | porta / chroot diferentes |
| WAN não autenticado | adjacente à L2 na zona |
| WebGUI / root / emissão de voucher | permanece fechado |
Sem WebGUI não autenticado. Sem root. Sem contorno do portal pela WAN.
cd lab
./run.sh
Espera em loopback 127.0.0.1:18820. Projeto Compose opnsense-captive-lastseen-roam. Tag de imagem desse compose. Witness OPNSENSE-CAPTIVE-LASTSEEN-ROAM-WITNESS. Última linha:
SUCCESS opnsense-captive-lastseen-roam attacker-ipv4-kept=192.0.2.99 victim-ipv4-dropped=yes roaming=1 OPNSENSE-CAPTIVE-LASTSEEN-ROAM-WITNESS
Launcher root: python3 opnsense-captive-lastseen-roam-Abraxas-Labs.py.
Escolha o IPv4 que a sessão já autorizou, não a linha mais recente do hostwatch para esse MAC. Limite o IPv6 da mesma forma, ou exija NDP que o kernel ainda mantém. Não atribua o primário a partir do current_ips[0] não filtrado quando o filtro já escolheu um endereço diferente. Trate um GARP que apenas atualiza o last_seen como observação não confiável, que é a invariante do GHSA-864r.
a842fe48c21288d11a422cb944678e8eb308becfcp-background-process.py _filter_addresses e reescrita do IP primáriolist_hosts.py ORDER BY last_seen DESClib/arp.py get_all_addresses_by_mac