Skip to main content

Command Palette

Search for a command to run...

Your OpenClaw Agent Was Compromised Three Sessions Ago. Here Is How to Find Out.

Production detection rules for CrowdStrike, Microsoft Defender for Endpoint, Cortex XDR, SentinelOne, and Splunk — plus YARA rules, Sigma rules, behavioral hunting queries, and forensic scripts mapped to the five MITRE ATLAS kill chains confirmed in the January 2026 disclosures.

Updated
37 min read
Your OpenClaw Agent Was Compromised Three Sessions Ago. Here Is How to Find Out.

Part 3 of 3 | ← Part 2: Production Security Architecture | ← Part 1: Attack Vectors and Verification

🔒 Update — April 2026: Cisco's DefenseClaw now provides structured enforcement events (dc_block, dc_codeguard) that function as additional signal sources alongside the openclaw-telemetry events used in Tier 2 and Tier 3 queries below. If you have DefenseClaw deployed, see the addenda in the Tier 2 section for enhanced Splunk queries that join both event streams — the combination produces significantly fewer false negatives for Kill Chain 1 (Injection → RCE) scenarios.


If you stopped at Part 2, your deployment is hardened but invisible. You have no answer for:

  • When an attacker with a novel prompt injection technique bypasses openclaw-shield

  • Whether an infostealer already exfiltrated credentials before you rotated them

  • What your agent actually did in the 48 hours before you deployed behavioral monitoring

  • Whether SOUL.md has been modified since you last reviewed it

You hardened the gateway, isolated credentials, containerized the runtime, and deployed openclaw-shield. Your CISO's first question was not "did you harden it?" It was "how will you know when it's compromised?"

That question doesn't have a good answer in Parts 1 and 2. This post is the answer.

Parts 1 and 2 addressed the operator's problem: close the backdoors, architect defense-in-depth, assume breach at every layer. This post addresses the SOC team's problem: detect OpenClaw abuse before it becomes a breach, investigate when it does, and collect evidence your incident timeline will actually hold up.

This post is for: Security engineers, threat hunters, and SOC analysts who own detection coverage for endpoints running OpenClaw, Moltbot, or Clawdbot — including shadow deployments you didn't approve.

By the end, you'll have: Ready-to-deploy detection queries for CrowdStrike Falcon, Microsoft Defender for Endpoint, Palo Alto Cortex XDR, SentinelOne, and Splunk; a complete IOC set including YARA rules and Sigma rules; behavioral hunting queries mapped to the official OpenClaw MITRE ATLAS kill chains; a forensic evidence collection procedure; an honest account of where detection fails; and — if you have DefenseClaw deployed — enhanced Splunk queries that join DefenseClaw enforcement events with openclaw-telemetry for higher-confidence kill chain detection.

Environment Note: Detection queries target Windows endpoints (the most common enterprise deployment). Process and DNS queries work on macOS and Linux with EDR telemetry where noted. The telemetry source for behavioral hunting is openclaw-telemetry (covered in Part 2, Layer 6). Platform path variants use ~/.moltbot (current default), ~/.clawdbot (legacy), and ~/.openclaw (base installation).

Implementation time: Tier 1 discovery queries take under an hour to deploy on any supported EDR. Tier 2 behavioral hunting requires openclaw-telemetry from Part 2 — if you haven't deployed Layer 6 yet, complete that first. Tier 3 kill chain detection builds on Tier 2. Plan for a one-to-two day sprint if Part 2 is complete, or one to two weeks if you're starting fresh.


Table of Contents

  1. Why Detection Is Different for AI Agents

  2. What You're Actually Detecting

  3. Tier 1: Discovery Detection — Finding OpenClaw on Your Endpoints

  4. Tier 2: Behavioral Hunting — Detecting Compromise in Progress

  5. Tier 3: Kill Chain Detection — Mapping Attacks to ATLAS Tactics

  6. Forensic Investigation: When Compromise Has Already Occurred

  7. IOC Reference

  8. Detection Gaps: Where This Falls Short

  9. Production Detection Checklist


Why Detection Is Different for AI Agents

Framework mapping: NIST CSF DE.AE (Anomalies and Events), DE.CM (Continuous Monitoring), MITRE ATLAS AML.TA0003 (ML Attack Execution)

Traditional endpoint detection relies on a core assumption: malicious activity looks structurally different from legitimate activity. An attacker running mimikatz.exe leaves a process name. A C2 callback makes a network connection to an unusual domain. A ransomware deployment writes thousands of files in seconds.

OpenClaw breaks this assumption in a specific way.

When a compromised OpenClaw agent reads ~/.ssh/id_ed25519 and sends its contents to an attacker's email address, the process tree looks like this: openclaw.mjs spawns node, which calls the native file_read tool, which invokes the email_send tool. Every step is the agent behaving exactly as designed. The only difference from a legitimate request is the instruction that caused it — and that instruction lived inside a natural language string that the model decided to obey.

This is the detection problem in one sentence: you cannot reliably distinguish a malicious tool call from a legitimate one by looking at the tool call alone. You can only detect it through context — when it happened, what it accessed, what sequence it was part of, and whether a human authorized it.

Detection for AI agents therefore runs on three tiers. The first tier finds the software on your endpoints at all. The second tier looks for behavioral anomalies in what the agent does at runtime. The third tier maps observed activity to the specific kill chains documented in OpenClaw's official MITRE ATLAS threat model, letting you identify which attack scenario is in progress rather than just flagging suspicious behavior.

Figure 1: Three-tier detection model for OpenClaw deployments. Each tier builds on the previous — Tier 1 requires only EDR, Tier 2 requires openclaw-telemetry, and Tier 3 requires both.


What You're Actually Detecting

Before deploying any query, you need a clear picture of what normal OpenClaw activity looks like so your detections don't drown in false positives.

Normal process activity on a healthy installation:

openclaw.mjs                 -- Main agent process
openclaw-openclaw-gateway    -- Gateway/WebSocket multiplexer on 127.0.0.1:18789
openclaw-orchestrator        -- Task orchestration loop (Heartbeat)
node                         -- Runtime for skill execution

Normal network activity:

  • 127.0.0.1:18789 — Gateway listener (WebSocket + HTTP control UI)

  • DNS queries to openclaw.ai, molt.bot, clawd.bot, docs.openclaw.ai — Documentation and update checks

  • DNS queries to clawhub.openclaw.ai or auth.clawdhub.com — Skill marketplace

Normal filesystem activity:

  • Reads/writes to ~/.openclaw/, ~/.moltbot/, ~/.clawdbot/

  • Access to SOUL.md — The persistent identity file that injects into every agent session as behavioral context; think of it as the agent's long-term memory and self-description

  • Access to ~/.openclaw/skills/ — Installed skill modules

Anomalies are deviations from this baseline: access to paths outside the agent's configured working directories, outbound connections to non-OpenClaw infrastructure initiated by the agent process, modifications to SOUL.md outside the user's active session, and tool execution sequences that don't match typical user workflows.


Tier 1: Discovery Detection

Framework mapping: NIST CSF ID.AM-1 (Asset Management — physical devices and systems inventoried), DE.CM-7 (Monitoring for unauthorized activity)

