ZeroHour
GBHackerspublished ()ingested Divya
Part of a story covered by 4 sources: “Human Attacker Hits Machine-Speed Exploitation of Marimo RCE CVE-2026-39987” — merged summary and timeline →

Marimo RCE Flaw Lets Hackers Steal AWS Credentials and Pivot to Bastion Host in 8 Seconds

criticalExploit / PoC exploited in the wildimportance 72CVE-2026-39987
AI summary · glm-5.3

Attacker exploited unauthenticated marimo WebSocket RCE CVE-2026-39987 to steal AWS credentials and SSH into a bastion host in eight seconds.

Sysdig Threat Research Team documented a real intrusion exploiting CVE-2026-39987 in marimo (versions up to 0.20.4, fixed in 0.23.0), where the unauthenticated /terminal/ws WebSocket endpoint exposed an interactive shell. Within eight seconds the attacker pulled AWS credentials from Redis, extracted an SSH private key from AWS Secrets Manager via Boto3, and authenticated to a bastion host; over nine hours the operator ran 850+ commands using a staged custom Python toolkit. Blocked EC2 Instance Connect attempts (SendSSHPublicKey to placeholder instance i-0000000000000000) provide a high-confidence detection signal.

  • CVE-2026-39987: unauthenticated /terminal/ws WebSocket shell in marimo, fixed in 0.23.0
  • AWS credential theft to Secrets Manager key retrieval to bastion SSH completed in eight seconds
  • Attacker staged custom Python automation scripts in /tmp after four hours of development
  • Two distinct IAM identities used; 850+ interactive commands over nine-hour intrusion
  • Defenders should hunt /terminal/ws connections, keys in /tmp, and port 4444 callbacks

Vulnerabilities mentionedAll →

CVEVulnerabilityCVSSEPSSFlagsAffectedExposurePublished
CVE-2026-39987
Unauthenticated Remote Code Execution in Marimo Python Notebook

Marimo, a reactive Python notebook, contains an unauthenticated remote code execution flaw (CVE-2026-39987, CWE-306; CVSS 4.0: 9.3 Critical) because its terminal WebSocket endpoint /terminal/ws skips authentication entirely. Unlike other WebSocket endpoints such as /ws, which call validate_auth(), /terminal/ws only checks the running mode and platform support before accepting connections, so any unauthenticated attacker who can reach the server can obtain a full PTY shell and execute arbitrary system commands on the host. All marimo deployments running versions prior to 0.23.0 are affected, with internet-exposed instances at greatest risk. Exploitation is confirmed in the wild: the flaw was added to CISA's KEV catalog on 2026-04-23, public PoCs exist, and reporting shows it was exploited within roughly 10 hours of disclosure, with observed post-exploitation activity involving LLM agents. EPSS assigns a 98.9% probability of exploitation within 30 days (100th percentile).

Do: Upgrade marimo to 0.23.0 or later; until patched, restrict access to the /terminal/ws WebSocket endpoint by binding the notebook to localhost, a VPN, or an authenticating reverse proxy. Identify whether any marimo instances are internet-exposed and review logs for connections to /terminal/ws and unexpected shell or process spawns, given reports of LLM-agent-driven post-exploitation on compromised instances. As a KEV entry (added 2026-04-23), this requires federal agencies to apply the vendor fix or mitigations per BOD 22-01 timelines.

9.399% KEV PoC ×4
  • Marimo (reactive Python notebook) all versions prior to 0.23.0
  • CoreWeave marimo all versions prior to 0.23.0
moderatelikely tens of thousands of users, with directly internet-exposed marimo servers plausibly in the low thousands
Full article687 words · extracted from gbhackers.com · click to collapse

A threat actor exploited a critical pre-authentication remote code execution vulnerability in marimo to harvest AWS credentials, retrieve an SSH private key from AWS Secrets Manager, and authenticate to a bastion host in just eight seconds, according to the Sysdig Threat Research Team.

This vulnerability, tracked as CVE-2026-39987, affects marimo versions up to 0.20.4 and was fixed in version 0.23.0.

The issue originates in the /terminal/ws WebSocket endpoint, which exposed an interactive pseudo-terminal without enforcing the authentication validation applied to other WebSocket routes.

