CARBONATO is a botnet targeting exposed Docker servers and using them as entry points for further attacks.
Once a server is compromised, the malware can install an AI agent that receives instructions through Telegram. The agent can then execute commands, collect information, and send the results back to the attackers.
The campaign starts with a simple security mistake: Docker services exposed to the internet without authentication.
Researchers from ThreatDown discovered the activity after finding an unauthenticated Docker registry that had been exposed since May 2026. The registry contained dozens of repositories and hundreds of image tags, providing researchers with a detailed look at the operation.
CARBONATO Adds an AI Agent
The attackers use the open-source Hermes Agent framework as part of the operation.
Rather than changing the framework itself, they replace its configuration instructions with a short set of commands telling the agent to maintain access, search for sensitive information, and follow instructions received through Telegram.
When an operator sends a task, the AI model processes the request and determines which terminal commands should be used. The commands are then executed on the compromised server, with the results sent back to the attackers.
The agent searches for valuable information such as:
- AI API keys
- SSH credentials
- Access tokens
- Database information
This makes the compromised server useful for more than simply running malware. It can also become a source of credentials that may help attackers access additional systems.
How the Botnet Spreads
CARBONATO looks for Docker daemons that accept unauthenticated connections.
After finding one, the malware can launch a privileged container with access to the host’s files, processes, and network. It then establishes access and creates several persistence mechanisms.
The malware uses methods including:
- Cron jobs
- Systemd timers
- Startup scripts
- OpenRC
- Reverse SSH tunnels
It can also disguise some of its files and processes as normal Linux activity.
Every few minutes, CARBONATO checks networks connected to the compromised server and scans /24 ranges for other exposed Docker services.
When another vulnerable Docker daemon is discovered, the same deployment process can be repeated.
Importantly, the AI agent is not responsible for the automated spreading. Traditional scripts handle the scanning and deployment.
What Security Teams Should Do
The operation highlights the danger of exposing Docker management interfaces directly to the internet.
Organizations should:
- Keep Docker daemon APIs off public networks
- Require authentication for container registries
- Look for unexpected privileged containers
- Investigate unusual Telegram traffic from servers
- Check for unexpected persistence mechanisms
- Rotate exposed AI API keys and other credentials
- Review Docker configurations for unauthorized access
The main lesson is simple: an exposed Docker service can become the starting point for a much larger compromise. Securing container infrastructure should be treated as part of the organization’s overall security strategy.
IoCs
| Type | Indicator | Description |
|---|---|---|
| Network | 45[.]79[.]183[.]61 | C2 hub (Linode) |
| Network | 91[.]99[.]195[.]164 | fsociety-era C2 (Hetzner) |
| Network | 213[.]136[.]79[.]115 | Beacon / reverse shell (Contabo, :8080 and :4444) |
| Network | 213[.]136[.]83[.]197 | LLM gateway (Contabo), live |
| Network | 190[.]211[.]124[.]187 | Reverse-tunnel sink (AS262145, Costa Rica) |
| Network | carbonato-proxy-{drab,zeta,zeta-2}[.]vercel[.]app | LLM proxies, suspended |
| Network | Registry fleet on AS40065 | Seven endpoints, six live, withheld while live |
| Container | gh0st/, fsociety/, netd-svc, system/resolved, scrub-empty | Repository names, 59 total |
| Container | GH0ST_C2, FSOCIETY_DISABLE_TUNNEL, GATEWAY_ALLOW_ALL_USERS | Image environment variables |
| Container | /opt/gh0st/entry.sh, auto-persist-host.sh, SOUL.md | Implant kit files |
| Host | /usr/local/bin/.docker-network-monitor | Watchdog binary |
| Host | /usr/sbin/systemd-logind | Miner disguised as a system service |
| Host | [kworker/u2:0] | Disguised process arguments |
| Secret | carbonato125 | Shared password across the archive |
| Secret | CARBONATO_API_KEY | .env variable on infected hosts |
| Telegram | Chat 750752697 | Deployment reports and C2 chat |