Your first question is not whether OpenClaw is being abused. It's whether you know where it's running. An estimated 300,000–400,000 Clawdbot/OpenClaw deployments went up without IT approval. You cannot detect compromise on instances you don't know exist.

These queries find all OpenClaw installations and running instances across your managed fleet. Deploy them as standing scheduled queries or integrate into your MDM detection pipeline alongside openclaw-detect (covered in Part 2, Layer 7).

CrowdStrike Falcon

Full discovery query — process, DNS, and network in one:

(#event_simpleName=DnsRequest and (
    DomainName=/(openclaw\.ai|molt\.bot|clawd\.bot|docs\.(molt\.bot|clawd\.bot|openclaw\.ai)|moltbotai\.chat)/i
    or DomainName=*openclaw.ai* or DomainName=*molt.bot* or DomainName=*clawd.bot*
    or DomainName=*moltbotai.chat* or DomainName=*clawhub*
))

OR

(#event_simpleName=ProcessRollup2 and (
    CommandLine=/(molt\.bot|clawd\.bot|openclaw\.mjs|openclaw\s+(gateway|status|onboard)|openclaw-openclaw-gateway|openclaw-orchestrator|127\.0\.0\.1:18789|ws:\/\/127\.0\.0\.1:18789)/i
    or ImageFileName=/(openclaw|molty|clawd)(\.mjs|\.exe|$)/i
    or CommandLine=*molt.bot* or CommandLine=*clawd.bot*
    or CommandLine=*openclaw.mjs* or CommandLine=*openclaw gateway*
    or CommandLine=*openclaw-openclaw-gateway*
    or CommandLine=*127.0.0.1:18789* or CommandLine=*ws://127.0.0.1:18789*
    or ImageFileName=*openclaw* or ImageFileName=*molty* or ImageFileName=*clawd*
))

OR

((#event_simpleName=NetworkConnectIP4 or #event_simpleName=NetworkConnectIP6)
    and RemotePort=18789)

| table([@timestamp, ComputerName, UserName, #event_simpleName,
         DomainName, ImageFileName, CommandLine,
         RemoteAddress, RemotePort, ContextBaseFileName])

Microsoft Defender for Endpoint (KQL)

Full discovery query:

let ProcessIOCs =
DeviceProcessEvents
| where Timestamp > ago(30d)
| where ProcessCommandLine has "openclaw.mjs"
    or ProcessCommandLine has "openclaw-openclaw-gateway"
    or ProcessCommandLine has "openclaw-orchestrator"
    or ProcessCommandLine has "openclaw gateway"
    or ProcessCommandLine has "openclaw status"
    or ProcessCommandLine has "openclaw onboard"
    or ProcessCommandLine has "127.0.0.1:18789"
    or ProcessCommandLine has "ws://127.0.0.1:18789"
    or ProcessCommandLine has "molt.bot"
    or ProcessCommandLine has "clawd.bot"
| project Timestamp, DeviceName,
    AccountName = InitiatingProcessAccountName,
    EventType = "Process", FileName,
    CommandLine = ProcessCommandLine,
    RemotePort = 0, RemoteIP = "";

let NetworkDomainIOCs =
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemoteUrl has "openclaw.ai"
    or RemoteUrl has "molt.bot"
    or RemoteUrl has "clawd.bot"
    or RemoteUrl has "clawhub"
    or RemoteUrl has "moltbotai.chat"
| project Timestamp, DeviceName,
    AccountName = InitiatingProcessAccountName,
    EventType = "Network_Domain",
    DomainOrUrl = RemoteUrl,
    FileName = InitiatingProcessFileName,
    CommandLine = InitiatingProcessCommandLine,
    RemotePort, RemoteIP;

let Port18789 =
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemotePort == 18789
| project Timestamp, DeviceName,
    AccountName = InitiatingProcessAccountName,
    EventType = "Port18789",
    DomainOrUrl = RemoteUrl,
    FileName = InitiatingProcessFileName,
    CommandLine = InitiatingProcessCommandLine,
    RemotePort, RemoteIP;

union ProcessIOCs, NetworkDomainIOCs, Port18789
| order by Timestamp desc
| project Timestamp, DeviceName, AccountName,
    EventType, DomainOrUrl, FileName,
    CommandLine, RemoteIP

Palo Alto Cortex XDR

Full discovery query:

datamodel dataset = xdr_data
| filter
    xdm.event.description contains "openclaw.mjs"
    or xdm.event.description contains "openclaw-openclaw-gateway"
    or xdm.event.description contains "openclaw-orchestrator"
    or xdm.event.description contains "openclaw gateway"
    or xdm.event.description contains "127.0.0.1:18789"
    or xdm.event.description contains "ws://127.0.0.1:18789"
    or xdm.event.description contains "molt.bot"
    or xdm.event.description contains "clawd.bot"
    or xdm.source.process.executable.filename contains "openclaw"
    or xdm.source.process.executable.filename contains "molty"
    or xdm.source.process.executable.filename contains "clawd"
    or xdm.target.url contains "openclaw"
    or xdm.target.url contains "molt.bot"
    or xdm.target.url contains "clawd.bot"
    or xdm.target.domain contains "clawhub"
    or xdm.target.port = 18789
| fields _time,
    xdm.source.host.hostname,
    xdm.source.user.username,
    xdm.event.type,
    xdm.event.description,
    xdm.source.process.executable.filename,
    xdm.target.url,
    xdm.target.domain,
    xdm.target.ipv4,
    xdm.target.port
| sort desc _time

SentinelOne

Full discovery query:

src.process.cmdline contains (
    'openclaw.mjs',
    'openclaw-openclaw-gateway',
    'openclaw-orchestrator',
    'openclaw gateway',
    'openclaw status',
    'openclaw onboard',
    '127.0.0.1:18789',
    'ws://127.0.0.1:18789',
    'molt.bot',
    'clawd.bot'
)
or src.process.name contains ('openclaw', 'molty', 'clawd')
or src.process.image.path contains ('openclaw', 'molty', 'clawd')
or network.url contains (
    'openclaw.ai', 'molt.bot', 'clawd.bot',
    'docs.openclaw', 'docs.molt.bot', 'clawhub',
    'moltbotai.chat', 'moltbot', 'clawdbot', 'openclaw'
)
or dst.port.number = 18789

Splunk (Splunk Security Essentials / ES)

Full discovery query against the Endpoint data model:

| tstats count min(_time) as firstTime max(_time) as lastTime
    FROM datamodel=Endpoint.Processes
    WHERE
        Processes.process="*openclaw.mjs*" OR
        Processes.process="*openclaw-openclaw-gateway*" OR
        Processes.process="*openclaw gateway*" OR
        Processes.process="*openclaw status*" OR
        Processes.process="*openclaw onboard*" OR
        Processes.process="*127.0.0.1:18789*" OR
        Processes.process="*ws://127.0.0.1:18789*" OR
        Processes.process="*molt.bot*" OR
        Processes.process="*clawd.bot*"
    BY Processes.dest Processes.user Processes.process Processes.process_name
| `drop_dm_object_name(Processes)`
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| eval risk_score=case(
    match(process, "0\.0\.0\.0:18789"), 100,
    match(process, "openclaw"), 60,
    true(), 40
  )
| sort - risk_score
| table firstTime lastTime dest user process process_name risk_score

All Tier 1 discovery queries — CrowdStrike, MDE (behavioral + kill chain), Cortex XDR, SentinelOne, Splunk


⚡ QUICK WIN — Deploy Fleet Discovery in the Next 10 Minutes

What it does: Finds every OpenClaw, Moltbot, or Clawdbot instance running on your managed fleet, including shadow installations that bypassed IT approval.

Why it matters: An estimated 300,000–400,000 deployments went up without security review. You cannot detect compromise on instances you don't know exist, and shadow deployments by definition have none of the Part 2 hardening in place.

Time estimate: 5–10 minutes with EDR console access.

Step 1 — Pick your platform and paste the query above into a new custom detection or saved search.

Step 2 — Set the schedule to run daily at minimum. Hourly is better given how fast new deployments appear.

Step 3 — Alert on any new result. Every OpenClaw process or domain contact that isn't in your approved asset inventory is a finding.

Step 4 — Cross-reference results with openclaw-detect (Part 2, Layer 7) for MDM-based coverage of endpoints without full EDR telemetry.

Expected safe output: Only the instances you approved appear, all bound to 127.0.0.1:18789.

Red flags: Any result from a machine not in your asset inventory. Any process with 0.0.0.0:18789 in the command line — that machine is or was internet-exposed.



Tier 2: Behavioral Hunting

Framework mapping: OWASP LLM01 (Prompt Injection — detection), NIST CSF DE.AE (Anomalies and Events), DE.CM-3 (Personnel activity monitored)

Knowing OpenClaw is running is table stakes. What your SOC actually needs is a way to distinguish a healthy deployment from a compromised one. The queries in this tier require openclaw-telemetry to be running (Part 2, Layer 6) — without it, you have process-level visibility only, which is insufficient for behavioral detection.

openclaw-telemetry writes events to ~/.openclaw/logs/telemetry.jsonl in this schema:

{
  "timestamp": "2026-02-18T06:34:12.441Z",
  "event_type": "tool_executed",
  "session_id": "sess_abc123",
  "tool_name": "file_read",
  "tool_args": {"path": "/home/user/.ssh/id_ed25519"},
  "tool_result_summary": "success",
  "chain_hash": "sha256:a1b2c3...",
  "prev_hash": "sha256:9z8y7x..."
}

When openclaw-telemetry forwards events to SIEM via CEF/syslog, the tool_args object is flattened into named CEF extension fields — tool_name, tool_path, recipients, session_id, etc. The KQL queries below reference these CEF extension names; the jq queries reference the raw JSONL field paths directly. If a field appears in the KQL but not in the schema above, it is a CEF-flattened variant of a nested tool_args key.

The following hunting queries work against this telemetry, either parsed locally with jq or after forwarding to your SIEM via CEF/syslog.

If you have DefenseClaw deployed: DefenseClaw emits its own structured event stream alongside openclaw-telemetry. The two event types most useful for behavioral hunting are:

// dc_block — DefenseClaw blocked a tool invocation or code execution
{
  "timestamp": "2026-04-01T14:22:03.112Z",
  "event_type": "dc_block",
  "session_id": "sess_xyz789",
  "trigger": "runtime_inspection",     // or "codeguard" | "supply_chain"
  "tool_name": "python_repl",
  "reason": "command_injection_pattern",
  "severity": "critical",
  "blocked_content_hash": "sha256:f3a..."
}

// dc_codeguard — CodeGuard scanned agent-generated code
{
  "timestamp": "2026-04-01T14:22:03.089Z",
  "event_type": "dc_codeguard",
  "session_id": "sess_xyz789",
  "tool_name": "exec",
  "findings": ["secrets_exposure", "command_injection"],
  "action_taken": "blocked"            // or "logged"
}

A dc_block event in the same session_id as a tool_executed anomaly from openclaw-telemetry is near-zero false positive evidence of an active attack — the behavioral anomaly detection fired and the enforcement layer blocked something. Join these two streams in your SIEM for high-confidence alerting.

Hunt 1: Credential Harvesting Sequence

This pattern detects the most common post-exploitation sequence — the agent reads a sensitive path shortly after receiving an inbound message from an external channel.

# Detect file reads targeting credential or key paths
cat ~/.openclaw/logs/telemetry.jsonl \
  | jq 'select(
      .event_type == "tool_executed"
      and .tool_name == "file_read"
      and (
        .tool_args.path | test(
          "\\.ssh|\\.aws|\\.moltbot|\\.clawdbot|\\.openclaw|id_rsa|id_ed25519|\\.bak|\\.env|credentials"
        )
      )
    )
    | {timestamp, session_id, tool_name, path: .tool_args.path}'

