Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsTraining
StudyProjectsNewsletterHire MeAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Training
Study
Projects
Newsletter
Hire Me
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

2844+ Articles
167+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Checklists
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. News
  3. Human Attacker Exploits Marimo RCE, Reaches SSH Bastion in Eight Seconds
Human Attacker Exploits Marimo RCE, Reaches SSH Bastion in Eight Seconds
NEWS

Human Attacker Exploits Marimo RCE, Reaches SSH Bastion in Eight Seconds

Sysdig traced a human attacker from Marimo RCE to SSH bastion access in 8 seconds: no AI, just hand-built tradecraft.

Dylan H.

Security Engineer

September 15, 2026
8 min read

A Human Operator Matches Machine-Speed Exploitation

The Sysdig Threat Research Team (TRT) has published a forensic breakdown of a real intrusion that answers a question defenders have been asking all year: once AI-assisted attackers can chain exploitation and lateral movement in seconds, can a skilled human still keep up without help? In this case, the answer was yes. Sysdig traced a single operator moving from an unauthenticated WebSocket shell on a vulnerable Marimo notebook server to authenticated SSH access on an internal bastion host in eight seconds — using a hand-written Python toolkit, with no AI assistance detected anywhere in the chain.

The underlying flaw is CVE-2026-39987, the critical pre-authentication remote code execution vulnerability in Marimo that CosmicBytez Labs previously covered as a standalone advisory after it landed on CISA's KEV catalog. This piece focuses on what Sysdig observed after that initial foothold — the attacker's tradecraft, tooling, and pace — because it reframes how defenders should think about detection-and-response speed in the post-AI-attacker era.


Incident Summary

FieldDetails
VulnerabilityCVE-2026-39987 — unauthenticated PTY shell via Marimo's /terminal/ws WebSocket endpoint
Affected VersionsMarimo up to and including 0.20.4; fixed in 0.23.0
ResearcherSysdig Threat Research Team (TRT)
Session Length~9 hours (12:52 – 21:50 UTC), 850+ interactive commands
Time-to-Bastion (staged run)8 seconds — fresh WebSocket connection to SSH bastion authentication
Tooling5 hand-written Python scripts, staged via base64 to /tmp/; boto3, Paramiko, an AsyncSSH-style listener
AI InvolvementNone detected — no LLM fingerprints, no public offensive tooling
Attacker InfrastructureSource 172.236.12.17 (London); callback 45.79.187.72 (Cedar Knolls, NJ) — both on AS63949 (Akamai Connected Cloud / Linode)

What Happened: Two Sessions, One Chain

Sysdig's telemetry shows the intrusion wasn't a single lucky burst of speed — it was the payoff of methodical preparation. The operator worked in (at least) two distinct sessions against the same compromised Marimo instance:

  • Session one (starting 12:52:18 UTC) was reconnaissance and toolkit-building: scanning the internal subnet, writing and testing Python scripts directly on the compromised host, and validating that a harvested AWS key could reach the target bastion.
  • Session two (starting 18:54:31 UTC) reused what session one had built. By the time the operator opened a third, fresh WebSocket connection at 18:57:22 UTC, the entire credential-theft-to-bastion-login chain fired from a single backgrounded command — completing in eight seconds because every dependency was already staged on disk.

Attack Timeline (UTC)

TimeEvent
~28 hrs priorFirst harvested AWS credential validated (visible later in CloudTrail)
12:52:18Initial WebSocket connection to /terminal/ws from 172.236.12.17
12:54:13First interactive command — TCP sweep of the internal RFC1918 subnet
16:00 – 16:30Five base64-encoded Python scripts written to /tmp/
16:50:40Script calls AWS Secrets Manager GetSecretValue via boto3
16:51:45Retrieved SSH key tested against the bastion host
18:54:31New WebSocket session opens
18:54:45AWS Secrets Manager call fires 14 seconds after session open
18:56:32 – 18:56:50EC2 enumeration attempts (all denied by IAM)
18:57:22Fresh WebSocket session opens
18:57:30SSH bastion authentication observed — 8 seconds later
20:13 – 20:32AsyncSSH-style listener deployed for follow-on access
21:50:14Operator disconnects

The vulnerability itself made this possible: Marimo's /terminal/ws WebSocket endpoint exposed a fully interactive PTY shell but, unlike other WebSocket routes in the same application, skipped the validate_auth() call that would have required credentials. Any client that opened a connection got a shell as the Marimo process user — no login, no token, no exploit chain beyond "connect." Marimo shipped the fix in version 0.23.0.


The Toolkit: Five Hand-Written Scripts, Staged for Speed

Sysdig recovered five Python scripts the attacker wrote and refined over several hours, each deployed with echo '<base64-blob>' | base64 -d > /tmp/<name>.py — a technique that sidesteps shell-quoting problems and keeps the actual script contents out of plaintext bash_history.

  • Script 1 — Initial Secrets Manager retrieval, with region fallback across us-east-1, us-west-2, eu-west-1, ap-southeast-1, and us-east-2.
  • Script 2 — A refined retrieval routine adding key persistence (chmod 0600), JSON parsing, and a fallback to ListSecrets if direct access was denied.
  • Script 3 — A standard-library-only reverse shell built from socket, os.dup2, and subprocess, with error handling and a 10-second timeout.
  • Script 4 — SSH connection logic via Paramiko, with detection for RSAKey, Ed25519Key, and ECDSAKey, plus a netcat listener on port 4444.
  • Script 5 — A consolidated "chain" module tying the previous four together into the single command that ran in 8 seconds (Sysdig only partially recovered its contents).

