Skip to main contentClaim $5 in free credit — one-time, per account. Claim $5 free
Krova CloudKrova Cloud
AI Code Sandboxing

Ollama Security: PoeLLM, the Botnet That Reads Poetry to Find Its Master

More than 3,400 servers mined monero for a botnet that reads a poem for orders. Its front doors were exposed LiteLLM and Ollama installs. The audit is short.

4 min read
Share
Ollama Security: PoeLLM, the Botnet That Reads Poetry to Find Its Master: a row of small server cubes with one lit by a teal mining-hash pattern while a ribbon of verse threads toward it

The command and control address lives in a poem. Four keywords lifted from On the Nature of Connection map through a hard-coded dictionary to an IPv4 address. The poem hides as a file called dash.css inside a GitHub fork of the nodejs.org website; edit it and every infected server recomputes where home is. That is PoeLLM, an ollama security story Lumen's Black Lotus Labs has tracked since April 2026 across more than 3,400 servers. Its front door is usually a model server bound to every interface with nothing authenticating in front of it.

The scale is industrial. Black Lotus Labs counts peaks of 800 active infected systems in a single day, mostly in the United States and Western Europe. The target list reads like a self-hosted AI stack inventory: LiteLLM proxies, Ollama model servers, Gotenberg converters, Gitea instances, Ivanti Sentry appliances in the telemetry. Compromised hosts run XMRig and Iron miners against the Kryptex pool, then join the scan line probing ports 3000 and 4000 on somebody else's network.

The door: a LiteLLM endpoint that spawns commands

The confirmed exploitation path is LiteLLM's MCP server test endpoint, /mcp-rest/test/connection, tracked as CVE-2026-42271. The April 2026 disclosure described it as requiring authentication; Horizon.ai later showed it chains with CVE-2026-48710 into unauthenticated remote code execution. The endpoint accepts a full server configuration including commands and environment variables, and LiteLLM spawns them. One POST buys command execution on the proxy host, the provider API keys the proxy holds, and a pivot into whatever the gateway connects to. Black Lotus Labs' write-up traces the rest: payload pulled from port 81, miners installed, host conscripted as scanner and exploit server.

A poem instead of a domain

Block one address and the poem moves. The operator has rotated the computed C2 eleven times so far. Servers sat on hijacked consumer routers, a Brazilian device exposing a Boa web server on port 2222 among them, so takedown chases home hardware. The sample carries Italian-language comments; attribution stops at moderate confidence. The motive never gets romantic: monero.

The same month brought a second campaign with a stranger address book. ChainDrop's Shai-Hulud worm resolves its C2 through an Ethereum smart contract. The tensorlake npm compromise pushed it into the AI tooling supply chain, harvesting cloud keys plus the MCP configuration files of Claude, Cursor, Kiro, Windsurf and Zed. Different hiding places, same thesis: a botnet's address book now lives wherever takedown teams cannot write.

The audit that ends the exposure class

  • Unmap the port before anything else. Every PoeLLM chain begins with an address that answered from the internet. A no-public-ip default removes the scan surface entirely; mapped ports with allowlists hand it back only to real clients.
  • Patch or fence the LiteLLM proxy. CVE-2026-42271 chained with CVE-2026-48710 is unauthenticated RCE. If patching waits on a change window, put the proxy behind mutual TLS and an IP allowlist today.
  • Authenticate Ollama at the gateway. The default install has no auth and no reason to face the world. Bind it to loopback inside its own microVM, and let a gateway that does authentication answer clients.
  • Starve the miner. XMRig and Iron need egress to pool addresses. An outbound allowlist converts a successful compromise into loud, unpaid work, and DNS lookups for pool domains are your cheapest detection signal.
  • Hunt the poem, not just the IP. Indicators rot when the C2 is a computed address, so watch for the lookup pattern itself. A serving host fetching a raw CSS file from a GitHub fork is anomalous enough to page on. The libgcrypt filename on disk is the sample's own signature.
  • Assume the keys moved. A mined host held provider tokens and proxy secrets; isolate first and rotate after, in that order, which is also the lesson ChainDrop's hostage payload teaches.

Krova's default posture is the first four bullets as architecture. No inbound address to scan, per-workload microVMs so a compromised converter cannot read the model server's memory, egress you allowlist, teardown that ends persistence. Running untrusted code safely covers the layer below, where the workload itself is the hostile party.

FAQ

Is cryptomining the worst outcome here? Mining is the revenue, not the objective. The same foothold reads provider API keys and proxy configuration, then conscripts your host into scanning its peers. Treat any miner as proof of full host compromise and rotate accordingly.

Does the poem C2 make PoeLLM undetectable? It defeats static blocklists, not observation. The lookup is visible: a serving host fetching poetry from a GitHub fork is anomalous enough to alert on, and miner pool traffic is louder still.

What should small teams patch first? The internet-facing proxy, then the model server. LiteLLM's chained RCE buys everything on the host, while an exposed Ollama buys compute and a scanning position.

Serve models, not scanners

Krova Cubes boot with no public IP. Your Ollama and LiteLLM stacks answer only mapped, allowlisted ports, and botnets find no door at all.

For AI agents:llms.txtsitemap

Related posts