DEV Community

senturkselim
senturkselim

Posted on

Building 646 Suricata Rules to Detect AI Agent Threats: OpenClaw Security with CGTI Lite

 # Building 646 Suricata Rules to Detect AI Agent Threats: OpenClaw Security with CGTI Lite

Between January and March 2026, the OpenClaw AI agent ecosystem faced a wave of targeted attacks that existing security tools weren't equipped to handle. The ClawHavoc campaign distributed 1,184+ malicious skills through ClawHub. GhostClaw RAT spread via typosquatted npm packages. AMOS Stealer harvested macOS credentials. 135,000+ OpenClaw instances were found exposed on the public internet with zero authentication. 25 CVEs were disclosed, with CVSS scores reaching 9.9.

I looked for Suricata rules covering these threats. MCP protocol exploitation, WebSocket gateway attacks, AI skill supply-chain poisoning — none of it was covered by ET Open, ET Pro, or any community ruleset I could find.

So I built CGTI Lite for OpenClaw — 646 hand-crafted Suricata detection rules across 13 specialized categories, plus a cross-platform management tool. This post explains the detection engineering behind it.

GitHub: https://github.com/Senturkselim/CGTI-for-OpenClaw


The Threat Landscape

Here's what CGTI Lite detects, mapped to the actual campaigns:

Threat What It Does CGTI Detection Method
ClawHavoc 1,184+ malicious ClawHub skills distributing infostealers C2 IPs, domains, skill download patterns, DNS queries
GhostClaw/GhostLoader RAT via typosquatted npm packages, exfil to GoFile.io TLS/HTTP C2 to trackpipe.dev, bootstrap payload URI, npm package detection
AMOS Stealer macOS infostealer targeting openclaw.json, crypto wallets TLS C2 (91.92.242.0/24), HTTP exfil patterns, BuildID header
Vidar 2.0 Credential store theft from ~/.openclaw/ JA3 fingerprint, TLS cert anomalies
GhostSocks Proxy malware turning hosts into SOCKS proxies Default cert CN, Stealth Packer indicators
25 CVEs RCE, sandbox escape, command injection Full kill-chain signatures per CVE

Rule Design: Why Two Indicators Minimum

Every CGTI rule requires at least two independent content matches. No rule fires on a single content: string alone. Here's why — and how it looks in practice.

Bad rule (single indicator, high FP risk):

alert http any any -> any any (
  msg:"Suspicious download";
  content:"download"; http.uri;
  sid:9999999; rev:1;
)
Enter fullscreen mode Exit fullscreen mode

This fires on literally any HTTP request with "download" in the URI.

CGTI approach (dual indicator):

alert tls $HOME_NET any -> $EXTERNAL_NET any (
  msg:"CGTI-OC GHOSTCLAW - TLS Connection to trackpipe.dev C2 Panel";
  flow:to_server,established;
  tls.sni; content:"trackpipe.dev"; nocase; isdataat:!1,relative;
  classtype:trojan-activity; priority:1;
  reference:url,research.jfrog.com/post/ghostclaw-unmasked/;
  sid:9200124; rev:1;
  metadata:malware_family GhostClaw, mitre_attack T1071.001,
           signature_severity Critical, false_positive Zero;
)
Enter fullscreen mode Exit fullscreen mode

This combines tls.sni match + isdataat:!1,relative (exact domain, not substring) + flow:to_server,established (only outbound TLS handshakes). The false positive rate on a known C2 domain is effectively zero.


Three Confidence Layers

Rules are organized into detection confidence tiers:

Layer 1 — High Confidence (priority 1): Known C2 IPs and domains, CVE-specific exploit signatures, JA3/JARM fingerprints. These are indicators derived directly from published threat research (JFrog, Huntress, DepthFirst Security, etc.). Near-zero false positive rate.

Layer 2 — Medium Confidence (priority 2): Behavioral patterns like data exfiltration to paste sites, unusual WebSocket commands, HTTP requests matching supply-chain attack patterns. These use threshold-based detection and require protocol-specific scoping.

Layer 3 — Low Confidence (priority 3): Heuristic rules like scanner detection, broad IP geolocation lookups, generic curl-to-shell patterns. Informational — meant to be tuned per deployment.


Detecting a 5-Phase CVE Kill Chain

CVE-2026-25253 (CVSS 8.8) enables 1-click RCE through gatewayUrl token exfiltration. The attack has 5 distinct phases, and CGTI has detection rules for each:

Phase 1 — Token exfiltration via gatewayUrl:

alert http $HOME_NET any -> $EXTERNAL_NET any (
  msg:"CGTI-OC CVE-2026-25253 Phase-1 gatewayUrl Token Exfil";
  flow:established,to_server;
  http.uri; content:"gatewayUrl=";
  http.uri; content:"token="; distance:0;
  classtype:trojan-activity; priority:1;
  reference:cve,2026-25253;
  sid:9200801; rev:1;
)
Enter fullscreen mode Exit fullscreen mode

Detecting each phase individually means even if the attacker modifies one step, the other phases still trigger alerts. Defense in depth at the rule level.


The DNS Blocking Problem (And How I Solved It)

This is the most technically interesting part of the project.

When Suricata fires a DNS alert (e.g., "host queried trackpipe.dev"), the destination IP in the EVE log is your DNS resolver — typically 8.8.8.8 or 1.1.1.1. If your autoblock system naively blocks the destination IP from the alert, it blocks your DNS server. Your entire internet breaks.