In Microsoft Sentinel (KQL) after CEF forwarding:

CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "tool_executed"
| extend tool_name = extract("tool_name=([^,]+)", 1, AdditionalExtensions)
| extend tool_path = extract("tool_path=([^,]+)", 1, AdditionalExtensions)
| where tool_name == "file_read"
    and tool_path matches regex @"(\.ssh|\.aws|\.moltbot|\.clawdbot|\.openclaw|id_rsa|id_ed25519|\.bak|\.env|credentials)"
| project TimeGenerated, DeviceName, SourceUserName,
    tool_name, tool_path
| order by TimeGenerated desc

Hunt 2: Exfiltration Sequence (file_read → email_send)

The Snyk-demonstrated email exfiltration attack leaves a distinctive tool sequence in logs: a file read of a sensitive path followed by an email send within the same session, within a short time window.

# Find sessions containing both file_read of sensitive paths
# and email_send within 60 seconds
cat ~/.openclaw/logs/telemetry.jsonl \
  | jq -s '
    group_by(.session_id)[]
    | . as $session
    | {
        session_id: $session[0].session_id,
        sensitive_reads: [
          $session[]
          | select(.tool_name == "file_read"
              and (.tool_args.path | test("\\.ssh|\\.aws|\\.bak|\\.env")))
        ],
        email_sends: [
          $session[]
          | select(.tool_name == "email_send")
        ]
      }
    | select(
        (.sensitive_reads | length) > 0
        and (.email_sends | length) > 0
      )
  '

KQL equivalent in Sentinel:

let sensitiveReads =
CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "tool_executed"
| extend tool_name = extract("tool_name=([^,]+)", 1, AdditionalExtensions)
| extend tool_path = extract("tool_path=([^,]+)", 1, AdditionalExtensions)
| extend session_id = extract("session_id=([^,]+)", 1, AdditionalExtensions)
| where tool_name == "file_read"
    and tool_path matches regex @"(\.ssh|\.aws|\.bak|\.env|credentials)"
| project TimeGenerated, DeviceName, session_id, tool_path;

let emailSends =
CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "tool_executed"
| extend tool_name = extract("tool_name=([^,]+)", 1, AdditionalExtensions)
| extend session_id = extract("session_id=([^,]+)", 1, AdditionalExtensions)
| extend recipients = extract("recipients=([^,]+)", 1, AdditionalExtensions)
| where tool_name == "email_send"
| project TimeGenerated, DeviceName, session_id, recipients;

