
UniFi Network Application 컨트롤러가 CVE-2026-22557에 취약한지 안전하게 탐지합니다.
UniFi Network Application 컨트롤러가 CVE-2026-22557에 취약한지 여부를 중단 없이 안전하게 탐지합니다. 전체 분석 글은 Bishop Fox 블로그에서 확인하세요.
CVE-2026-22557은 UniFi Network Application의 게스트 캡티브 포털에서 인증 없이 경로 탐색이 가능한 취약점으로, 원격 공격자가 컨트롤러 프로세스 사용자 권한으로 임의 파일을 읽을 수 있습니다 (CVSS 10.0). 이 취약점은 10.1.x 브랜치의 UniFi Network Application 10.1.85 이하, 그리고 10.2.x 및 9.0.x 브랜치의 해당 이전 릴리스에 영향을 미칩니다. Ubiquiti는 10.1.89, 10.2.97, 9.0.118에서 수정 사항을 제공했습니다 (SAB-062).
게스트 포털의 오류 페이지 렌더러는 page_error 요청 매개변수를 읽어 유효성 검사 없이 포털 리소스 로더에서 상대 경로로 그대로 사용합니다. 조회된 사이트에서 portal_customized: true가 설정된 경우 (호텔, 소매점, 카페 등 브랜드화된 캡티브 포털을 사용하는 모든 배포에서 설정됨), 로더는 해당 경로를 디스크의 포털 디렉터리 기준으로 해석하며, 경로가 이를 벗어날 수 있습니다.
이 도구는 비파괴적 취약성 테스트를 수행합니다:
/status에서 보고된 컨트롤러 버전을 읽고 SAB-062 수정 라인과 비교/guest/<site>/wechat/sign에서 page_error 매개변수를 ../ 깊이 1~8로 이중 분기 파일명에 대해 프로빙하여 트래버설이 발생하는지 확인firmware.json)을 한 번 더 읽어 맞춤형 포털 파일 시스템 분기가 활성화되었는지 확인이 도구는 분기 활성화 오라클로 런타임 카탈로그 파일만 요청합니다. 자격 증명, TLS 자료, 데이터베이스 상태 또는 백업을 읽지 않으며, 파일 내용을 stdout이나 디스크에 기록하지 않습니다. 결과만 출력됩니다.
portal_customized: true가 설정된 경우, 보정된 깊이에서 카탈로그 파일을 반환하여 VULNERABLE로 확인됩니다.portal_customized: false인 경우, 보정 단계에서 트래버설이 발생하지만 확인 단계에서 디스크 내용을 반환하지 않습니다 → PARTIALLY EXPOSED. 애플리케이션 바이너리는 여전히 취약하므로 패치가 필요합니다.NOT VULNERABLE.NOT EXPOSED를 반환합니다.git clone https://github.com/BishopFox/CVE-2026-22557-check
cd CVE-2026-22557-check
Python 3.9+가 필요합니다. 이 도구는 Python 표준 라이브러리만 사용하므로 pip install 단계가 필요하지 않습니다.
<TARGET>에서 UniFi Network Application 컨트롤러를 테스트합니다. 컨트롤러의 웹 UI에 도달하는 URL을 도구에 지정하세요. 취약한 핸들러는 관리 포트(기본값 8443/TCP)뿐만 아니라 전용 게스트 포털 포트(8843, 8880)에서도 디스패치됩니다.
python3 cve_2026_22557_check.py <BASE_URL> [--site NAME]
기본 사이트 슬러그는 default입니다. 여러 사이트가 구성된 UniFi 배포에서는 각 사이트에 대해 --site <name>을 사용하여 도구를 다시 실행해야 합니다. 어떠한 사이트라도 portal_customized: true가 설정되면 컨트롤러는 악용 가능한 상태가 됩니다.
아래 예제는 호스트당 한 줄 결과를 위해 --brief를 사용합니다. --brief 없이 실행하면 전체 배너, 단계별 진행 상황, 권장 수정 조치가 포함된 결과 블록을 볼 수 있습니다.
컨트롤러가 취약한 빌드에 있고, 조회된 사이트에 대해 맞춤형 포털 전제 조건이 활성화되어 있어 인증 없는 읽기 경로가 접근 가능합니다.
$ python3 cve_2026_22557_check.py https://192.168.1.100:8443 --brief
[VULNERABLE] https://192.168.1.100:8443 site=default
컨트롤러가 취약한 빌드에 있지만, 조회된 사이트에 portal_customized: true가 활성화되지 않아 디스크 읽기 전제 조건이 충족되지 않습니다. 애플리케이션 바이너리는 여전히 패치가 필요하며, 동일한 컨트롤러의 다른 사이트는 여전히 악용 가능한 상태일 수 있습니다.
$ python3 cve_2026_22557_check.py https://192.168.1.100:8443 --brief
[PARTIAL] https://192.168.1.100:8443 site=default
컨트롤러가 수정된 빌드(10.1.89, 10.2.97, 9.0.118 이상)에 있어 조회된 모든 깊이에서 트래버설이 발생하지 않습니다.
$ python3 cve_2026_22557_check.py https://192.168.1.200:8443 --brief
[NOT VULNERABLE] https://192.168.1.200:8443 site=default
--site NAME 프로브할 UniFi 사이트 슬러그 (기본값: "default")
--max-depth N 시도할 최대 ../ 트래버설 깊이 (기본값: 8)
--no-tls-recon TLS 인증서 subject/SAN 표시 건너뛰기
--no-color ANSI 컬러 출력 비활성화 (NO_COLOR 환경 변수도 적용됨)
--timeout N 요청당 타임아웃(초) (기본값: 20)
--brief 배너나 단계 없이 한 줄 결과 출력
종료 코드: 0 VULNERABLE, 1 부분 노출/취약하지 않음/노출되지 않음, 2 전송 오류.
이 도구는 다음 조건이 모두 충족되어야 VULNERABLE 결과를 반환할 수 있습니다:
/guest/* 핸들러는 관리 포트(8443)와 전용 게스트 포털 포트(8843, 8880)에서 모두 디스패치됩니다. 도구는 제공된 URL만 프로브합니다.guest_access 설정에서 portal_customized: true가 설정되어 있어야 합니다. 이는 디스크 읽기 코드 경로의 전제 조건입니다. 여러 사이트가 있는 컨트롤러는 사이트 중 하나라도 이 설정이 활성화되어 있으면 악용 가능합니다.어떤 조건이라도 충족되지 않으면 도구는 더 보수적인 결과를 반환합니다. PARTIALLY EXPOSED 결과는 여전히 애플리케이션이 취약하며 패치가 필요하다는 것을 의미합니다. 조회된 사이트가 단순히 디스크 읽기 경로를 노출하지 않는 것뿐입니다.
취약한 요청 패턴은 다음과 같습니다:
GET /guest/s/<site>/wechat/sign?page_error=<value>
정상 클라이언트는 /guest/s/<site>/wechat/sign에 POST 방식으로만 접근합니다(디스패처가 이를 수락하며 오류 페이지 렌더러를 호출하지 않음). page_error= 쿼리 매개변수, 특히 ../, %2e%2e, 또는 선행 /를 포함하는 이 엔드포인트에 대한 모든 GET 요청은 비정상적이며 악용 시도로 간주되어야 합니다. Tomcat의 표준 액세스 로그는 쿼리 문자열을 포함한 전체 요청 라인을 캡처합니다.
이 코드는 MIT 라이선스에 따라 배포됩니다.
사전 상호 동의 없이 대상을 공격하기 위해 이 도구를 사용하는 것은 불법입니다. 최종 사용자는 모든 관련 지역, 주, 연방 법률을 준수할 책임이 있습니다. 개발자는 어떠한 책임도 지지 않으며, 이 프로그램의 오용이나 손해에 대해 책임지지 않습니다.