An attacker able to access this endpoint could obtain a shell as the marimo process user without needing any credentials.

Marimo RCE Flaw

Sysdig observed that the attacker initiated a fresh WebSocket session at 18:57:22 UTC. Just four seconds later, the attacker retrieved AWS credentials stored in the application’s Redis backend.

By 18:57:30, the actor had authenticated to an internet-accessible bastion host using an SSH private key extracted from AWS Secrets Manager.

Researchers did not attribute this rapid progression to an AI agent. Instead, researchers noted that the actor spent about four hours building and debugging a custom Python toolkit during earlier sessions.

Once the toolkit was staged in the /tmp/ directory, the scripts automated tasks such as credential recovery, accessing Secrets Manager, extracting the SSH key, and authenticating to the bastion, all through a single background Python invocation.

Over a nine-hour intrusion, the operator executed more than 850 interactive commands. These commands included probing the local network, validating AWS credentials, calling Secrets Manager APIs, discovering EC2 instances, and preparing reverse-shell infrastructure.

The attacker utilized two separate AWS credential paths. The first credential was collected from environment variables or credential files on the compromised host.

At the same time, the second was retrieved through a Redis lookup against an application-stored credential value. CloudTrail logs indicated that the credentials belonged to different IAM users, suggesting the actor iteratively switched identities after the initial set failed to expose the targeted secret.

The custom scripts used the Boto3 library to call `secretsmanager:GetSecretValue`, including fallback attempts across multiple AWS Regions. The retrieved private key material was saved to `/tmp/bastion_key` with 0600 permissions before being replayed against the bastion.

Additionally, the operator attempted an alternative persistence method through EC2 Instance Connect. AWS logs recorded denied requests for `DescribeInstances`, `DescribeKeyPairs`, and `DescribeInstanceInformation`, followed by a blocked `SendSSHPublicKey` request targeting the placeholder instance ID i-0000000000000000. This sequence may serve as a high-confidence behavioral detection signal.

IOC Table

Indicator typeValueRole / detection context
Source IP172.236.12[.]17Interactive /terminal/ws WebSocket sessions; AS63949 Akamai Connected Cloud/Linode
C2 / relay IP45.79.187[.]72Attacker-controlled VPS used for nc -lvp 4444 callback listener
Vulnerable endpoint/terminal/wsUnauthenticated marimo WebSocket terminal endpoint
Dropped files/tmp/chain.py, /tmp/full_chain.pyBase64-decoded Python automation scripts
SSH key path/tmp/bastion_keyPrivate key retrieved from Secrets Manager and saved with mode 0600
Log artifacts/tmp/chain.log, /tmp/chain_output.txt, /tmp/callback.logOutput files associated with chain execution and listener activity
AWS APIsecretsmanager:GetSecretValueSecret retrieval preceding SSH pivot
AWS API patternDescribeInstances → denied; DescribeKeyPairs → denied; DescribeInstanceInformation → denied; SendSSHPublicKeyFailed EC2 Instance Connect automation sequence
Command patternbase64 -d > /tmp/<name>.py followed by nohup python3Script staging and background execution behavior

Note: IP addresses and domains are intentionally defanged (e.g., [.]) to prevent accidental resolution or hyperlinking. Re-fang only within controlled threat intelligence platforms such as MISP, VirusTotal, or your SIEM.

Organizations should upgrade marimo to version 0.23.0 or later immediately and restrict network access to notebook services. Defenders should hunt for unauthenticated connections to /terminal/ws, unexpected Python processes accessing AWS Secrets Manager, SSH private keys written under /tmp, and outbound connections to unapproved hosts on port 4444.

CloudTrail detections should prioritize the attack chain rather than the apparent operator style: a compromised workload identity calling Secrets Manager, followed closely by SSH authentication, unusual EC2 Instance Connect activity, or outbound callback traffic.

Keep your SOC up to date on active malware & phishing within 24h of their emergence. Try ANYRUN to prevent incidents with early detection

Divya

Divya is a Senior Journalist at GBhackers covering Cyber Attacks, Threats, Breaches, Vulnerabilities and other happenings in the cyber world.

Text extracted automatically; images, tables and formatting may be missing. Original: https://gbhackers.com/marimo-rce-flaw/