sensitiveReads
| join kind=inner emailSends on session_id
| where abs(datetime_diff('second', TimeGenerated, TimeGenerated1)) < 60
| project
    ReadTime = TimeGenerated,
    SendTime = TimeGenerated1,
    DeviceName,
    session_id,
    sensitive_path = tool_path,
    email_recipients = recipients
| order by ReadTime desc

Hunt 2-DC: DefenseClaw-Enhanced Exfiltration Detection (Splunk)

If DefenseClaw is deployed alongside openclaw-telemetry, this Splunk query joins both event streams to produce a high-confidence exfiltration alert. A dc_block on a sensitive tool in the same session as a file read of a credential path is confirmed attack evidence — both the behavioral anomaly and the enforcement block are present.

index=openclaw_telemetry OR index=defenseclaw_events
| eval source_type=case(
    source=="openclaw-telemetry", "telemetry",
    source=="defenseclaw", "dc_event",
    true(), "unknown"
  )
| stats
    values(tool_name) as tools_used,
    values(event_type) as event_types,
    count(eval(event_type="dc_block")) as dc_blocks,
    count(eval(tool_name="file_read")) as credential_reads,
    count(eval(tool_name="email_send")) as email_sends
  by session_id, host
| where dc_blocks > 0 AND (credential_reads > 0 OR email_sends > 0)
| eval confidence=case(
    dc_blocks > 0 AND credential_reads > 0 AND email_sends > 0, "HIGH",
    dc_blocks > 0 AND credential_reads > 0, "MEDIUM",
    true(), "LOW"
  )
| sort - confidence
| table session_id, host, confidence, dc_blocks, credential_reads, email_sends, tools_used

Why this is different from Hunt 2: Hunt 2 requires both a sensitive file read and an email send in the same session to fire. This query fires on a dc_block event alone — meaning it catches cases where DefenseClaw stopped the exfiltration before email_send was ever invoked. The dc_block + credential_read combination is sufficient for a MEDIUM confidence alert.

Hunt 3: Off-Hours Execution

Tool execution when the user is not active is one of the cleanest behavioral signals. Prompt injection that triggers autonomous execution tends to happen whenever the attacker sends the payload — not necessarily during the user's working hours.

# Flag tool executions outside 8am-7pm local time on weekdays
cat ~/.openclaw/logs/telemetry.jsonl \
  | jq 'select(
      .event_type == "tool_executed"
      and (
        (.timestamp | strptime("%Y-%m-%dT%H:%M:%S.%fZ") | .tm_hour)
        < 8
        or
        (.timestamp | strptime("%Y-%m-%dT%H:%M:%S.%fZ") | .tm_hour)
        >= 19
      )
    )
    | {timestamp, tool_name, tool_args}'

KQL:

CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "tool_executed"
| extend HourOfDay = hourofday(TimeGenerated)
| extend DayOfWeek = dayofweek(TimeGenerated)
| extend tool_name = extract("tool_name=([^,]+)", 1, AdditionalExtensions)
| where HourOfDay < 8 or HourOfDay >= 19
    or DayOfWeek == 0d or DayOfWeek == 6d  // weekend
| where tool_name in ("exec", "shell", "python_repl",
    "file_read", "file_write", "email_send", "browser_action")
| project TimeGenerated, DeviceName, SourceUserName,
    tool_name, HourOfDay, DayOfWeek
| order by TimeGenerated desc

Hunt 4: Burst Tool Execution

Automated exploitation sequences run fast. More than ten tool calls within sixty seconds is unusual for normal human-driven usage and a reliable signal of either a prompt injection attack in progress or a runaway automation loop.

# Count tool calls per session per minute, flag bursts
cat ~/.openclaw/logs/telemetry.jsonl \
  | jq -s '
    [.[] | select(.event_type == "tool_executed")]
    | group_by(.session_id)[]
    | {
        session_id: .[0].session_id,
        total_calls: length,
        first_call: .[0].timestamp,
        last_call: .[-1].timestamp,
        tools_used: [.[].tool_name] | unique
      }
    | select(.total_calls > 10)
  '

KQL:

CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "tool_executed"
| extend session_id = extract("session_id=([^,]+)", 1, AdditionalExtensions)
| summarize
    tool_call_count = count(),
    tools_used = make_set(extract("tool_name=([^,]+)", 1, AdditionalExtensions)),
    first_call = min(TimeGenerated),
    last_call = max(TimeGenerated)
    by session_id, DeviceName, bin(TimeGenerated, 1m)
| where tool_call_count > 10
| project first_call, last_call, DeviceName,
    session_id, tool_call_count, tools_used
| order by tool_call_count desc

Hunt 5: SOUL.md Modification

SOUL.md is OpenClaw's persistent identity file — it injects into every session as behavioral context. Researchers demonstrated that attacker-controlled modifications to this file create persistence that survives restarts. Any write to SOUL.md outside of a user-initiated configuration change is a high-confidence indicator of compromise.

On Linux/macOS with inotify or auditd:

# Real-time monitoring (Linux with inotifywait)
inotifywait -m -e modify,create \
    ~/.openclaw/SOUL.md \
    ~/.moltbot/SOUL.md \
    ~/.clawdbot/SOUL.md 2>/dev/null

# Audit log review
ausearch -f SOUL.md --start yesterday --end now 2>/dev/null

KQL (via Defender for Endpoint file events):

DeviceFileEvents
| where Timestamp > ago(7d)
| where FileName == "SOUL.md"
    or FolderPath endswith "SOUL.md"
| where ActionType in ("FileModified", "FileCreated")
| where InitiatingProcessFileName !in~ ("openclaw.mjs", "node", "node.exe")
| project Timestamp, DeviceName, AccountName,
    InitiatingProcessFileName,
    InitiatingProcessCommandLine,
    FolderPath, ActionType
| order by Timestamp desc

Why this matters: Any process other than the OpenClaw gateway writing to SOUL.md — particularly a shell, Python interpreter, or download manager — is either a malicious skill executing its persistence payload or a direct filesystem attack. The KQL filter (!in~) excludes the two legitimate agent processes; everything else that modifies SOUL.md should be treated as a high-confidence finding until proven otherwise.

Behavioral hunting queries (KQL + Splunk SPL)Sigma rules for all five behavioral hunts (platform-agnostic)


Tier 3: Kill Chain Detection

The official OpenClaw MITRE ATLAS threat model documents five critical attack kill chains. Each one has a distinct observable signature. The queries in this tier map to specific chains so your SOC can identify which scenario is in progress rather than responding to generic anomalies.

Kill Chain 1: Prompt Injection to Remote Code Execution

ATLAS chain: T-ACCESS-006 → T-EXEC-001 → T-EVADE-003 → T-EXEC-004 → T-IMPACT-001

Gain channel access, inject prompt, manipulate confirmation dialog, bypass exec approval, execute commands on host.

The behavioral signature is a high-risk tool (exec, shell, python_repl) executed shortly after an inbound message from an external channel (email, Slack, Twitter/X), with no corresponding user interaction event.

