Back to Intelligence

Carbonato Botnet Hijacking Exposed Docker Daemons with AI Agents — Detection and Hardening Guide

SA
Security Arsenal Team
September 24, 2026
11 min read

A new botnet tracked as Carbonato is actively compromising Docker hosts whose daemons are exposed to the internet without authentication. Once it finds an open Docker Remote API endpoint, Carbonato deploys a containerized foothold and installs the Hermes Agent AI framework — an AI-agent toolkit that gives the operators an autonomous, LLM-driven control layer on the victim host. This is a meaningful evolution in botnet tradecraft: instead of static shell scripts and hardcoded C2 logic, the operators are delegating post-exploitation decision-making to an AI agent running on the compromised machine.

If your organization runs Docker on any cloud VM, bare-metal server, or edge appliance, you need to verify today that port 2375 (unencrypted) and 2376 (TLS) are not reachable from the internet, and hunt for the indicators described below. Exposed Docker daemons are one of the most reliably abused misconfigurations in cloud security — Carbonato is simply the latest and most sophisticated crew monetizing them.

Technical Analysis

What is being targeted

  • Affected platform: Any Linux host running the Docker Engine (dockerd) with the Remote API bound to a network interface without authentication — most commonly TCP port 2375 (plaintext) or port 2376 without proper client certificate verification.
  • Common exposure paths: dockerd -H tcp://0.0.0.0:2375 in startup scripts, daemon.json with "hosts": ["tcp://0.0.0.0:2375"], systemd unit overrides (ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375), and developer convenience configurations that leak into production images.
  • Payload: A malicious container image pulled over the exposed API, followed by installation of the Hermes Agent AI framework on the host (typically via a bind-mounted host filesystem, giving the container trivial write access to /).

