Poisoned Pipeline

Poisoned Pipeline / Incidents / AS306

AS306 · 2026-10

Azazel harvested GitLab CI secrets and called a local MCP tool on a victim

GitLabGitLab CIGit / GitHubJenkinsMCPAI coding agentsLinux distro / packagesAWSKubernetes

CloudSEK published this on 5 October 2026. The operator calls
himself Azazel, a Russian-speaking affiliate of the Gentlemen
ransomware group who also ran an independent leak site, LEAKNED.
CloudSEK found the operation on an exposed file server. More than
two dozen organisations across six countries were on the loot
servers. This story maps the CI secret harvest and the MCP
execution channel. It does not map the ransom payments.

Chain A is how every victim outside one AI-company engagement was
reached. The setup script installed glato, nord-stream,
gitlab-secrets, gitlab-watchman, and gitleaks. The tooling table
names GitLab variable stores, Jenkins, and git history. From one
GitLab instance, Azazel pulled tokens, database credentials, API
keys, and SSH private keys. That instance hosted pipelines for two
unrelated organisations. One CI/CD token then opened Oracle and
PostgreSQL credentials, shipping API credentials, and SSH keys for
three cloud hosts of the second organisation. CloudSEK does not
say how the first GitLab was entered. No CVE is named.

A separate SaaS platform case used one CI/CD token to reach more
than 150 databases, payment gateways, and hundreds of source
repositories, including more than a dozen of that platform's
clients. Azazel named three of those clients on LEAKNED. CloudSEK
does not repeat the names. A second platform, hosting a
government-linked financial registry, lost more than 120,000
records across client environments. After the copy, a Python
script killed PostgreSQL and deleted the data directory. No
malicious package was published.

The ransom-note checker va.py called exec_in_session on
127.0.0.1:35367 with a fixed bearer token, looping SSH checks
across six internal hosts. CloudSEK says Azazel registered a
reverse shell handler as a tool inside an AI coding assistant via
MCP. mcp_test.py and recon_mcp.py sit next to va.py. The tooling
table records the MCP client name as hermes. The same table lists
internet-census-mcp-scanner, hunting exposed MCP ports. CloudSEK
does not tie a victim to a port that scanner found. The confirmed
calls are the attacker's script to a listener already bound on the
victim host. The post does not show a project-open hook.

Chain B is a different intrusion of one AI company, still
transferring when CloudSEK looked, more than 6TB. Initial access
was an unauthenticated AI medical-imaging API that fetched a
caller-supplied URL. A hardcoded JWT bypass remained in git
history after it was removed from the tree. Cluster configuration
values were encrypted with Jasypt; Azazel recovered the master key
and decrypted them. A sweep of the exfiltrated data collected
kubeconfig files and SSH keys. That chain is not the CI harvest.

Attacker staging used the hostname forgitlab.com. That host is the
operator's server, not a victim GitLab, and not the shared
instance in Chain A.

Mapped techniques

supply-chain GitLab CI variable stores and a shared instance

T0112 · Initial Access · Compromised token

One CI/CD token from a GitLab instance that hosted
pipelines for two organisations opened the second
organisation's database credentials, a shipping API, and
SSH keys for three cloud hosts. A separate SaaS platform
token reached that platform's clients. CloudSEK does not
say how either token was first obtained.

T0184 · Credential Access · Harvesting sensitive information from files

gitleaks was in the setup script. The tooling table names
git history as a credential source, and Chain B recovered
a removed JWT bypass from git log. GitLab variable stores
were harvested with glato, gitlab-secrets, and
gitlab-watchman. Those stores are not files. There is no
separate technique for a variable-store API.

T0199 · Impact · Secret leak

Extracted values include CI tokens, database credentials,
API keys, and SSH private keys. The SaaS case also took
JWT secrets and cleartext passwords from client databases.

T0186 · Impact · Source code leak

The SaaS CI token reached hundreds of source code
repositories across the platform and its clients. CloudSEK
does not publish those repositories.

T0201 · Impact · Customers compromised

One CI token reached more than a dozen client companies of
a SaaS platform, including databases and payment gateways.
A second platform's client environments lost records from
a government-linked financial registry. No poisoned package
or update was the vehicle. The supplier CI token was.

supply-chain MCP tool on the victim host

T0210 · Persistence · Poison AI coding-agent config or workspace

CloudSEK says a reverse shell handler was registered as a
tool inside an AI coding assistant via MCP. The confirmed
use is va.py calling exec_in_session at 127.0.0.1:35367.
mcp_test.py and recon_mcp.py are named beside it. The post
does not show a project-open hook or a write into .claude
or .vscode. The client string in the tooling table is
hermes.

Framework gaps noted

Sources