// Defender for Endpoint — detect exec/shell tool within 5 min of inbound message
let HighRiskToolExec =
CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "tool_executed"
| extend tool_name = extract("tool_name=([^,]+)", 1, AdditionalExtensions)
| extend session_id = extract("session_id=([^,]+)", 1, AdditionalExtensions)
| where tool_name in ("exec", "shell", "python_repl")
| project ExecTime = TimeGenerated, DeviceName, session_id, tool_name;

let InboundMessages =
CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "message_received"
| extend channel = extract("channel=([^,]+)", 1, AdditionalExtensions)
| extend session_id = extract("session_id=([^,]+)", 1, AdditionalExtensions)
| where channel in ("email", "slack", "twitter", "discord", "whatsapp", "telegram")
| project MsgTime = TimeGenerated, DeviceName, session_id, channel;

HighRiskToolExec
| join kind=inner InboundMessages on session_id
| where ExecTime > MsgTime
    and datetime_diff('second', ExecTime, MsgTime) < 300
| project MsgTime, ExecTime, DeviceName, session_id, channel, tool_name
| extend SecondsToExec = datetime_diff('second', ExecTime, MsgTime)
| order by ExecTime desc

Kill Chain 2: Indirect Injection Data Theft

ATLAS chain: T-EXEC-002 → T-DISC-004 → T-EXFIL-001

Poison fetched content (a webpage, document, or feed item), let the agent enumerate the environment, exfiltrate via web_fetch or HTTP tool.

This chain is harder to detect because web_fetch is a normal tool. The signal is environment enumeration (T-DISC-004) — the agent reading system paths, user configuration, or environment variables — immediately after a web_fetch call.

# Detect web_fetch immediately followed by filesystem enumeration
# within the same session
cat ~/.openclaw/logs/telemetry.jsonl \
  | jq -s '
    [.[] | select(.event_type == "tool_executed")]
    | group_by(.session_id)[]
    | to_entries
    | . as $events
    | $events[]
    | select(.value.tool_name == "web_fetch")
    | . as $fetch
    | \(events[(\)fetch.key + 1):($fetch.key + 4)][]
    | select(
        .value.tool_name == "file_read"
        or .value.tool_name == "shell"
        or (.value.tool_name == "exec"
            and (.value.tool_args.command
                | test("env|printenv|ls -la|cat ~|whoami|id")))
      )
    | {
        fetch_at: $fetch.value.timestamp,
        fetch_url: $fetch.value.tool_args.url,
        followed_by: .value.tool_name,
        followed_args: .value.tool_args
      }
  '

KQL equivalent in Sentinel:

let WebFetches =
CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "tool_executed"
| extend tool_name = extract("tool_name=([^,]+)", 1, AdditionalExtensions)
| extend session_id = extract("session_id=([^,]+)", 1, AdditionalExtensions)
| extend tool_url = extract("tool_url=([^,]+)", 1, AdditionalExtensions)
| where tool_name == "web_fetch"
| project FetchTime = TimeGenerated, DeviceName, session_id, tool_url;

let EnvEnumeration =
CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "tool_executed"
| extend tool_name = extract("tool_name=([^,]+)", 1, AdditionalExtensions)
| extend session_id = extract("session_id=([^,]+)", 1, AdditionalExtensions)
| extend tool_path = extract("tool_path=([^,]+)", 1, AdditionalExtensions)
| extend tool_cmd = extract("tool_cmd=([^,]+)", 1, AdditionalExtensions)
| where (tool_name == "file_read")
    or (tool_name in ("exec", "shell")
        and tool_cmd matches regex @"(env|printenv|ls -la|cat ~|whoami|id)")
| project EnumTime = TimeGenerated, DeviceName, session_id,
    tool_name, tool_path, tool_cmd;

WebFetches
| join kind=inner EnvEnumeration on session_id
| where EnumTime > FetchTime
    and datetime_diff('second', EnumTime, FetchTime) < 120
| project FetchTime, EnumTime, DeviceName, session_id,
    fetched_url = tool_url,
    follow_tool = tool_name,
    follow_detail = coalesce(tool_path, tool_cmd)
| order by FetchTime desc

Kill Chain 3: Malicious Skill Full Kill Chain

ATLAS chain: T-RECON-003 → T-EVADE-001 → T-ACCESS-004 → T-EXEC-005 → T-PERSIST-001 → T-EXFIL-003

The attacker researches ClawHub, publishes an evasive skill, the user installs it, it executes, establishes persistence, and harvests credentials.

The detection opportunity for defenders is at T-EXEC-005 and T-PERSIST-001 — a skill executing unexpected system calls, or SOUL.md being modified by a skill process.

Defender for Endpoint — detect skill process spawning system-level child processes:

DeviceProcessEvents
| where Timestamp > ago(30d)
// Skills run as child processes of openclaw/node
| where InitiatingProcessFileName in~ ("openclaw.mjs", "node.exe", "node")
    or InitiatingProcessCommandLine has "openclaw"
// Flag when the child process is a shell or system utility
| where FileName in~ ("cmd.exe", "powershell.exe", "bash", "sh",
    "python.exe", "python3", "curl.exe", "curl", "wget",
    "certutil.exe", "bitsadmin.exe", "regsvr32.exe")
| project Timestamp, DeviceName,
    AccountName = InitiatingProcessAccountName,
    ParentProcess = InitiatingProcessFileName,
    ChildProcess = FileName,
    ChildCommandLine = ProcessCommandLine
| order by Timestamp desc

Kill Chain 4: Supply Chain Staged Payload

ATLAS chain: T-ACCESS-005 → T-EVADE-004 → T-EXEC-005 → T-PERSIST-002 → T-EXFIL-004

A compromised skill publisher pushes an update. The update appears benign on first run — it retrieves the actual payload from a remote source on the second execution. The skill manifest hash comparison from Part 2, Layer 5 catches tampering in storage. This query catches the runtime retrieval.

# Detect skill processes making unexpected outbound HTTP calls
# to non-OpenClaw infrastructure
cat ~/.openclaw/logs/telemetry.jsonl \
  | jq 'select(
      .event_type == "tool_executed"
      and .tool_name == "web_fetch"
      and (
        .tool_args.url
        | test("openclaw\\.ai|molt\\.bot|clawd\\.bot|anthropic\\.com|openai\\.com")
        | not
      )
    )
    | {timestamp, session_id, url: .tool_args.url}'

KQL equivalent in Sentinel:

CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "tool_executed"
| extend tool_name = extract("tool_name=([^,]+)", 1, AdditionalExtensions)
| extend tool_url = extract("tool_url=([^,]+)", 1, AdditionalExtensions)
| extend session_id = extract("session_id=([^,]+)", 1, AdditionalExtensions)
| extend skill_context = extract("skill_name=([^,]+)", 1, AdditionalExtensions)
| where tool_name == "web_fetch"
| where isnotempty(skill_context)  // only flag fetches within a skill execution context
| where tool_url !has "openclaw.ai"
    and tool_url !has "molt.bot"
    and tool_url !has "clawd.bot"
    and tool_url !has "anthropic.com"
    and tool_url !has "openai.com"
| project TimeGenerated, DeviceName, session_id, skill_context, tool_url
| order by TimeGenerated desc

Any web_fetch to a domain not on your known-good list that is initiated from within a skill execution context is a candidate for staged payload retrieval.