CGTI's Enhanced Autoblock handles this differently:

  1. Detect that the alert is DNS traffic (port 53)
  2. Extract the queried domain from the alert signature text
  3. Resolve that domain via system DNS to get the actual IP(s)
  4. Block the resolved IPs (the real C2 server), not the DNS resolver
  5. Apply RFC1918/CGNAT/loopback protection — never block private IPs
  6. Auto-whitelist configured DNS servers

So a DNS alert for trackpipe.dev results in blocking the actual GhostClaw C2 infrastructure IP, not your DNS resolver. Bidirectional — both INPUT and OUTPUT firewall rules are created.


False Positive Management

16 rules are shipped disabled by default. Each has a # DISABLED-FP: comment explaining exactly why:

  • SID:9200872 — Python REPL detection. Disabled because REPL is a core OpenClaw feature. Re-enable if you don't use the Python REPL.
  • SID:9202610 — MCP tools/call + exec. Matches legitimate tools like execute_query. Re-enable if you don't use any MCP tool with "exec" in its name.
  • SID:9201070registry.npmjs.org DNS. Fires on every npm install. Re-enable if your OpenClaw host never runs npm.

The README includes a full tuning guide organized by use case: Discord/Slack integrations, Telegram bots, crypto trading, MCP filesystem tools, etc.


IPS Mode on Linux: Avoiding the Fork Race

A technical detail that took significant debugging: Suricata's -D (daemon) flag causes a fork race condition with NFQUEUE binding on Linux. The forked child process tries to bind the NFQ queue before the parent fully exits, sometimes resulting in a failed bind.

CGTI's solution: start Suricata with subprocess.Popen + os.setpgrp instead of using -D. This keeps the process in the foreground from Python's perspective but fully detached from the parent process group. The NFQUEUE binding succeeds reliably.

The IPS flow:

  1. Stop any existing Suricata instance (including Ubuntu's suricata.service)
  2. Convert alert rules to drop rules in-place (reverts on stop)
  3. Auto-configure nfq: section in suricata.yaml
  4. Set up iptables -I NFQUEUE rules (with automatic rollback on failure)
  5. Start Suricata with -q 0 via Popen

Boot-Time Autostart: The Ubuntu Edge Case

On Ubuntu, installing Suricata via apt also installs suricata.service, which is enabled by default. At boot:

  1. suricata.service starts Suricata in IDS mode (--af-packet)
  2. cgti-lite.service runs — but Suricata is already running

If IPS mode is configured, CGTI detects this situation: Suricata is running but in IDS mode, not IPS. CGTI stops the IDS instance, then restarts Suricata in full NFQUEUE/IPS mode with iptables rules, drop rule conversion, and NFQ configuration.

This edge case took real-world testing on Ubuntu VMs to discover and fix properly.


Rule Coverage Summary

13 rule files, 646 active rules, SID range 9200001–9204419:

Category Rules What It Catches
Infostealer C2 67 AMOS, Vidar, GhostClaw, GhostSocks, DigitStealer
Reverse Shells 59 7 languages: bash, netcat, Python, Node.js, PowerShell, Go, Java
WebSocket Attacks 43 CVE-2026-25253 kill-chain, ClawJacked, log poisoning
Malicious Skills 50 Typosquatting, supply-chain, malicious install patterns
Data Exfiltration 57 Telegram, Discord, Slack, paste sites, cloud storage
Gateway Exposure 42 Scanner detection, exposed instances, lateral movement
Cryptostealer 41 Wallet theft, mining, seed phrases, exchange API keys
MCP Security 24 SSRF, tool injection, credential exfil
CVE Signatures 126 25 CVEs with full kill-chain coverage
Threat Intel IOCs 83 Malicious publishers, known attacker infrastructure
DNS Threats 34 C2, rebinding, typosquatting domains
TLS Anomalies 20 MITM, JA3/JARM, self-signed cert detection

Threat Intelligence Sources

All rules are built from published research — not generated or guessed:

  • JFrog Security Research — GhostClaw/GhostLoader RAT campaign
  • Huntress — AMOS Stealer analysis, GhostSocks campaign
  • DepthFirst Security — CVE-2026-25253 kill-chain discovery
  • Koi Security — ClawHavoc campaign (1,184+ malicious skills)
  • Darktrace, Trend Micro, Ontinue — Vidar/AMOS distribution research
  • Bitsight TRACE — 135K+ exposed instance scanning
  • Hunt.io — certificate analysis of 17,470+ instances
  • abuse.ch SSLBL — JA3 fingerprint database
  • MITRE ATT&CK — technique classification

Every rule includes reference: URLs pointing to the original research.


Getting Started

Rules only (any Suricata installation):

Copy the rules/ directory into your Suricata rules path and add them to rule-files: in suricata.yaml. Done.

Full management tool:

git clone https://github.com/Senturkselim/CGTI-for-OpenClaw.git
cd CGTI-for-OpenClaw
chmod +x install.sh && ./install.sh
cgti install
sudo cgti start
Enter fullscreen mode Exit fullscreen mode

Works on Linux, macOS, and Windows. Single Python file, rich as the only dependency.


What's Next

This is the first community-facing release from the CloudGo Threat Intelligence (CGTI) project. The rules will be updated as new threats emerge and new CVEs are disclosed. FP reports and contributions are welcome.

If you're running OpenClaw in production and want to test the rules against your traffic, I'd genuinely appreciate hearing about detection quality and false positive rates.

GitHub: https://github.com/Senturkselim/CGTI-for-OpenClaw
License: AGPL-3.0 — free forever.

Top comments (0)