flawopen.com/Teardowns/cve-2026-104286-fortimail-ibe-path-traversal
CVE-2026-104286: FortiMail IBE 경로 순회
CVE-2026-104286은 인증되지 않은 HTTP(S) 요청의 경로 순회를 통해 취약한 FortiMail 시스템에 파일을 쓸 수 있게 합니다. Fortinet은 실제 악용을 보고했습니다. IBE를 끄거나 웹 접근을 제한하고 조사 후 업데이트하세요.[1], [5]
직원이 첨부 파일을 정리하는 우편실을 떠올려 보세요. 이 결함은 요청이 잘못된 폴더 경로를 지정해 파일을 예상된 위치 밖에 쓰게 할 수 있습니다. 임시 조치는 IBE를 끄거나 웹 인터페이스 접근을 제한하는 것이며, 이후 업데이트하고 과거 침입 흔적도 조사해야 합니다.[1], [5]
핵심 개념 및 용어
경로 순회 (CWE-22)- 신뢰할 수 없는 경로 구성 요소가 파일 작업의 허용 디렉터리를 벗어납니다. Fortinet은 영향받는 FortiMail에 임의 파일을 쓸 수 있다고 설명합니다.[1], [6]
Identity-Based Encryption (IBE)- FortiMail의 암호화 메일 워크플로 기능입니다. 공급업체의 임시 완화책은 IBE 비활성화이며 운영 영향을 검토해야 합니다.[1], [5]
프레임워크 매핑
- 이 가이드에서 설명하는 약점의 CWE 참조: CWE-22
- CISA KEV — 추가일 2026-10-01 — CVE-2026-104286
근본 원인 분석 (Root Cause)
Fortinet은 CVE-2026-104286을 인증 없이 HTTP 또는 HTTPS 요청으로 임의 파일을 쓸 수 있는 경로 순회 취약점으로 설명합니다. FortiMail 펌웨어는 비공개이며 공개 자문에는 취약한 소스 코드나 패치 diff가 없습니다. 이 글은 이를 추측하지 않습니다. 공개 정부 자문은 임의 파일 쓰기 영향, 악용 및 버전 안내를 확인하지만 FortiMail 내부 핸들러는 설명하지 않습니다. IBE 비활성화 또는 웹 접근 제한 임시 조치와 공개 IOC는 Fortinet 자문을 근거로 합니다. 장비 접근을 제한해 조사한 뒤 해당 수정 버전을 적용하세요. IOC가 없다고 안전한 것은 아닙니다. CVE 레코드의 설명문은 7.2.0–7.2.9, 7.4.0–7.4.8, 7.6.0–7.6.6, 8.0.0–8.0.1을 나열합니다. 구조화 버전 표는 7.4와 7.6의 상한을 더 낮게 표시하고 7.0.0–7.0.9도 추가합니다. 같은 레코드의 solutions 항목은 더 이른 “예정” 버전인 7.4.8, 7.6.6, 8.0.1, 7.2.10을 제시해 영향 버전 데이터 및 10월 1일 캐나다 권고와 충돌합니다. 날짜가 명시된 정부 권고를 공개된 운영 지침으로 사용하고, 현재 제공 여부와 7.0 범위는 Fortinet에 확인하세요. 상충하는 CNA 항목만으로 수정 버전을 추정하지 마세요.[1], [3], [5], [4], [6], [7]
운영 매트릭스: 버전 범위와 초기 대응
| 영역 | 공식 출처의 설명 | 방어자 조치 |
|---|---|---|
| FortiMail 7.0 | NVD/CNA 데이터에는 7.0.0–7.0.9가 포함되지만 캐나다와 프랑스의 공식 요약에는 7.0 분기가 없습니다. 같은 레코드의 설명과 표는 7.4 및 7.6의 상한도 서로 다릅니다. solutions 항목도 영향 범위와 캐나다 권고에 어긋나는 더 낮은 “예정” 빌드(7.4.8, 7.6.6, 8.0.1, 7.2.10)를 나열합니다. | Fortinet에 해당 분기 상태를 확인하고, 요약에 없다는 이유로 안전하다고 추정하지 마세요. |
| FortiMail 7.2 | 캐나다 권고는 7.4 분기 이상으로 업그레이드하도록 안내합니다. | 지원되는 수정 완료 분기로 이전을 계획하고 7.2 패치가 있다고 가정하지 마세요. |
| FortiMail 7.4 / 7.6 / 8.0 | 캐나다 권고는 각각 7.4.9, 7.6.7, 8.0.2를 수정 버전으로 제시합니다. | 공개된 빌드 지침으로 캐나다 권고 AV26-989를 사용하고, 업데이트 전에 Fortinet 최신 자문에서 제공 여부와 지원을 확인하세요. 확인 없이 더 낮은 CNA 기준을 적용하지 마세요. |
| 차단 및 조사 | Fortinet은 악용을 보고하고 침해 지표를 공개했습니다. 임시 조치는 IBE 비활성화 또는 웹 접근 제한입니다. | 증거를 보존하고 임시 조치를 적용한 뒤 지표를 확인하고, 패치와 침해 여부 조사를 진행하세요. |
단계별 공격 실행 흐름
소스 코드 비교: 취약한 구현 vs 보안 패치
FortiMail 펌웨어 소스와 공급업체 패치 diff는 공개되지 않았으므로, 이 코드는 일반적인 Python 방어 패턴이며 Fortinet 코드나 취약점 재현이 아닙니다. 신뢰할 수 있는 디렉터리를 한 번 열고 서버가 생성한 불투명한 파일명을 사용하며, 배타적 생성 및 링크 미추적 플래그를 지정해 해당 디렉터리 디스크립터를 기준으로 새 파일을 만듭니다. POSIX 전용이며 필요한 플래그가 없으면 안전하게 실패합니다. 중첩 경로는 디렉터리 디스크립터로 검증된 구성요소를 하나씩 탐색하고, 문자열 경로를 검사한 뒤 이름으로 다시 여는 방식을 피하세요. CVE-2026-104286은 Fortinet이 지원하는 업데이트 또는 공식 임시 완화책으로 해결하세요. 설정된 루트 경로의 모든 구성요소와 상위 디렉터리는 관리자 통제하에 있어야 합니다. 루트를 열 때 O_NOFOLLOW는 마지막 구성요소만 보호합니다.
from pathlib import Path
def destination(root: Path, request_path: str) -> Path:
# 취약한 설계 예시: 요청 입력을 결합한 뒤
# 허용된 루트 안에 있는지 확인하지 않습니다.
return root / request_path
import os
import uuid
# 신뢰할 수 있는 서비스 디렉터리를 한 번 엽니다. 상위 경로 디렉터리도 관리자가 통제해야 합니다.
def open_upload_root(root):
required = ("O_DIRECTORY", "O_NOFOLLOW")
if not all(hasattr(os, flag) for flag in required) or os.open not in os.supports_dir_fd:
raise RuntimeError("POSIX directory protections unavailable")
flags = os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW
return os.open(root, flags)
# 요청 경로를 파일 경로로 바꾸지 말고 불투명한 이름을 생성합니다.
# 이름이 이미 있으면 O_EXCL이 실패하고 O_NOFOLLOW가 마지막 심볼릭 링크를 거부합니다.
ROOT_FD = open_upload_root("/srv/app-private/uploads")
def create_upload_file():
name = uuid.uuid4().hex
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW
fd = os.open(name, flags, 0o600, dir_fd=ROOT_FD)
return name, fd
엔지니어링 및 시스템 보안 강화 체크리스트
- ✓FortiMail 장비와 버전을 목록화하세요. Fortinet 및 정부 요약은 7.0을 생략하지만 CNA 구조 데이터는 7.0.0–7.0.9를 포함합니다. Fortinet에 확인하세요.[1], [5], [6]
- ✓공급업체 완화책을 즉시 적용하세요. IBE를 끄거나 웹 인터페이스의 공개 접근을 제거하고 신뢰하는 사설 네트워크로 제한하세요. IBE 비활성화 영향을 메일 담당자와 검토하세요.[1]
- ✓재부팅이나 업그레이드 전에 로그, 구성 백업, 포렌식 증거를 보존하세요. FG-IR-26-175의 최신 IOC를 확인하고 일치 항목을 조사하세요.[1], [4]
- ✓공개된 빌드 지침으로 캐나다 권고 AV26-989를 사용하고, 업데이트 전에 Fortinet 최신 자문에서 제공 여부와 지원을 확인하세요. 확인 없이 더 낮은 CNA 기준을 적용하지 마세요.[5], [1], [7]
- ✓패치와 침해 조사를 별도 작업으로 수행하세요. 수정 버전은 이전에 배치된 파일, 자격 증명 또는 지속성을 제거하지 않습니다. 의심 신호가 있으면 사고 대응 절차를 시작하세요.
- ✓자체 파일 처리기에서는 엄격하게 한 번 디코딩한 뒤 허용 루트 기준 canonical path를 확인하고 NUL 및 잘못된 인코딩을 거부하며 신뢰 디렉터리 상대 파일 열기를 사용하세요.