Kill Chain 5: Token Theft Persistent Access

ATLAS chain: T-ACCESS-003 → T-PERSIST-004 → T-DISC-002 → T-EXFIL-002

An attacker steals authentication tokens, uses them to maintain persistent Gateway access, extracts session data including conversation transcripts, and exfiltrates via messaging integrations.

The detection signal for this chain is multiple session starts from the same token but different source characteristics — timing, message patterns, or tool usage that doesn't match the legitimate user's behavioral baseline.

// Detect token reuse across sessions with anomalous timing gaps
CommonSecurityLog
| where DeviceProduct == "openclaw-telemetry"
| where DeviceEventClassID == "session_start"
| extend token_hash = extract("token_hash=([^,]+)", 1, AdditionalExtensions)
| extend source_channel = extract("channel=([^,]+)", 1, AdditionalExtensions)
| summarize
    session_count = count(),
    channels = make_set(source_channel),
    first_seen = min(TimeGenerated),
    last_seen = max(TimeGenerated)
    by token_hash, DeviceName
| where session_count > 5
    and array_length(channels) > 2
| order by session_count desc

Kill chain detection queries (MDE KQL)MITRE ATLAS full kill chain mapping


Forensic Investigation

Framework mapping: NIST CSF RS.AN (Analysis), RS.EV (Evidence), MITRE ATLAS AML.TA0009 (ML Exfiltration — evidence of)

When you've confirmed compromise — or when you're responding to an incident and need to build a timeline — this is the evidence you need to collect and the order to collect it in.

Before doing anything else, preserve logs. Once you stop the agent, log rotation or the next restart may overwrite evidence.

Phase 0: Preserve Evidence (Run Before Containment)

INCIDENT_DIR=~/incident-$(date +%Y%m%d-%H%M%S)
mkdir -p "$INCIDENT_DIR"

# Preserve all agent logs (telemetry, tool execution, standard)
cp -r ~/.openclaw/logs/ "$INCIDENT_DIR/openclaw-logs/" 2>/dev/null
cp -r ~/.moltbot/logs/ "$INCIDENT_DIR/moltbot-logs/" 2>/dev/null
cp -r ~/.clawdbot/ "$INCIDENT_DIR/clawdbot-config-backup/" 2>/dev/null

# Preserve SOUL.md and skill manifests (potential persistence artifacts)
cp ~/.openclaw/SOUL.md "$INCIDENT_DIR/SOUL.md.evidence" 2>/dev/null
cp ~/.moltbot/SOUL.md "$INCIDENT_DIR/SOUL.md.evidence" 2>/dev/null

# Capture current network state (active connections when compromise detected)
ss -tnap > "$INCIDENT_DIR/network-state.txt" 2>/dev/null
lsof -nP -iTCP -sTCP:ESTABLISHED >> "$INCIDENT_DIR/network-state.txt" 2>/dev/null

# Capture running processes (agent process tree)
ps auxf > "$INCIDENT_DIR/process-tree.txt" 2>/dev/null

# Check backup credential files (persistence of old credentials)
find ~/ \( -path "*/.moltbot/*" -o -path "*/.clawdbot/*" -o -path "*/.openclaw/*" \) \
    -name "*.bak*" -type f 2>/dev/null > "$INCIDENT_DIR/backup-files-found.txt"

# Verify telemetry hash chain integrity
# (broken chain = attacker tampered with logs)
tail -100 ~/.openclaw/logs/telemetry.jsonl \
    | jq -r '[.chain_hash, .prev_hash] | @csv' \
    > "$INCIDENT_DIR/hash-chain.csv" 2>/dev/null

echo "Evidence preserved to: $INCIDENT_DIR"
echo "Do NOT stop the agent process until evidence is secured."

Phase 1: Containment

# Stop agent and block outbound network
systemctl stop moltbot 2>/dev/null
systemctl stop openclaw 2>/dev/null
docker stop clawdbot 2>/dev/null

# Block outbound network from the agent user account (Linux)
sudo iptables -A OUTPUT -m owner --uid-owner "$USER" -j DROP

Phase 2: Build the Attack Timeline

The chain_hash field in openclaw-telemetry links every event to the previous one. If any hash fails to match the previous event's hash, log tampering occurred — note the break point, because everything before it is reliable evidence and everything after may have been modified.

# Build chronological timeline of all tool executions
cat "$INCIDENT_DIR/openclaw-logs/telemetry.jsonl" \
  | jq -r 'select(.event_type == "tool_executed")
    | [.timestamp, .tool_name, (.tool_args | tostring)] | @tsv' \
  | sort > "$INCIDENT_DIR/tool-execution-timeline.tsv"

# Identify first anomalous event
cat "$INCIDENT_DIR/openclaw-logs/telemetry.jsonl" \
  | jq 'select(
      .event_type == "tool_executed"
      and .tool_name == "file_read"
      and (.tool_args.path | test("\\.ssh|\\.aws|\\.bak|credentials"))
    )
    | {timestamp, path: .tool_args.path}' \
  | head -1

Phase 3: Determine Scope of Credential Exposure

The forensic question your CISO will ask is "what did the attacker get?" Work through this systematically:

# Enumerate what credential files existed and when they were last accessed
stat ~/.moltbot/moltbot.json 2>/dev/null
stat ~/.clawdbot/clawdbot.json 2>/dev/null

# Check OS audit log for Keychain access events (macOS)
log show --predicate 'eventMessage contains "Clawdbot"' \
    --start "2026-01-27 00:00:00" 2>/dev/null \
    | grep -i "keychain\|secret\|api_key"

# Linux: check Secret Service access audit
journalctl --since="2026-01-27" | grep -i "secret service\|clawdbot\|openclaw" 2>/dev/null

# Review email_send tool calls for external recipients
cat "$INCIDENT_DIR/openclaw-logs/telemetry.jsonl" \
  | jq 'select(
      .event_type == "tool_executed"
      and .tool_name == "email_send"
    )
    | {timestamp, recipients: .tool_args.recipients, subject: .tool_args.subject}'

Phase 4: Assess Skill Integrity

If the compromise came via a malicious skill, identify which skill, whether it modified SOUL.md, and whether it created any persistence mechanisms.

# Compare current skill hashes against your baseline manifest
python3 skill_manifest.py \
    --compare "$INCIDENT_DIR/../manifest_baseline.json" \
    --output "$INCIDENT_DIR/manifest-at-incident.json"

# Check SOUL.md for injected instructions
# Look for: scheduled task references, external URLs,
# unusual behavioral directives, base64-encoded content
cat "$INCIDENT_DIR/SOUL.md.evidence" | grep -E \
    "(schedule|cron|http|base64|eval|exec|ignore.*previous|override)"

# Check for scheduled tasks created by the agent (Linux)
crontab -l 2>/dev/null | grep -v "^#"
systemctl list-units --type=service | grep -i "openclaw\|moltbot\|clawd"

Automated forensic collection scriptscollect_evidence.sh, build_timeline.sh, check_credential_scope.sh, verify_hash_chain.py


IOC Reference

Framework mapping: NIST CSF ID.RA (Risk Assessment), DE.CM-1 (Network monitored for attack events)

This is the complete IOC set for OpenClaw, Moltbot, and Clawdbot deployments. Use these in your SIEM blocklists, EDR custom IOC feeds, and threat intelligence platforms.

Network

Domains

openclaw[.]ai
docs.openclaw[.]ai
clawhub.openclaw[.]ai
molt[.]bot
docs.molt[.]bot
clawd[.]bot
docs.clawd[.]bot
moltbotai[.]chat
moltbook[.]ai
clawhub[.]ai
auth.clawdhub[.]com

Ports

18789/tcp  -- OpenClaw Gateway (WebSocket + HTTP control panel)

URIs

127.0.0.1:18789
ws://127.0.0.1:18789
0.0.0.0:18789   -- CRITICAL: internet-exposed variant

Process

Command line patterns

openclaw gateway
openclaw status
openclaw onboard
openclaw doctor
openclaw security audit
openclaw orchestrator
openclaw-openclaw-gateway
openclaw-orchestrator
openclaw.mjs
molt.bot
clawd.bot
127.0.0.1:18789
ws://127.0.0.1:18789

Filesystem

Paths and files

~/.openclaw/
~/.moltbot/
~/.clawdbot/
SOUL.md                         -- Persistent identity file (monitor for writes)
Skill.md                        -- Skill definition files
entry.js                        -- Skill entry point
openclaw.mjs                    -- Main agent process
~/.moltbot/moltbot.json         -- Primary credential store
~/.moltbot/moltbot.json.bak*    -- Backup credential files (spans .bak through .bak.4)
~/.clawdbot/clawdbot.json.bak*  -- Legacy Clawdbot backup files
%USERPROFILE%\openclaw\         -- Windows installation path
%USERPROFILE%\.local\bin\openclaw.cmd  -- Windows CLI binary

Infostealer Target Patterns (Active as of February 2026)

Hudson Rock's telemetry confirmed that RedLine, Lumma, and Vidar adapted to explicitly enumerate these patterns within 72 hours of the January 2026 disclosures:

