
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
캡티브 포털 로밍은 여전히 MAC에 대한 가장 최신 hostwatch IPv4와 모든 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는 여러 개 중 하나가 아니라, 피해자 자신의 ARP보다 최신일 경우 필터가 유지하는 IPv4이다. IPv6 NDP는 결코 제한된 적이 없다. 로밍과 hostwatch는 기본 활성화되어 있다.
이 GitHub 팩은 조정된 공개까지 비공개로 유지된다.
| ID | 아직 CVE 없음 |
| 분류 | 네트워크 접근 우회 |
| 도달 범위 | 원격 (L2 인접, 캡티브 포털 영역) |
| 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) 캡티브 포털 로밍 |
| 인증 | 캡티브 포털 영역의 미인증 L2 인접 호스트; 로밍 활성화 |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1 전용 |
태그 26.7.6 peel a842fe48을 고정했다. 랩은 고정된 _filter_addresses / list_hosts.py / arp.py 라인의 Python 가젯이며, 127.0.0.1:18820에서 루프백 대기한다.
| 방법 | 싱크 | 권한 |
|---|---|---|
| roaming=1인 MAC에 대한 최신 hostwatch IPv4 | _filter_addresses / list_hosts.py ORDER BY last_seen DESC 고정; 필터링되지 않은 current_ips[0]에서 기본 IP | 무결성 (랩 입증): 공격자 192.0.2.99 유지, 피해자 192.0.2.10 제거, primary=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 유지. |
| 동일 MAC의 IPv6, roaming=1 | _filter_addresses가 모든 비-v4 유지 | 무결성 (랩 입증): 모든 IPv6 유지 (2001:db8::10 및 2001:db8::99). |
| hostwatch가 피해자 MAC 아래에 저장하는 위조 GARP / NDP | __captiveportal_zone_N에서 라이브 PF.add_to_table / IPFW.add_accounting | 무결성 (추론): 공격자 소스 IP가 포털 통과 테이블과 일치. 세션 사용자 이름과 할당량은 피해자의 것으로 유지. 라이브 GARP 온더와이어와 라이브 영역 테이블 통과는 이 가젯에서 실행되지 않음. |
| 동일 테이블 추가 | 세션당 ipfw 어카운팅 규칙 번호 | 무결성 (추론): 공격자 바이트가 피해자 세션에 계수됨. |
| 피해자 IPv4가 더 이상 첫 번째가 아님 | list_session_ips에 없는 주소의 _remove_client / pf 삭제 | 가용성 (추론): 공격자 IPv4가 유지되는 동안 피해자 IPv4가 영역 테이블에서 제거될 수 있음. |
랩 입증 vs 추론: last_seen IPv4 유지/제거, roaming=0 첫 IP, IPv6-전체는 랩 SUCCESS. 온더와이어 위조 GARP, 라이브 pf/ipfw 통과, 어카운팅 오염은 추론. 가젯이며, 완전한 OPNsense FreeBSD VM이 아님.
요구 사항: 캡티브 포털 영역의 L2 인접 미인증 호스트. 로밍 활성화 (기본). Hostwatch 활성화 (기본). 해당 영역에 이미 인가된 세션 하나.
| 표면 | 랩 |
|---|---|
| GHSA-864r 모든-IPv4-추가 | 26.7.3에서 닫힘; 이 잔여물은 last_seen IPv4와 모든 IPv6 |
| roaming=0 | 첫 IPv4 유지; 공격자 IPv4 선택되지 않음 |
다른 로그온 IP의 XFF / X-Real-Ip 스푸핑 | 영역 프록시가 추가; 깨끗한 pf CIDR이 아님 |
호출자 IP의 미인증 logon | getClientIp()의 문서화된 포털 로그인 |
| 기본 8+10 CSPRNG에 대한 바우처 브루트 | 이 잔여물이 아님 |
| 템플릿 zip-slip | realpath 및 관리자 업로드 |
| WebGUI 오리진에 대한 포털 스플래시 XSS | 다른 포트 / chroot |
| WAN-미인증 | 영역의 L2 인접 |
| WebGUI / root / 바우처 발행 | 닫힌 상태 유지 |
미인증 WebGUI 없음. root 없음. 포털의 WAN 건너뛰기 없음.
cd lab
./run.sh
루프백 대기 127.0.0.1:18820. Compose 프로젝트 opnsense-captive-lastseen-roam. 해당 compose의 이미지 태그. Witness 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를 선택하고, 해당 MAC의 최신 hostwatch 행을 선택하지 말 것. IPv6도 같은 방식으로 제한하거나, 커널이 여전히 보유한 NDP를 요구할 것. 필터가 이미 다른 주소를 선택한 경우 필터링되지 않은 current_ips[0]에서 기본 IP를 할당하지 말 것. last_seen만 갱신하는 GARP를 신뢰할 수 없는 관찰로 취급할 것, 이것이 GHSA-864r 불변식이다.
a842fe48c21288d11a422cb944678e8eb308becfcp-background-process.py _filter_addresses 및 기본-IP 재작성list_hosts.py ORDER BY last_seen DESClib/arp.py get_all_addresses_by_mac