The C2 Was Bound to Loopback — A Ransomware Affiliate Ran His Attack Through an MCP Tool Call

Every MCP threat model published since 2025 has carried the same footnote: a locally-bound MCP server is only as safe as the machine it runs on, and an attacker who already has a foothold can call its tools like any other local service. It was always the part of the risk register nobody had a field example for. CloudSEK’s “Caught in 4K: The Gentlemen Files”, published 5 October 2026, supplies one. The firm states plainly that it has not identified prior public reporting of a threat actor operationally using MCP exec_in_session as a C2 channel in a live criminal campaign, and that this investigation documents one confirmed instance.

The operator calls himself Azazel, a Russian-speaking affiliate of the Gentlemen ransomware group. CloudSEK found him the way threat actors are usually found: he left an open directory on port 8000 of his own C2 box. What the directory held was the entire operation — more than two dozen victim directories across six countries spanning logistics, insurance, pharmaceuticals, AI, medical devices and government-adjacent infrastructure, roughly 6TB of stolen data on the staging server, and a 22TB long-term vault on a second machine. More than 50TB of raw storage across a three-node estate, all of it rented bare metal rather than cloud, and all of it enumerable by anyone who loaded the right URL.

What the MCP abuse actually was — and what it was not

The headline deserves precision, because the interesting detail is easy to inflate. This was not a prompt-injection attack, a poisoned tool description, or an exploited MCP software vulnerability. Azazel registered a reverse-shell handler as a callable tool inside an AI assistant harness over MCP, then drove his own attack execution through that interface.

The concrete artefact is a script CloudSEK names va.py, whose job was to verify that the ransom note had actually landed. It called an MCP service at 127.0.0.1:35367, authenticated with a fixed bearer token, and invoked exec_in_session to loop SSH-based verification checks across six internal hosts in the victim environment. The verification swept eight separate surfaces: /etc/motd, ransom notes in both the root and ubuntu home directories, the SSH banner via sshd_config, the PostgreSQL cluster_name parameter, the pgAdmin login template, the victim’s own GitLab repository README, and a GitLab issue opened directly against the victim’s project. A multi-surface defacement chain, orchestrated through an agent tool call.

Two further details separate this from a one-off improvisation. CloudSEK found mcp_test.py and recon_mcp.py sitting alongside va.py — iterated tooling, developed over time, not a trick discovered once and reused. And the beacon logs carry the scanner fingerprint internet-census-mcp-scanner: dedicated infrastructure sweeping the internet for exposed MCP ports, treating reachable agent tool servers as a general-purpose initial access vector entirely independent of the credential chain that produced most of his victims. CloudSEK also names the MCP client identity hermes as a confirmed malicious indicator for this operator.

There is a smaller, bleaker observation in the report that deserves repeating: output recovered from Azazel’s own storage server is consistent with an AI assistant answering his infrastructure-planning questions — backup capacity, disk throughput, scan performance against large datasets. He used the model to run the business and to run the attacks.

The boring half is what produced the victims

It is worth resisting the pull of the AI angle, because every confirmed victim was reached through something far more pedestrian: stolen CI/CD secrets. Azazel’s setup script installed a toolkit built for exactly one surface — glato, nord-stream, gitlab-secrets, gitlab-watchman and gitleaks — and pointed it at GitLab CI/CD variable stores and git repository history.

The yield per token is the number to take to your own pipeline review. One compromised GitLab instance hosted pipelines for two unrelated organisations; a single CI/CD token surrendered Oracle and PostgreSQL credentials, shipping API credentials, and SSH private keys for three separate cloud hosts belonging to the second company. A SaaS platform breach reached more than 150 databases, payment gateways, and hundreds of repositories across the provider and more than a dozen of its own clients — again from one token. And at a platform hosting a government-linked financial registry, Azazel exfiltrated more than 120,000 records, then ran a script that killed the live PostgreSQL process and deleted the production data directory. Destructive extortion, after the data was already gone.

The single deepest compromise — an AI platform, more than 6TB and still actively transferring while CloudSEK watched — began with a weakness this site has covered in a dozen other forms: an AI medical-imaging API that fetched user-supplied URLs server-side without validation. An unauthenticated SSRF proxy into the internal network, which is precisely the bug class behind the five-vendor MCP SSRF cluster we covered earlier today. From there: Jasypt master key recovered and every encrypted config value bulk-decrypted in one pass; a hardcoded auth-bypass JWT recovered from git history after being removed from the current branch; Grafana admin hashes pulled out of exfiltrated object storage and cracked offline; and a sweep of all 6.1TB for kubeconfigs, SSH keys and credential-bearing container files.

Why the MCP detail still matters more than it looks

A sceptic’s reading is fair: Azazel already had code execution, so running his commands through an MCP tool call instead of a plain reverse shell changed nothing about his access. True. What it changes is what the activity looks like to defenders, and that is not a small thing.

Traffic to 127.0.0.1:35367 is not traffic. It never crosses a network boundary, never hits a firewall rule, and never produces an egress alert. The parent process is a sanctioned developer tool, not a shell spawned from a web server. Most organisations have no inventory of which MCP servers are running on which hosts, no log of which client identities called which tools, and no alerting on exec_in_session at all — because until this week the entire category existed in the threat model as a theoretical lateral-movement note rather than an observed TTP.

That is the gap this report closes. The agent tool interface is now a demonstrated execution surface in a real ransomware intrusion, and the scanner fingerprint shows someone is already looking for the next one at internet scale. We have tracked the governance side of this all year — 15,465 indexed MCP servers with no marketplace vetting, and the hijacked coding-assistant session that carried Shai-Hulud into 100 internal repositories. This is the same convergence from the other direction: not an agent tricked into attacking its owner, but an attacker who simply found the agent’s tool server a convenient place to work from.

What to do

  • Inventory your MCP servers and their bind addresses. CloudSEK’s first mitigation is blunt: never bind an MCP server beyond strict loopback. That is necessary and not sufficient — loopback is exactly where this one was.
  • Treat exec_in_session and every execution-capable tool as a privileged operation with an audit trail. If you cannot produce a log of who invoked a shell tool on a developer workstation last week, you cannot detect this.
  • Alert on MCP initialize RPCs from client identities outside an approved allowlist. The identity hermes and the scanner fingerprint internet-census-mcp-scanner are confirmed indicators for this operator specifically; the general control is allowlisting clients, not blocklisting names.
  • Rotate CI/CD secrets through history, not just the current variable store. Every confirmed victim here was reached via GitLab CI/CD variables and commits that looked removed. Pipeline variables are not a secrets manager.
  • Stop treating Jasypt ENC() values and embedded secrets in values.yaml or compose files as a boundary. One recovered master key decrypted the entire configuration set in a single pass.
  • Validate server-side URL fetching in AI inference endpoints. The deepest compromise in this report started at an unvalidated URL fetch in a medical imaging API — the same primitive, again.

Verification note: the operator profile, infrastructure addresses, victim scope, attack chains, the va.py / 127.0.0.1:35367 / exec_in_session detail, the eight verification surfaces, the scanner and client fingerprints, and the mitigations all come from CloudSEK’s report of 5 October 2026, which we read directly. CloudSEK’s “no prior public reporting” claim is reported here as the firm’s own characterisation, not as independently established priority; we have not located contradicting earlier reporting, and secondary coverage from Infosecurity Magazine and IT Pro describes it the same way. CloudSEK states victims were notified ahead of publication and we have not named any of them. We did not contact CloudSEK, the Gentlemen group, or any victim organisation before publication.

Sources: