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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-39987 — CVE-2026-39987 탐지 및 익스플로잇 툴킷으로, Marimo 노트북의 사전 인증 RCE(원격 코드 실행) 취약점입니다. WebSocket 엔드포인트 검사를 통해 취약한 인스턴스를 식별하는 Python 스캐너와 Nmap NSE 스크립트가 포함되어 있습니다. | Kitploit
도구/GitHubGitHub/keraattin/cve-2026-39987
Vulnerability ScannersVulnerability AnalysisExploitationWeb Application ExploitationInformation GatheringWeb SecurityNetwork SecurityPenetration Testing
GitHubkeraattin/cve-2026-39987

CVE-2026-39987

CVE-2026-39987 탐지 및 익스플로잇 툴킷으로, Marimo 노트북의 사전 인증 RCE(원격 코드 실행) 취약점입니다. WebSocket 엔드포인트 검사를 통해 취약한 인스턴스를 식별하는 Python 스캐너와 Nmap NSE 스크립트가 포함되어 있습니다.

저장소 보기
14개월 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-39987 — Marimo Python Notebook 사전 인증 원격 코드 실행

CVE-2026-39987 CVSS 9.3 CWE-306 Marimo Pre-Auth RCE

TL;DR

Marimo(데이터 과학 및 AI/ML용 오픈소스 Python 노트북)에서 사전 인증 원격 코드 실행 취약점이 발견되었습니다. 터미널 WebSocket 엔드포인트(/terminal/ws)는 인증 검증을 완전히 건너뛰는 반면, 인접한 노트북 엔드포인트(/ws)는 이를 올바르게 강제합니다. 인증되지 않은 공격자는 /terminal/ws에 연결하여 자격 증명 없이 호스트 시스템에서 완전한 대화형 PTY 셸을 얻을 수 있습니다.

공개 후 10시간 이내에 실제 환경에서 악용되었습니다. 공격자는 3분 이내에 AWS 자격 증명을 탈취했습니다.

영향: Marimo <= 0.20.4. Marimo 0.23.0에서 수정됨.


목차

  • 요약 정보
  • Marimo란 무엇인가?
  • 취약점 심층 분석
    • 두 개의 WebSocket 엔드포인트
    • 누락된 인증 검사
    • 공격: 공개부터 AWS 키 탈취까지 3분
  • 영향 분석
  • 영향받는 버전
  • 더 큰 그림: 공격받는 AI/ML 툴체인
  • 탐지
    • Python 스캐너
    • Nmap NSE 스크립트
    • 수동 검증
  • 침해 지표
  • 수정 및 완화
  • 참고 자료
  • 작성자

요약 정보

필드세부 내용
CVE IDCVE-2026-39987
공급업체Marimo 프로젝트
제품Marimo (Python 노트북)
영향받는 버전<= 0.20.4
CVSS v3.19.3 (치명적)
CWECWE-306 — 중요 기능에 대한 인증 누락
공격 경로네트워크
인증필요 없음
사용자 상호작용없음
악용 성숙도실제 환경에서 활발히 악용됨
악용까지 걸린 시간공개 후 약 10시간
패치 버전Marimo 0.23.0

Marimo란 무엇인가?

Marimo는 Jupyter의 현대적인 대안으로 설계된 오픈소스 반응형 Python 노트북입니다. 데이터 과학, AI/ML 실험, 대화형 데이터 분석을 위해 구축되었습니다. 주요 기능으로는 자동 종속성 추적, 재현 가능한 실행, 기존 노트북보다 깔끔한 개발자 경험이 있습니다.

Marimo는 Python 및 AI/ML 커뮤니티에서 빠르게 채택되고 있으며, 특히 Jupyter가 제공하는 것보다 더 구조화된 노트북 워크플로우를 원하는 실무자들 사이에서 인기를 얻고 있습니다.

모든 노트북 환경과 마찬가지로 Marimo 인스턴스는 일반적으로 민감한 리소스에 접근할 수 있습니다: 클라우드 자격 증명(AWS, GCP, Azure), 데이터베이스 연결 문자열, AI 서비스용 API 키(OpenAI, Anthropic 등), 내부 네트워크 접근 권한 등입니다. 기존 웹 애플리케이션과 달리 노트북은 임의 코드를 실행하도록 설계되었습니다. 그것이 핵심 목적입니다.

이러한 조합은 노트북 환경에서의 인증 우회를 특히 치명적으로 만듭니다.``` Typical Marimo Deployment:

┌──────────────┐ ┌────────────────────────────────┐ │ │ HTTP │ Marimo Server │ │ Browser │────────>│ │ │ (User) │ │ ┌──────────────────────────┐ │ │ │<────────│ │ /ws (Notebook) │ │ └──────────────┘ WS │ │ ✅ validate_auth() │ │ │ └──────────────────────────┘ │ │ │ │ ┌──────────────────────────┐ │ │ │ /terminal/ws │ │ │ │ ❌ NO AUTH CHECK │ │ │ └──────────────────────────┘ │ │ │ │ ┌──────────────────────────┐ │ │ │ Python Environment │ │ │ │ .env files │ │ │ │ AWS credentials │ │ │ │ API keys │ │ │ └──────────────────────────┘ │ └────────────────────────────────┘

root@kitploit:~
---

## 취약점 심층 분석

### 두 개의 WebSocket 엔드포인트

Marimo 서버는 다양한 기능을 위해 여러 WebSocket 엔드포인트를 구현합니다. 두 주요 엔드포인트 간의 중요한 차이점은 인증 검사의 존재(또는 부재)입니다:```
  Authentication Flow Comparison:

  /ws (Notebook WebSocket):
  ┌─────────┐    ┌───────────────┐    ┌──────────┐    ┌───────────┐
  │ Connect │───>│ validate_auth │───>│  Accept  │───>│ Notebook  │
  └─────────┘    └───────┬───────┘    └──────────┘    └───────────┘
                         │
                    ❌ Reject if
                    not authenticated

  /terminal/ws (Terminal WebSocket):
  ┌─────────┐    ┌───────────────┐    ┌──────────┐    ┌───────────┐
  │ Connect │───>│ Check mode &  │───>│  Accept  │───>│ PTY Shell │
  └─────────┘    │ platform only │    └──────────┘    └───────────┘
                 └───────────────┘
                 ⚠️ No auth check!
                 Anyone gets a shell!

누락된 인증 검사

노트북 엔드포인트(/ws)는 WebSocket 연결을 수락하기 전에 사용자 신원을 확인하기 위해 validate_auth()를 올바르게 호출합니다. 이는 예상되는 보안 동작입니다.

터미널 엔드포인트(/terminal/ws)는 서버가 실행 모드에 있는지와 플랫폼이 터미널 기능을 지원하는지만 확인합니다. validate_auth()를 절대 호출하지 않습니다. 이러한 기본 검사를 통과한 후에는 연결을 수락하고 완전한 PTY(의사 터미널) 세션을 생성합니다.```python

/ws (Notebook) — CORRECT implementation

async def websocket_connect(self, message): await self.validate_auth() # ✅ Checks authentication await self.accept() # ... notebook communication

/terminal/ws (Terminal) — VULNERABLE implementation

async def websocket_connect(self, message): if not self.is_running_mode(): # Only checks mode await self.close() return if not self.is_platform_supported(): # Only checks platform await self.close() return await self.accept() # ❌ No auth! Anyone gets a shell # ... PTY shell creation

root@kitploit:~
이것은 **CWE-306: 중요 기능에 대한 인증 누락**입니다. 서버에서 가장 위험한 엔드포인트(대화형 셸을 제공하는 엔드포인트)에는 인증이 전혀 없습니다.

### 공격: 3분 만에 AWS 키 탈취

악용 타임라인은 현대 위협 행위자들이 얼마나 빠르게 움직이는지 보여줍니다:```
  ┌──────────────────────────────────────────────────────────────┐
  │                   CVE-2026-39987 Timeline                    │
  ├──────────────────────────────────────────────────────────────┤
  │                                                              │
  │  T+0h        Advisory published                              │
  │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                       │
  │  T+9h        First exploit built from advisory               │
  │  T+10h       Exploitation in the wild confirmed              │
  │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                       │
  │  T+10h 0m    Attacker connects to /terminal/ws               │
  │  T+10h 1m    Full PTY shell obtained                         │
  │  T+10h 2m    .env file located and read                      │
  │  T+10h 3m    AWS keys exfiltrated                            │
  │              Total attack time: ~3 minutes                   │
  └──────────────────────────────────────────────────────────────┘

공격 자체는 매우 단순합니다:``` Step 1: Attacker opens WebSocket connection to /terminal/ws (No authentication needed, no special tools required)

Step 2: Server creates a PTY (pseudo-terminal) session Attacker now has an interactive shell

Step 3: Attacker runs commands: $ cat .env AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... DATABASE_URL=postgres://... OPENAI_API_KEY=sk-...

Step 4: Credentials exfiltrated Attacker now has cloud access, database access, and API keys for AI services

Total time: under 3 minutes Authentication required: none Tools required: any WebSocket client

root@kitploit:~
No exploit development needed. No shellcode. No memory corruption. Just a WebSocket client and a missing auth check.

---

## Impact Analysis

**Marimo 호스트에 대한 즉각적인 영향:**
- Marimo 프로세스의 권한을 가진 완전한 대화형 셸
- 프로세스가 읽을 수 있는 모든 파일에 대한 접근(소스 코드, 데이터, 자격 증명)
- API 키와 비밀번호가 포함된 환경 변수에 대한 접근
- 호스트 시스템에서 임의 명령 실행 능력

**자격 증명 노출(주요 공격 목표):**
- `.env` 파일 또는 환경 변수의 AWS 액세스 키와 시크릿 키
- GCP/Azure 서비스 계정 자격 증명
- 비밀번호가 포함된 데이터베이스 연결 문자열
- OpenAI, Anthropic 및 기타 AI 서비스 API 키
- SSH 키 및 기타 인증 자료

**다운스트림 영향(도난된 자격 증명을 통한):**
- 클라우드 인프라에 대한 무단 접근(EC2, S3, Lambda 등)
- 클라우드 스토리지 및 데이터베이스에서 데이터 유출
- 리소스 남용(암호화폐 채굴, AI API 크레딧 도용)
- 클라우드 및 온프레미스 네트워크로의 측면 이동

**위험 증폭 요인:**
- 노트북 환경은 임의 코드를 실행하도록 설계됨(그것이 목적임)
- 데이터 과학 환경은 일반적으로 학습 작업을 위해 광범위한 클라우드 접근 권한을 가짐
- 많은 Marimo 인스턴스가 협업 및 원격 작업을 위해 인터넷에 노출됨
- 연구/실험 환경에서는 보안 강화가 종종 후순위로 밀림

---

## 영향을 받는 버전

| 버전 | 상태 |
|---------|--------|
| Marimo 0.23.0+ | **패치됨** |
| Marimo 0.20.5 ~ 0.22.x | **취약할 가능성 높음**(권고 범위와 수정 사이) |
| Marimo <= 0.20.4 | **취약함**(확인된 범위) |

---

## 더 큰 그림: 공격받는 AI/ML 도구 체인

CVE-2026-39987은 고립된 사건이 아닙니다. 이는 2026년 4월에 나타난 명확한 패턴의 일부입니다:

| CVE | 제품 | 유형 | 상태 |
|:---|:---|:---|:---|
| **CVE-2026-39987** | Marimo | 사전 인증 RCE(WebSocket) | 10시간 만에 악용됨 |
| **CVE-2026-33017** | Langflow | RCE | CISA KEV(3월 26일) |
| **CVE-2026-5059** | aws-mcp-server | 명령 주입 RCE | 공개 권고 |
| **TorchGeo** | TorchGeo | eval() RCE | 공개 권고 |

단 한 달 만에 4개의 AI/ML 개발 도구가 심각한 RCE 취약점에 노출되었습니다. AI/ML 개발 파이프라인은 새로운 섀도우 IT가 되고 있습니다: 광범위한 접근 권한, 최소한의 보안 감독, 그리고 풍부한 자격 증명 저장소를 갖춘 채 배포되는 도구들입니다.```
  ┌─────────────────────────────────────────────────┐
  │        Why AI/ML Tools Are Prime Targets        │
  ├─────────────────────────────────────────────────┤
  │                                                 │
  │  1. DESIGNED to execute arbitrary code          │
  │     (that's literally what notebooks do)        │
  │                                                 │
  │  2. Run with elevated privileges                │
  │     (GPU access, cloud SDKs, network access)    │
  │                                                 │
  │  3. Contain high-value credentials              │
  │     (AWS keys, API tokens, DB connections)      │
  │                                                 │
  │  4. Often exposed to the network                │
  │     (for collaboration and remote access)       │
  │                                                 │
  │  5. Security hardening is an afterthought       │
  │     (focus on features and UX, not security)    │
  │                                                 │
  │  6. Users are researchers, not security experts │
  │     (default configs, weak passwords, no VPN)   │
  └─────────────────────────────────────────────────┘

감지

Python 스캐너

Python 스크립트는 다단계 분석을 통해 취약한 Marimo 인스턴스를 감지합니다.

작동 방식:

  1. Marimo 식별 — /api/status, /api/health, /를 쿼리하여 응답 콘텐츠와 헤더에서 Marimo 표시를 확인합니다
  2. 버전 추출 — API 응답, 서버 헤더, HTML 콘텐츠에서 버전 정보를 파싱합니다
  3. WebSocket 핸드셰이크 테스트 — /terminal/ws에 안전한 HTTP 업그레이드 요청을 전송합니다(연결을 통해 데이터는 전송되지 않음)
  4. 차등 인증 확인 — /terminal/ws(인증이 필요해야 함)와 /ws(인증이 필요한 것으로 알려짐)의 동작을 비교하여 불일치를 확인합니다
  5. 버전 취약점 확인 — 감지된 버전을 취약 범위(<= 0.20.4) 및 패치 버전(>= 0.23.0)과 비교합니다

대상 시스템에서 실행되는 명령은 없습니다. WebSocket 핸드셰이크는 테스트되지만 연결을 통해 데이터는 전송되지 않습니다. 이 확인은 완전히 수동적이며 프로덕션 환경에 안전합니다.

사용법:```bash

Install dependencies

pip install -r requirements.txt

Single target (Marimo default port: 2718)

python CVE-2026-39987_Marimo_RCE_detector.py -t http://marimo-host:2718

HTTPS target

python CVE-2026-39987_Marimo_RCE_detector.py -t https://marimo-host:443

Bulk scan from file with verbose output

python CVE-2026-39987_Marimo_RCE_detector.py -f targets.txt -o results.json -v

Increased timeout for slow networks

python CVE-2026-39987_Marimo_RCE_detector.py -t http://10.0.0.5:2718 --timeout 15

root@kitploit:~
**옵션:**

| 플래그 | 설명 | 기본값 |
|------|-------------|---------|
| `-t`, `--target` | 단일 대상 URL (예: `http://host:2718`) | — |
| `-f`, `--file` | 대상 URL이 한 줄에 하나씩 포함된 파일 (`#` 주석 지원) | — |
| `-o`, `--output` | 결과를 JSON 파일로 저장 | — |
| `--timeout` | 연결 제한 시간(초) | `10` |
| `--verify-ssl` | SSL 인증서 검증 활성화 | 비활성화 |
| `-v`, `--verbose` | 전체 세부 정보가 포함된 자세한 출력 | 꺼짐 |

**출력 예시:**```
[*] CVE-2026-39987 Marimo Pre-Auth RCE Scanner
[*] Scanning 1 target(s)...
[*] NOTE: This scanner only checks for endpoint exposure.
[*]       No commands are executed on target systems.

======================================================================
Target: http://10.0.0.5:2718
Scan Time: 2026-04-14T16:00:00Z
Risk Level: CRITICAL
======================================================================
  Is Marimo:             YES
  Marimo Version:        0.19.2
  /terminal/ws Open:     YES — UNAUTHENTICATED
  Vulnerable:            YES

  *** CRITICAL: Pre-authenticated RCE is possible! ***
  *** An attacker can get a full PTY shell without any auth ***

  Details:
    - Marimo instance detected via /api/status
    - Marimo version: 0.19.2
    - WebSocket upgrade accepted — /terminal/ws accessible WITHOUT auth
    - CONFIRMED: /terminal/ws accepts unauthenticated connections while
      /ws requires auth — classic CVE-2026-39987 signature
    - Version 0.19.2 <= 0.20.4 — VULNERABLE to pre-auth RCE

======================================================================
[*] Scan Complete: 1 targets scanned
[*] Marimo Instances: 1 | Vulnerable: 1 | Critical: 1
======================================================================

Nmap NSE 스크립트```bash

Install the NSE script

sudo cp CVE-2026-39987_Marimo_RCE.nse /usr/share/nmap/scripts/ sudo nmap --script-updatedb

Basic scan (Marimo default port: 2718)

nmap -p 2718 --script CVE-2026-39987_Marimo_RCE

Scan common ports where Marimo might run

nmap -p 2718,8080,8443,443 --script CVE-2026-39987_Marimo_RCE

Subnet scan

nmap -p 2718 --script CVE-2026-39987_Marimo_RCE 10.0.0.0/24

Scan targets from a file

nmap -p 2718 --script CVE-2026-39987_Marimo_RCE -iL targets.txt

With service version detection

nmap -sV -p 2718 --script CVE-2026-39987_Marimo_RCE

root@kitploit:~
**Nmap 출력 예시:**```
PORT     STATE SERVICE
2718/tcp open  http
| CVE-2026-39987_Marimo_RCE:
|   VULNERABLE:
|   Marimo Pre-Auth RCE (CVE-2026-39987)
|     State: VULNERABLE
|     Risk level: CRITICAL
|     Marimo Version: 0.19.2
|     /terminal/ws: accessible without authentication
|     Description:
|       The Marimo /terminal/ws WebSocket endpoint accepts connections
|       without authentication, enabling pre-authenticated RCE.
|       An attacker can obtain a full PTY shell without any credentials.
|     References:
|_      https://nvd.nist.gov/vuln/detail/CVE-2026-39987

수동 검증

Marimo 인스턴스에 접근할 수 있는 경우:```bash

Check Marimo version via API

curl -s http://:2718/api/status | python3 -m json.tool

Test WebSocket upgrade on /terminal/ws (should NOT succeed without auth)

curl -s -o /dev/null -w "%{http_code}"
-H "Upgrade: websocket"
-H "Connection: Upgrade"
-H "Sec-WebSocket-Key: dGVzdC1rZXktMTIzNDU2Nzg="
-H "Sec-WebSocket-Version: 13"
http://:2718/terminal/ws

If it returns 101 (Switching Protocols), the endpoint is open without auth

If it returns 401/403, authentication is enforced (patched or hardened)

For comparison, test /ws (should always require auth)

curl -s -o /dev/null -w "%{http_code}"
-H "Upgrade: websocket"
-H "Connection: Upgrade"
-H "Sec-WebSocket-Key: dGVzdC1rZXktMTIzNDU2Nzg="
-H "Sec-WebSocket-Version: 13"
http://:2718/ws

root@kitploit:~
If `/terminal/ws`가 101을 반환하고 `/ws`가 401/403을 반환한다면, 이는 전형적인 CVE-2026-39987 시그니처입니다.

---

## 침해 지표

사용자 환경에서 다음 징후를 확인하세요:

| 지표 | 확인 위치 | 찾아야 할 것 |
|:---|:---|:---|
| 승인되지 않은 WebSocket 연결 | 서버/프록시 로그 | 예상치 못한 IP에서 `/terminal/ws`로의 연결 |
| PTY 세션 생성 | 프로세스 모니터링 | Marimo 서버에 의해 생성된 예상치 못한 셸 프로세스 |
| 파일 접근 | 파일 감사 로그 | `.env`, 자격 증명 파일 또는 SSH 키 읽기 |
| 자격 증명 사용 | 클라우드 제공업체 감사 로그 | Marimo 환경에 저장된 키를 사용한 API 호출 |
| 외부 데이터 전송 | 네트워크 모니터링 | Marimo 호스트에서 발생하는 비정상적인 이그레스 트래픽 |

**조사 명령:**```bash
# Check for active WebSocket connections
ss -tnp | grep <MARIMO_PORT>

# Review process tree for unexpected shells
ps aux --forest | grep -A5 marimo

# Check if .env or credential files were recently accessed
stat .env
stat ~/.aws/credentials

# Review cloud provider activity logs for unauthorized access
aws cloudtrail lookup-events --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=<KEY_ID>

# Check for unauthorized outbound connections
netstat -tnp | grep ESTABLISHED | grep -v 127.0.0.1

해결 방안

즉시 조치 (지금 바로 수행):

  1. Marimo 0.23.0 이상으로 업그레이드 (pip install --upgrade marimo)
  2. 방화벽 규칙으로 Marimo 인스턴스에 대한 네트워크 접근 제한 (localhost 또는 신뢰할 수 있는 IP에만 바인딩)
  3. 서버 로그에서 무단 연결 확인

단기 조치 (이번 주 내):

  1. Marimo 환경에서 접근 가능했던 모든 자격 증명 교체 (AWS 키, API 토큰, 데이터베이스 비밀번호, 클라우드 서비스 계정)
  2. 클라우드 제공업체 활동 로그 감사 — 잠재적으로 유출된 자격 증명을 사용한 무단 API 호출 확인
  3. .env 파일 및 환경 변수 검토 — 노출되었을 수 있는 민감한 데이터 확인
  4. 지속성 메커니즘 확인 (무단 SSH 키, cron 작업, 수정된 시작 스크립트)

장기 조치:

  1. 노트북 환경을 인터넷에 직접 노출하지 않기 (VPN 또는 SSH 터널 사용)
  2. AI/ML 개발 환경을 고보안 자산으로 취급 (클라우드 자격 증명을 포함하고 코드 실행 기능이 있음)
  3. 정기적인 취약점 스캔 프로그램에 노트북 서버 포함
  4. 노트북 서버 인스턴스에 대한 네트워크 모니터링 구현 — 예상치 못한 연결 시 알림 설정

참고 자료

  • The Hacker News — Marimo RCE Flaw CVE-2026-39987 Exploited Within 10 Hours
  • SecurityWeek — Critical Marimo Flaw Exploited Hours After Public Disclosure
  • BleepingComputer — Critical Marimo Pre-Auth RCE Flaw Now Under Active Exploitation
  • Security Affairs — CVE-2026-39987: Marimo RCE Exploited in Hours After Disclosure
  • CSA Labs — Marimo Pre-Auth RCE: AI Development Toolchain Under Attack
  • GBHackers — Marimo RCE Vulnerability Exploited Within 10 Hours
  • InfoWorld — Critical Flaw in Marimo Python Notebook Exploited Within 10 Hours

작성자

Kerem Oruç — 사이버보안 엔지니어

  • GitHub: @keraattin
  • Twitter: @keraattin
도구 다운로드