*/.moltbot/*.bak*
*/.clawdbot/*.bak*
*/.openclaw/*.bak*
~/.moltbot/moltbot.json
~/.clawdbot/clawdbot.json

YARA Rules

Four YARA rules are available in the repository for scanning disk images, EDR memory dumps, and SIEM-ingested file telemetry. The rule below detects backup credential files containing API keys — the pattern that remained exploitable for 35 days after users believed they had rotated:

rule OpenClaw_Backup_Credential_File {
    meta:
        description = "Detects OpenClaw/Moltbot/Clawdbot backup credential files containing API keys"
        author      = "openclaw-security-playbook"
        date        = "2026-02-20"
        severity    = "high"
    strings:
        $anthropic = "\"anthropicKey\"" ascii
        $openai    = "\"openaiKey\""    ascii
        $bak_hint  = ".json.bak"        ascii
        $path1     = ".moltbot"         ascii
        $path2     = ".clawdbot"        ascii
    condition:
        (\(anthropic or \)openai) and (\(bak_hint or \)path1 or $path2)
}

The other three rules cover: OpenClaw process artifacts on disk (OpenClaw_Process_Presence), suspicious content patterns in SOUL.md that indicate prompt injection persistence (OpenClaw_SOUL_Modification), and skill scripts making unexpected outbound HTTP calls indicative of staged payload retrieval (OpenClaw_Staged_Payload_Fetch).

All four YARA rules

Sigma Rules

Four platform-agnostic Sigma rules are available for conversion to any supported SIEM using pySigma. The rule below detects SOUL.md modifications by non-agent processes — the persistence mechanism that Hunt 5 monitors at runtime:

title: OpenClaw SOUL.md Modified by Non-Agent Process
id: d4e5f6a7-b8c9-0123-bcde-f45678901234
status: experimental
description: >
  Detects modification of SOUL.md by a process other than openclaw.mjs or node.
  SOUL.md injects into every agent session; attacker-controlled modifications
  create persistence that survives restarts. MITRE ATLAS T-PERSIST-001.
references:
  - https://cloudsecops.hashnode.dev/openclaw-detecting-compromise
  - https://trust.openclaw.ai/trust/threatmodel
author: openclaw-security-playbook
date: 2026/02/20
tags:
  - attack.persistence
  - attack.t1546
  - atlas.t-persist-001
logsource:
  category: file_event
  product: windows
detection:
  selection:
    TargetFilename|endswith: '\SOUL.md'
    EventType: 'FileModified'
  filter_legitimate:
    Image|endswith:
      - '\openclaw.mjs'
      - '\node.exe'
      - '\node'
  condition: selection and not filter_legitimate
falsepositives:
  - User manually editing SOUL.md in a text editor (document and suppress per user)
level: high

The other three rules cover: gateway port exposure (openclaw-gateway-exposure.yml), credential path reads (openclaw-credential-harvest.yml), and skill child process spawning (openclaw-skill-child-process.yml).

All four Sigma rulesFlat IOC file (importable to SIEM blocklists)


Detection Gaps: Where This Falls Short

The detection content in this post has real limits and you should understand them before presenting it to your team as coverage.

Prompt injection is not reliably detectable in real time. The attack lands inside a natural language string. By the time the tool execution happens - which is what Tier 2 detects - the injection has already succeeded. You're detecting the consequence, not the event. The practical implication is that your detection posture for prompt injection is: catch the execution, not the instruction.

Benchmarks also reveal that tool-abuse detection is the biggest blind spot: even the best detectors block only around 9–17 % of unauthorized tool calls. This highlights the need for runtime enforcement and monitoring beyond static injection detection.

What DefenseClaw closes (April 2026): If deployed, DefenseClaw's enforcement events close two of the most significant detection gaps:

  1. Agent-generated code execution gap: Hunt 3 and Kill Chain 1 queries detect off-hours exec calls but cannot inspect the content of what gets executed. DefenseClaw's CodeGuard scans the generated code before execution and emits a dc_codeguard event with findings. This surfaces command injection and secrets-harvesting code that would otherwise execute silently and only be visible via process-level EDR telemetry.

  2. Supply chain gap (pre-install): The manifest drift detection in Part 2 Layer 5 detects tampering after install. DefenseClaw catches malicious skills before install and emits a dc_block event with severity and reason. Add index=defenseclaw_events event_type=dc_block trigger=supply_chain severity=critical as a standing Splunk alert — any result is a high-priority finding.

What DefenseClaw does not close: Single-session, low-tool-count prompt injection attacks that complete before any rate-limit or burst threshold fires. If an attacker sends one carefully crafted email that results in exactly one file_read of ~/.ssh/id_ed25519 and one email_send, and both complete in under 30 seconds, none of the Tier 2 queries and no DefenseClaw pattern will fire unless the agent-generated code path is involved. The only reliable mitigation for this scenario is disabling the email_send tool entirely or requiring human confirmation (Part 2, Layer 4).

Telemetry-dependent queries require Part 2 to be complete. Tier 2 and Tier 3 behavioral hunting only work if openclaw-telemetry is deployed and forwarding to your SIEM. If you're deploying these detections against existing endpoints that never had telemetry configured, you have process-level visibility only. That means Tier 1 discovery queries are your primary tool and your behavioral gap is significant.

The Staged Payload kill chain (T-EVADE-004) is difficult to detect without a known-good domain allowlist. The queries in Kill Chain 4 work well if you've taken the time to build and maintain a list of expected outbound domains for your deployment. Without it, web_fetch calls look identical whether they're retrieving a user-requested webpage or downloading a second-stage payload.

Hash chain integrity tells you whether logs were tampered, not what was deleted. If an attacker gained sufficient access to delete log files entirely before you collected them, the chain-hash verification produces no output. Collection timing matters — the Phase 0 evidence preservation script should run as an automated response action, not a manual step.

These queries assume the attacker has not disabled openclaw-telemetry. An attacker with sufficient access to modify the agent configuration can disable the telemetry plugin. Detecting that event requires a separate monitor on the OpenClaw configuration file itself, which the SOUL.md monitoring query in Tier 2 partially covers.

Pair this detection content with your EDR's out-of-band process and network telemetry, and treat missing telemetry on an endpoint as a finding in its own right.

Real-Time Protection on the Moltbook Social Network

Researchers found that about 506 posts (≈ 2.6 % of those analysed) on Moltbook—a closed social network for AI agents—contained malicious instructions attempting prompt injection or coercing agents to violate policy. The Moltbook-Agent-Guard library scans each post in memory and blocks it if an anomaly is detected, preventing the language model from processing it. It detects jailbreaks, credential theft, data exfiltration, prompt extraction, role hijacking and encoded payloads, providing immediate protection in chat-like environments. Integrate this guard when your agents consume messages from external users.


Production Detection Checklist

Before signing off that detection coverage is in place for your fleet:

Tier 1: Discovery

  • [ ] CrowdStrike/MDE/Cortex/SentinelOne/Splunk discovery query deployed as a scheduled rule (run daily minimum)

  • [ ] Port 18789 network rule active in your SIEM and EDR

  • [ ] DNS IOCs (openclaw.ai, molt.bot, clawd.bot, clawhub.*, moltbotai.chat) in your DNS monitoring blocklist or alert policy

  • [ ] openclaw-detect deployed via MDM for shadow installation coverage (see Part 2, Layer 7)

  • [ ] Baseline of approved OpenClaw installations documented in asset inventory

Tier 2: Behavioral Hunting

  • [ ] openclaw-telemetry deployed on all OpenClaw endpoints (see Part 2, Layer 6)

  • [ ] SIEM CEF/syslog forwarding configured and verified with a test event

  • [ ] Credential path read alert active (Hunt 1)

  • [ ] file_reademail_send sequence alert active (Hunt 2)

  • [ ] Off-hours execution alert active (Hunt 3)

  • [ ] Burst tool execution alert active (Hunt 4)

  • [ ] SOUL.md modification alert active (Hunt 5) — this one is high priority; deploy it first

  • [ ] Alert tuning completed based on 7-day baseline of normal activity

  • [ ] (If DefenseClaw deployed) dc_block alert active for trigger=runtime_inspection and trigger=codeguard events

  • [ ] (If DefenseClaw deployed) dc_block + credential_read join query deployed (Hunt 2-DC above)

  • [ ] (If DefenseClaw deployed) DefenseClaw supply chain block alert active: event_type=dc_block trigger=supply_chain severity=critical

Tier 3: Kill Chain Coverage

  • [ ] Inbound message → high-risk tool execution alert deployed (Kill Chain 1)

  • [ ] web_fetch → environment enumeration sequence alert deployed (Kill Chain 2)

  • [ ] Skill process spawning shell child process alert deployed (Kill Chain 3)

  • [ ] Domain allowlist built for web_fetch monitoring (Kill Chains 2 and 4)

  • [ ] Token reuse anomaly detection active (Kill Chain 5)

Forensics Readiness

  • [ ] Evidence preservation script staged on each OpenClaw endpoint, executable as a response action

  • [ ] Log retention period sufficient for forensic investigation (90 days minimum)

  • [ ] Incident response playbook from Part 2 reviewed by SOC team with agent-specific steps understood

  • [ ] Hash chain integrity verification procedure documented and tested

  • [ ] MITRE ATT&CK/ATLAS TTP mapping distributed to SOC and IR team for case taxonomy


The Answer to Your CISO's Question

"How will you know when it's compromised?"

You'll know because port 18789 will show up in your SIEM before an attacker pivots to the credential store. You'll know because a file_read against .ssh followed by email_send in the same session is a sequence that fires Hunt 2 before exfiltration completes. You'll know because SOUL.md modification outside the agent process is a one-signal, near-zero false positive indicator that something has established persistence.

You won't always know in time. The Detection Gaps section is honest about that. Prompt injection that completes in a single session and leaves no email trail won't fire any of these rules. But "in time" is only one measure of detection value. The other is forensics: if you have telemetry with an intact hash chain, you can reconstruct the full attack sequence weeks after the fact, answer the scope question precisely, and give your IR team evidence that holds up.

That is what Parts 1 and 2 made possible. This post is how you use it.

This completes the OpenClaw Security Playbook — three parts covering the attack surface, the defense architecture, and the detection layer for the most widely deployed unauthorized AI agent of 2026.

Corrections or additions? Open a GitHub issue at topazyo/openclaw-security-playbook or reach out on LinkedIn.

Found this useful? Share it with your SOC team and star the repository — detection content improves when defenders collaborate.


Additional Resources

Community security tools for OpenClaw deployments

  • openclaw-detect (Knostic) — Shadow AI discovery via MDM deployment; prerequisite for Tier 1 coverage on endpoints without full EDR

  • openclaw-telemetry (Knostic) — Enterprise telemetry with SIEM integration; prerequisite for all Tier 2 and Tier 3 detection

  • openclaw-shield (Knostic) — 5-layer runtime defense plugin covering prompt injection, output scanning, and tool blocking (Part 2, Layer 4)

  • clawguard (Capsule Security) — JavaScript/TypeScript prompt injection guards with 150+ detection patterns (Part 2, Layer 4)

  • AgentShield Benchmark - Comparative benchmark for agent-security tools covering detection quality, tool-abuse coverage, and overall effectiveness

  • Security-Skill-Scanner — Local scanning for risky or malicious skills as an alternative pre-install validation option

  • Moltbook-Agent-Guard — Real-time scanning and blocking of malicious Moltbook posts before the model processes them

  • DefenseClaw (Cisco, April 2026) — Supply chain scanning (skills + MCPs), runtime inspection engine with CodeGuard, and one-command Splunk setup. Emits dc_block and dc_codeguard events that extend the Tier 2 behavioral hunting queries in this post. Designed for OpenClaw deployments on NVIDIA's OpenShell sandbox.

Detection content for this post

Original security research


Series Navigation

← Part 1: Attack Vectors and Verification | ← Part 2: Production Security Architecture

OpenClaw Security Playbook

Part 3 of 3

Complete security playbook for OpenClaw and AI agents: attack vectors, immediate mitigations, and 7-layer defense-in-depth with production configs.

Start from the beginning

OpenClaw Security: Fix 3 Critical AI Agent Backdoors

1,200+ exposed instances, 91.3% prompt injection rate, and credential backups users didn't know existed