The operator also probed an EC2 Instance Connect fallback — attempting to push an SSH public key using a placeholder instance ID (i-0000000000000000) after enumeration attempts were denied. AWS blocked it. Sysdig also found evidence the attacker pursued two separate credential paths in parallel: one harvested from environment variables/files on the host, and a second pulled from the application's own Redis backend, each tested against different IAM identities.


No AI Fingerprints — and a Trap That Didn't Work

What makes this report notable isn't the exploit itself; it's what Sysdig didn't find. There was no LLM-generated code, no agentic tool-calling pattern, and no publicly available offensive framework anywhere in the session — just four-plus hours of manual scripting, testing, and debugging by a person who evidently knew AWS IAM and SSH key handling well. Sysdig had also planted a prompt-injection probe inside the compromised Marimo container as a tripwire for AI-driven operators; the human attacker didn't take the bait, which the researchers noted is exactly the kind of judgment call that trips up agentic attack tooling.

Sysdig's own framing of the finding:

"Eight seconds is the kind of speed we expect to see in AI-assisted attacks. This operator got there on skill alone."

The team went further, arguing that the two attacker profiles — human and AI-driven — don't fail the same way, which matters directly for detection engineering:

"A skilled human will outmaneuver an LLM-driven operator on evasion and judgement alone... defenses built for one will likely miss the actions of the other."


Why This Matters for Defenders

The headline number — eight seconds — is a useful shock value, but the real takeaway is about the assumptions built into a lot of current detection logic. Many "time to detect / time to respond" targets, and a good chunk of anomaly-based tooling, were tuned around the idea that fast correlates with automated, and that automated activity looks different from a human at a keyboard (typos, pauses, trial-and-error). This case shows a human operator who eliminated all of that by doing the trial-and-error offline, in an earlier session, then executing the finished chain as a single pre-staged command. The activity that actually hit the bastion host looked instantaneous and clean — nothing about its speed alone would flag it as either "bot" or "human."


Detection & Defensive Recommendations

Indicators of Compromise

  • Source IP 172.236.12.17; callback/C2 IP 45.79.187.72
  • File artifacts: /tmp/chain.py, /tmp/full_chain.py, /tmp/bastion_key (mode 0600), /tmp/chain.log, /tmp/chain_output.txt, /tmp/callback.log
  • Behavioral markers: a base64-decode-then-execute pattern feeding straight into python3; boto3 region-fallback iteration; Paramiko SSHClient connections originating from non-SSH binaries; an early, out-of-place pip3 install boto3

Cloud and runtime detection

  • In CloudTrail, alert on secretsmanager:GetSecretValue calls from newly-seen principals followed by AccessDeniedException retries across multiple regions within about 60 seconds — the region-fallback pattern is a strong signal on its own.
  • In GuardDuty, watch for UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS findings tied to notebook or data-science compute.
  • Apply container runtime policies that flag drift and unexpected outbound egress from notebook/Jupyter-style containers.
  • Restrict egress from notebook services to only the endpoints they legitimately need (package registries, model APIs) — a bastion-bound SSH connection or an unfamiliar HTTPS callback from a notebook container should stand out immediately.

Remediation priority

  1. Upgrade Marimo to version 0.23.0 or later on every instance — this flaw is already confirmed under active exploitation and sits on CISA's KEV catalog.
  2. Put the /terminal/ws endpoint behind authentication, or disable the terminal feature entirely if it isn't required.
  3. Audit every credential-storage surface reachable from a notebook host: environment variables, systemd unit files, ~/.aws, .env files, and any connected data backend (Redis, in this case).
  4. Scope Secrets Manager and IAM permissions available to notebook hosts down to least privilege — dual-path credential harvesting only works if both paths lead somewhere useful.
  5. Rotate any credentials that were reachable from an internet-exposed Marimo instance, treating them as compromised regardless of whether exploitation is confirmed.
  6. Hunt specifically for staged toolkits: unexplained /tmp/*.py files, base64-decoded script artifacts, and SSH private key material written outside expected paths.

References

  • The Hacker News — Human Attacker Exploits Marimo RCE, Reaches SSH Bastion in Eight Seconds
  • Sysdig — Machine Speed, Hold the AI: Hand-Rolled Marimo CVE-2026-39987 Exploit

Related Reading

  • CVE-2026-39987: Marimo Pre-Auth Remote Code Execution
#Marimo#CVE-2026-39987#Remote Code Execution#Sysdig#Incident Response

Related Articles

CVE-2026-39987: Marimo Pre-Auth Remote Code Execution

A critical pre-authorization remote code execution vulnerability in Marimo, the open-source reactive Python notebook, allows unauthenticated attackers to...

4 min read

AI Agent Exploits Langflow RCE to Automate Database Ransomware Attack

Sysdig researchers documented the first fully autonomous AI-driven ransomware campaign, where threat actor JADEPUFFER used an AI agent to chain Langflow...

3 min read

73 Seconds to Breach, 24 Hours to Patch: The Case for Autonomous Validation

Attackers can compromise systems in under 90 seconds while patching and response still take hours or days. Picus Security breaks down why autonomous...

5 min read
Back to all News