
OPNsense 26.7.6 — высокий — удалённый — обход сетевого доступа — captive lastseen roam
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · opnsense-captive-lastseen-roam
Класс: Обход контроля доступа к сети Достижимость: Удалённая
Ядро OPNsense 26.7.6 (a842fe48) - opnsense.org
Роуминг captive-портала по-прежнему наследует сессию для самого нового IPv4 hostwatch на MAC, а также для каждого IPv6. GHSA-864r (26.7.3) остановил «добавление каждого IPv4». Оставшийся IPv4 — это list_hosts.py ORDER BY last_seen DESC. Затем основной IP назначается из нефильтрованного current_ips[0]. Gratuitous ARP attacker_IP is-at victim_MAC обновляет last_seen. После 26.7.3 этот IPv4 не один из многих; это тот IPv4, который фильтр сохраняет, если он новее собственного ARP жертвы. IPv6 NDP никогда не ограничивался. Роуминг и hostwatch включены по умолчанию.
Этот пакет на GitHub остаётся приватным до скоординированного раскрытия.
| ID | CVE пока нет |
| Класс | Обход контроля доступа к сети |
| Достижимость | Удалённая (L2-смежная, зона captive-портала) |
| CWE | CWE-345 / CWE-863 |
| CVSS | Высокий: 7.4 CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:N |
| Продукт | OPNsense core |
| Затронуто | 26.7.6 (a842fe48c21288d11a422cb944678e8eb308becf) роуминг captive-портала |
| Аутентификация | Неаутентифицированный L2-смежный хост в зоне captive-портала; роуминг включён |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1 |
Я зафиксировал тег 26.7.6 peel a842fe48. Лаборатория — это Python-гаджет из зафиксированных строк _filter_addresses / list_hosts.py / arp.py, ожидание loopback на 127.0.0.1:18820.
| Метод | Точка воздействия | Привилегия |
|---|---|---|
| Самый новый IPv4 hostwatch для MAC при roaming=1 | зафиксировать _filter_addresses / list_hosts.py ORDER BY last_seen DESC; основной из нефильтрованного current_ips[0] | Целостность (доказано в лаборатории): IPv4 атакующего 192.0.2.99 сохранён, IPv4 жертвы 192.0.2.10 отброшен, основной=192.0.2.99. Лаборатория: attacker-ipv4-kept=192.0.2.99 victim-ipv4-dropped=yes roaming=1. |
| Тот же MAC, roaming=0 | _filter_addresses возвращает [addresses[0]] | Отрицательный (доказано в лаборатории): первый IPv4 192.0.2.10 сохранён. |
| IPv6 на том же MAC, roaming=1 | _filter_addresses сохраняет каждый не-v4 | Целостность (доказано в лаборатории): все IPv6 сохранены (2001:db8::10 и 2001:db8::99). |
| Поддельный GARP / NDP, который hostwatch сохраняет под MAC жертвы | живой PF.add_to_table / IPFW.add_accounting на __captiveportal_zone_N | Целостность (предположительно): исходный IP атакующего совпадает с таблицей пропуска портала. Имя пользователя сессии и квота остаются за жертвой. Живой GARP в сети и живой пропуск в таблице зоны в этом гаджете не выполняются. |
| То же добавление в таблицу | номер правила учёта ipfw на сессию | Целостность (предположительно): байты атакующего учитываются в сессии жертвы. |
| IPv4 жертвы больше не первый | _remove_client / удаление pf адресов, отсутствующих в list_session_ips | Доступность (предположительно): IPv4 жертвы может выпасть из таблицы зоны, пока IPv4 атакующего остаётся. |
Доказано в лаборатории vs предположительно: сохранение/отбрасывание IPv4 по last_seen, первый IP при roaming=0 и все IPv6 — это SUCCESS в лаборатории. Поддельный GARP в сети, живой пропуск pf/ipfw и искажение учёта — предположительны. Гаджет, а не полноценная FreeBSD VM OPNsense.
Требуется: L2-смежный неаутентифицированный хост в зоне captive-портала. Роуминг включён (по умолчанию). Hostwatch включён (по умолчанию). Одна уже авторизованная сессия в этой зоне.
| Поверхность | Лаборатория |
|---|---|
| GHSA-864r добавление-каждого-IPv4 | закрыто в 26.7.3; этот остаток — это IPv4 по last_seen плюс все IPv6 |
| roaming=0 | первый IPv4 сохранён; IPv4 атакующего не выбран |
Подмена XFF / X-Real-Ip для другого IP входа | прокси зоны добавляет; это не чистый pf CIDR |
Неаутентифицированный logon IP вызывающего | документированный вход в портал через getClientIp() |
| Перебор ваучеров на стандартном 8+10 CSPRNG | не этот остаток |
| Zip-slip шаблона | realpath плюс загрузка администратором |
| XSS splash портала в origin WebGUI | другой порт / chroot |
| Неаутентифицированный WAN | L2-смежный в зоне |
| WebGUI / root / выпуск ваучеров | остаётся закрытым |
Никакого неаутентифицированного WebGUI. Никакого root. Никакого обхода портала через WAN.
cd lab
./run.sh
Ожидание loopback 127.0.0.1:18820. Проект Compose opnsense-captive-lastseen-roam. Тег образа из этого compose. Свидетель OPNSENSE-CAPTIVE-LASTSEEN-ROAM-WITNESS. Последняя строка:
SUCCESS opnsense-captive-lastseen-roam attacker-ipv4-kept=192.0.2.99 victim-ipv4-dropped=yes roaming=1 OPNSENSE-CAPTIVE-LASTSEEN-ROAM-WITNESS
Корневой лаунчер: python3 opnsense-captive-lastseen-roam-Abraxas-Labs.py.
Выбирайте IPv4, который сессия уже авторизовала, а не самую новую строку hostwatch для этого MAC. Ограничивайте IPv6 таким же образом или требуйте NDP, который ядро всё ещё удерживает. Не назначайте основной адрес из нефильтрованного current_ips[0], когда фильтр уже выбрал другой адрес. Рассматривайте GARP, который обновляет только last_seen, как недоверенное наблюдение — это инвариант GHSA-864r.
a842fe48c21288d11a422cb944678e8eb308becfcp-background-process.py _filter_addresses и перезапись основного IPlist_hosts.py ORDER BY last_seen DESClib/arp.py get_all_addresses_by_mac