pfSense Plus MIM API 툴킷 b4acd7ca - 높음 - 원격 - IDOR - ACB userkey 기능 URL
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-acb-userkey
분류: IDOR 도달 범위: 원격
pfSense Plus MIM API (Netgate/pfsense-api b4acd7ca) - Netgate
GET /services/acb와 GET /services/acb/bkp는 userkey를 제약 없는 쿼리 파라미터로 받는다. 생성된 Python 클라이언트는 해당 키를 쿼리 문자열에 넣는다. YAML에는 securitySchemes가 없다. Auto Config Backup 디바이스 키의 보유 여부가 검증 수단이다. 이는 기능 URL(capability URL)이다.
탈취되거나 유출된 ACB userkey는 해당 디바이스의 호스팅된 백업 목록을 나열하고 리비전 본문을 가져온다. 전체 설정이 그 블롭 안에 들어 있다. 키가 유출될 경우 CE ACB 키 CVE-2024-57273 / SA-25_03과 동일한 부류다. 그 CVE는 SSH 배너 도출이었다. 이 잔여물은 Plus MIM API 쿼리 파라미터 형제 격이다. 나는 배너 도출을 다시 신고하지 않는다.
이것은 pfSense Plus Nexus Multi-instance Management(컨트롤러는 :8443)를 위한 공개 OpenAPI + 생성된 클라이언트다. CE REST 패키지(jaredhendrickson/pfsense-api / pfrest.org)가 아니다. 서버는 Plus 전용(유료)이다. 나는 pfSense Plus를 실행하지 않았다.
| ID | 아직 CVE 없음 |
| 분류 | IDOR (기능 URL) |
| 도달 범위 | 원격 |
| CWE | CWE-639 |
| CVSS | 높음: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N — 해당 GET들이 JWT를 디바이스에 바인딩하지 않고 userkey를 존중할 경우 |
| 제품 | Netgate/pfsense-api (pfSense Plus MIM OpenAPI + 생성된 클라이언트) |
| 영향받음 | 핀 b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25). 태그 없음. |
| 인증 | 스펙: 없음 (securitySchemes 부재). userkey가 쿼리 시크릿이다. Plus JWT/RBAC는 실행되지 않았다. |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1:19171 전용. Plus 이미지 없음. |
시리즈 허브: pfsense-api-nexus-mim (이것은 파트 7이다).
탈취되거나 유출된 ACB userkey가 필요하다(스펙: "hexidecimal encoded 32-byte random bytes", 64 hex). 스펙은 해당 키를 JWT나 호출자의 디바이스에 바인딩하지 않는다. G11급 GET /services/acb/config는 라이브 userkey를 반환한다. G9 샘플은 verify_ssl=False로 설정되어 있어, :8443의 MITM이 키를 와이어 상에서 볼 수 있다. 이것들이 유출 경로다. 이 잔여물은 키가 유출된 후 그 키로 살 수 있는 것이다.
| Method | Sink | Privilege |
|---|---|---|
GET /services/acb?userkey=<stolen> | GetACBList (pfapi_openapi.yml). 생성된 get_acb_list.py params["userkey"]. | 실험실 입증 (mock): 해당 장치가 호스팅하는 백업 목록. backups[].reason에서 확인 가능. |
GET /services/acb/bkp?userkey=<stolen>&revision= | GetACB -> RetrievedBackup.backup. 생성된 get_acb.py params["userkey"] + params["revision"]. | 실험실 입증 (mock): 리비전 본문을 가져옴. backup에서 확인 가능. |
| 라이브 컨트롤러에서 동일한 백업 문자열 | 호스팅된 ACB blob | 추론: 읽을 수 있게 되면 전체 config.xml (사용자, 키, 패키지). Mock은 평문 확인용 XML을 반환함. acb.netgate.com과 통신하거나 라이브 blob을 복호화하지는 않음. |
GET /services/acb/config | ACBConfigInfo.userkey, ACBConfig.encryption_password | 명세상, 이 실험실 아님: 라이브 기능 시크릿 및 복호화 비밀번호. G11 secrets-on-GET 클래스. 실행되지 않음. |
| Method | Sink | Privilege |
|---|---|---|
POST /services/acb/restore | RestoreACB body { timestamp } | 인접 폐쇄: 샘플은 여전히 JWT를 전송함. 이 잔여물 아님. 실행되지 않음. |
POST /services/acb/config replace userkey | SaveACBConfig | 인접 폐쇄: GET 기능 URL이 아님. 실행되지 않음. |
GET list / GET bkp는 삭제하지 않음. DELETE /services/acb/bkp/{timestamp}는 다른 작업임. 실행되지 않음.
잘못된 userkey와 누락된 userkey는 확인 증거를 반환하지 않음 (실험실 입증).
실험실 입증 vs 추론: 탈취된 키 list와 bkp는 확인 증거를 반환함. 잘못된 키와 누락된 키는 반환하지 않음. Plus는 실행되지 않음. 라이브 config.xml 내용과 복호화는 공개 스키마에서 추론됨 (RetrievedBackup.backup은 문자열; encryption_password는 ACBConfig에 위치).
요구 사항: MIM 컨트롤러 ACB GET에 대한 네트워크 경로, 그리고 탈취/유출된 userkey. 해당 GET이 JWT를 장치에 바인딩하지 않고 쿼리 키를 존중한다면 CVSS 7.5. 솔직히: 이 팩은 공개 명세가 해당 계약을 모델링함을 루프백에서 입증함.
| Surface | Why |
|---|---|
| pfSense Plus 컨트롤러 | 실행되지 않음. 이 팩에 Plus 이미지 없음. |
| CE REST 패키지 | 다른 서버 (jaredhendrickson/pfsense-api / pfrest.org). |
| SSH-banner ACB 키 파생 | CVE-2024-57273 / SA-25_03. 재신고하지 말 것. |
이 발견으로서의 POST /services/acb/restore | 샘플은 여전히 JWT를 전송함. |
누락된 OAS security로 인한 비인증 php/shell | 문서 잔여물. Mock은 JWT 없는 200 서버 증명이 아님. |
누락된 userkey | 실험실 403, 확인 증거 없음. |
잘못된 userkey | 실험실 list 비어 있음 / bkp 403, 확인 증거 없음. |
생성된 라이브러리 verify_ssl | 기본값 True. G9는 이를 끄는 샘플이지 패키지 기본값이 아님. |
Netgate/pfsense-api main b4acd7ca (2026-05-25, "Add Snort-3 API definitions")를 고정함. login/JWT, diagnostics, MIM enrollment, client TLS, users/certs, packages, VPN/firewall, OpenAPI security, device IDOR, git/firmware/feeds, 그리고 모든 생성된 작업의 루프백 mock에 걸쳐 12회 탐색.
먼저 건너뛸 목록: 이미 메일로 보고된 CE WebGUI 잔여물 (QinQ parent if, OpenVPN wizard CRLF, CARP VHID, limiter number, IPsec login banner). Diagnostics PHP/shell은 의도된 관리자 권한. 서드파티 CE REST 패키지. CVE-2024-57273 banner 파생.
GetACBList와 GetACB를 읽었다. userkey는 쿼리 파라미터이지 바인딩된 디바이스 id가 아니다. 생성된 Python은 이를 쿼리 문자열에 복사한다. YAML에 securitySchemes가 없다. ACBConfigInfo.userkey는 "16진수로 인코딩된 32바이트 랜덤 바이트"이다. GET /services/acb/config가 그 키를 반환한다. G9 샘플은 TLS 검증을 비활성화하므로 MITM이 이를 유출할 수 있다. G11은 GET 덤프이다. 이 잔여물은 그 덤프가 공급하는 기능 URL이다.
잘못된 방향: 누락된 OAS 보안을 unauth php/shell로 취급하는 것; CVE-2024-57273을 다시 제출하는 것; 라이브 Plus 덤프를 주장하는 것. 극적인 요소: Plus 컨트롤러. 오라클은 공개 스펙과 루프백 목이다.
python3 pfsense-api-acb-userkey-Abraxas-Labs.py
또는
cd lab
./run.sh
Loopback 전용: http://127.0.0.1:19171. Compose 프로젝트 pfsense-api-acb-userkey. Witness PFSENSE-API-ACB-USERKEY-WITNESS. Docker. Plus 이미지 없음.
예상 마지막 줄:
SUCCESS pfsense-api-acb-userkey capability-url stolen-key-returns-witness wrong-key-does-not plus-not-executed public-spec-models-acb-userkey-capability-url PFSENSE-API-ACB-USERKEY-WITNESS
정직하게: Plus는 실행되지 않았습니다. 탈취된 키는 증인을 반환했습니다. 잘못된 키는 그렇지 않았습니다. 공개 명세는 ACB userkey를 기능 URL로 모델링합니다.
ACB GET에 JWT를 요구하십시오. userkey를 기능 URL로 취급하지 마십시오. 목록 조회와 검색을 인증된 장치의 키에 바인딩하십시오. 외부 호출자로부터 다른 장치의 키를 받아들이지 마십시오. 이미 장치 소유자가 아닌 모든 역할에 대해 GET config에서 라이브 userkey와 encryption_password를 반환하는 것을 중단하십시오.