Attack chain (defender's view)

  1. Reconnaissance: Internet-wide scanning for TCP/2375 and TCP/2376 responding to the Docker API version handshake (GET /version).
  2. Initial access: Unauthenticated POST /images/create to pull an attacker-controlled image, followed by POST /containers/create and POST /containers/{id}/start. The container spec typically includes --privileged or a bind mount of the host root ("Binds":["/:/host"]), which is functionally equivalent to root on the host.
  3. Execution & persistence: From inside the container, the attacker writes to the host filesystem via the bind mount — installing the Hermes Agent binary, adding cron entries (/etc/cron.d/), systemd units, or modifying shell profiles, and pulling additional tooling.
  4. Command and control: The Hermes Agent establishes outbound connectivity to operator infrastructure. Because the agent is AI-driven, its behavior is less predictable than a classic botnet client: expect varied process execution, ad-hoc script generation (Python/shell), and reconnaissance activity driven by the agent rather than fixed playbooks.
  5. Monetization: The compromised host joins the Carbonato botnet — resources are available for cryptomining, DDoS, proxying, or follow-on intrusion depending on what the operator directs the agent to do.

Why the AI-agent angle matters to defenders

Traditional botnet detections rely on repeatable command lines and stable C2 beacons. An AI agent on the host means behavioral variance is the norm: one infected host may enumerate cloud credentials, another may pivot laterally via SSH, a third may simply mine. Signature-based detection on the payload alone will underperform. The reliable detection surface is the access vector (exposed daemon, anomalous container creation) and the persistence/egress artifacts, not the agent's day-to-day behavior.

Exploitation status

  • Actively exploited in the wild. Carbonato is an operational botnet campaign scanning for and compromising exposed Docker daemons now. This is not theoretical.
  • No CVE is associated with this campaign — it exploits misconfiguration, not a software vulnerability. That also means there is no patch coming to save you; remediation is purely an exposure-management exercise.

Detection & Response

The highest-fidelity signals are: (1) Docker API container/image creation events not originating from your known CI/CD or orchestration plane, (2) containers created with host-root bind mounts or privileged mode, (3) dockerd/containerd child processes touching host persistence locations, and (4) unexpected outbound connections from hosts that should only serve containers.

Sigma Rules

YAML
---
title: Suspicious Container Creation with Host Root Mount or Privileged Mode
id: 3f8c2a41-7b9e-4d1c-a5f6-9c2e1b7d3a05
status: experimental
description: Detects docker client or API-driven container creation that bind-mounts the host root filesystem or requests privileged mode, consistent with Carbonato-style compromise of an exposed Docker daemon.
references:
  - https://www.bleepingcomputer.com/news/security/new-carbonato-malware-uses-ai-agents-to-hijack-exposed-docker-hosts/
  - https://attack.mitre.org/techniques/T1610/
author: Security Arsenal
date: 2026/06/12
tags:
  - attack.execution
  - attack.privilege_escalation
  - attack.t1610
  - attack.t1611
logsource:
  category: process_creation
  product: linux
detection:
  selection_img:
    Image|endswith:
      - '/docker'
      - '/docker-cli'
      - '/ctr'
      - '/nerdctl'
  selection_flag:
    CommandLine|contains:
      - 'run'
      - 'create'
  selection_escape:
    CommandLine|contains:
      - '--privileged'
      - '-v /:/'
      - '-v /:/host'
      - '--volume /:/'
      - '/:/host'
      - '--pid=host'
      - '--net=host'
      - '--cap-add SYS_ADMIN'
  condition: selection_img and selection_flag and selection_escape
falsepositives:
  - Legitimate host-management containers (monitoring agents, backup tooling) — baseline known images
level: high
---
title: Docker Remote API Access Over Unauthenticated Port 2375
id: 8a1e5c72-3d4b-4f6a-b2c8-5e7d9a1f3b26
status: experimental
description: Detects inbound network connections to the Docker daemon on TCP 2375 (unauthenticated plaintext API), the primary access vector abused by the Carbonato botnet.
references:
  - https://www.bleepingcomputer.com/news/security/new-carbonato-malware-uses-ai-agents-to-hijack-exposed-docker-hosts/
  - https://attack.mitre.org/techniques/T1190/
author: Security Arsenal
date: 2026/06/12
tags:
  - attack.initial_access
  - attack.t1190
  - attack.t1610
logsource:
  category: network_connection
  product: linux
detection:
  selection:
    DestinationPort: 2375
    Image|endswith:
      - '/dockerd'
  condition: selection
falsepositives:
  - Internal orchestration traffic where 2375 is intentionally (though insecurely) used — treat any hit as a finding to remediate
level: high
---
title: Shell or Interpreter Spawned by Container Runtime
id: b62d9f18-4e7a-4c35-9d81-2a6c8e4f7b19
status: experimental
description: Detects shells or script interpreters spawned directly by dockerd or containerd, a common post-exploitation artifact when attackers execute commands through a container escape or a bind-mounted host filesystem, as seen in Carbonato infections.
references:
  - https://www.bleepingcomputer.com/news/security/new-carbonato-malware-uses-ai-agents-to-hijack-exposed-docker-hosts/
  - https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/06/12
tags:
  - attack.execution
  - attack.t1059.004
  - attack.t1059.006
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|endswith:
      - '/dockerd'
      - '/containerd'
      - '/containerd-shim'
      - '/containerd-shim-runc-v2'
  selection_child:
    Image|endswith:
      - '/sh'
      - '/bash'
      - '/dash'
      - '/python'
      - '/python3'
      - '/perl'
      - '/curl'
      - '/wget'
      - '/crontab'
      - '/systemctl'
  condition: selection_parent and selection_child
falsepositives:
  - Containers whose entrypoint is a shell script — filter by image name or container ID in your environment
level: medium

KQL — Microsoft Sentinel / Defender

This query hunts for evidence of exposed-daemon abuse: remote API connections to 2375/2376 and container creation events originating from unexpected sources, using Syslog/CEF ingestion and Defender process telemetry.

KQL — Microsoft Sentinel / Defender
let Lookback = 14d;
let DockerHosts = (DeviceNetworkEvents
    | where Timestamp > ago(Lookback)
    | where LocalPort in (2375, 2376)
    | summarize arg_max(Timestamp, *) by DeviceName);
// Part 1: Inbound connections to Docker Remote API from non-private IPs
let RemoteAPIAccess = DeviceNetworkEvents
    | where Timestamp > ago(Lookback)
    | where LocalPort in (2375, 2376)
    | where RemoteIPType == "Public"
    | summarize Connections=count(), FirstSeen=min(Timestamp), LastSeen=max(Timestamp),
        SourceIPs=make_set(RemoteIP), Actions=make_set(ActionType) by DeviceName, LocalPort
    | project DeviceName, LocalPort, Connections, FirstSeen, LastSeen, SourceIPs;
// Part 2: Suspicious container execution / escape-style command lines
let SuspiciousContainerExec = DeviceProcessEvents
    | where Timestamp > ago(Lookback)
    | where DeviceName in (DockerHosts | project DeviceName)
    | where ProcessCommandLine has_any ("--privileged", "/:/host", "-v /:/", "--pid=host", "--cap-add")
       or (InitiatingProcessFileName has_any ("dockerd", "containerd")
           and FileName in~ ("sh", "bash", "dash", "python", "python3", "curl", "wget", "crontab", "systemctl"))
    | project Timestamp, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName,
        InitiatingProcessCommandLine, AccountName;
union RemoteAPIAccess, SuspiciousContainerExec
| order by DeviceName asc

Velociraptor VQL

Use this hunt artifact on suspected Docker hosts to enumerate runtime state: container runtime processes, suspicious children, listening API ports, and persistence artifacts that Hermes Agent installation would touch.

VQL — Velociraptor
-- Carbonato Docker host triage: runtime processes, API listeners, persistence
SELECT * FROM {
  -- Processes tied to container runtime and suspicious child processes
  SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime, 'process' AS Artifact
  FROM pslist()
  WHERE Name =~ 'docker|containerd|runc|hermes'
     OR (CommandLine =~ 'privileged|/:/host|--pid=host|--cap-add'
         AND CommandLine =~ 'docker|ctr|nerdctl')
} UNION {
  -- Listening sockets: flag Docker API bound to non-loopback interfaces
  SELECT Pid, NULL AS Ppid, Name, String AS CommandLine, Laddr AS Exe,
         Raddr AS Username, NULL AS CreateTime, 'listener' AS Artifact
  FROM netstat()
  WHERE Laddr.Port in (2375, 2376) AND Laddr.IP !~ '^127\\.'
} UNION {
  -- Persistence surfaces commonly written via host bind mount
  SELECT NULL AS Pid, NULL AS Ppid, Name, FullPath AS CommandLine,
         Size.String AS Exe, Mtime.String AS Username, NULL AS CreateTime,
         'persistence_file' AS Artifact
  FROM glob(globs=[
    '/etc/cron.d/*',
    '/etc/systemd/system/*.service',
    '/etc/systemd/system/*.timer',
    '/usr/local/bin/*hermes*',
    '/opt/*hermes*',
    '/root/.ssh/authorized_keys'
  ])
  WHERE Mtime > now() - 1209600
}

Triage & Hardening Script (Bash)

Run this on any Docker host to (1) determine whether the daemon is exposed, (2) audit for Carbonato-style container abuse, and (3) apply immediate hardening. It is read-only except for the clearly marked hardening section at the bottom — review before executing in production.

Bash / Shell
#!/bin/bash
# Carbonato exposure triage & hardening for Docker hosts
echo "=== [1] Docker daemon listening sockets ==="
ss -tlnp | grep -E ':(2375|2376)' && echo "[!] Docker API is network-reachable" || echo "[OK] No TCP Docker API listener"

echo "=== [2] Daemon configuration review ==="
grep -rE '"hosts"|tcp://' /etc/docker/daemon.json /etc/systemd/system/docker.service.d/ 2>/dev/null
grep -E 'ExecStart.*(-H|--host).*tcp' /lib/systemd/system/docker.service /etc/systemd/system/docker.service.d/*.conf 2>/dev/null

echo "=== [3] Suspicious containers: privileged / host-root mounts ==="
for c in $(docker ps -aq 2>/dev/null); do
  docker inspect "$c" --format '{{.Name}} | Image={{.Config.Image}} | Privileged={{.HostConfig.Privileged}} | Binds={{.HostConfig.Binds}} | Created={{.Created}}' 2>/dev/null
done | grep -Ei 'true|/:/|/host|unknown|alpine|busybox' 

echo "=== [4] Recently pulled images (review for anything you did not deploy) ==="
docker images --format '{{.Repository}}:{{.Tag}} | {{.CreatedAt}} | {{.ID}}' 2>/dev/null | head -30

echo "=== [5] Persistence check: recent cron/systemd/SSH changes ==="
find /etc/cron.d /etc/cron.daily /etc/systemd/system -type f -mtime -14 2>/dev/null
stat -c '%y %n' /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys 2>/dev/null

echo "=== [6] Hunt for Hermes Agent artifacts ==="
find / -iname '*hermes*' -type f -mtime -30 2>/dev/null | grep -vE '^/(proc|sys)'
ps aux | grep -i hermes | grep -v grep

echo "=== [7] Outbound connections from container runtime processes ==="
ss -tnp | grep -E 'dockerd|containerd|hermes'

# --- HARDENING (review before running) ---
# 1) Remove any tcp:// binding from daemon.json and systemd overrides; use the local socket only.
# 2) If remote API access is required, enforce TLS with client certs on 2376:
#    "tlsverify": true, "tlscacert", "tlscert", "tlskey" in daemon.json
# 3) Block the ports at the edge even after fixing the daemon (defense in depth):
#    sudo iptables -A INPUT -p tcp --dport 2375 -j DROP
#    sudo iptables -A INPUT -p tcp --dport 2376 ! -s <approved_mgmt_cidr> -j DROP
# 4) Restart docker to apply: sudo systemctl restart docker

Remediation

Immediate (today):

  1. Enumerate exposure. Query your external attack surface (or just run nmap -p 2375,2376 from outside your network against every public IP you own). Any host answering on 2375 with an unauthenticated /version response must be treated as potentially compromised, not merely misconfigured.
  2. Assume breach on exposed hosts. If a daemon was reachable, run the triage script above, review docker images and docker inspect output for unknown images/containers, check cron/systemd/SSH persistence, and strongly consider rebuilding the host from a known-good image. Carbonato installs an agent on the host itself — stopping the malicious container is not sufficient.
  3. Remove the exposure. Bind the daemon to the local Unix socket only (/var/run/docker.sock). If remote management is genuinely required, configure TLS with mutual client certificate verification on port 2376 per the official Docker daemon security documentation, and restrict source IPs at the security group/firewall layer. Never expose 2375.

Short term (this week):

  • Deploy the Sigma/KQL detections above and alert on any container created with --privileged, host-root bind mounts, or --pid=host/--net=host outside an approved image list.
  • Centralize Docker daemon and container runtime logs (journald for docker.service, container stdout/stderr) into your SIEM — most Carbonato victims had zero visibility into API calls made against their daemon.
  • Add cloud security posture checks (CIS Docker Benchmark controls 2.1–2.15 and 5.x container runtime rules) to CI so exposed daemon configs cannot ship again.

Strategic:

  • Treat the Docker daemon socket as root-equivalent: anyone who can talk to the API can mount / into a container. Architect accordingly — rootless Docker or alternative runtimes (containerd with restricted CRI, gVisor, Kata) reduce blast radius.
  • Expect AI-agent-based botnets to become noisier and more varied at the endpoint while remaining identical at the access vector. Invest in exposure management and behavioral egress detection rather than payload signatures.

There is no vendor patch for this campaign because there is no software flaw — the fix is configuration discipline, and the window between exposure and compromise is measured in minutes given continuous internet-wide scanning.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.