TeamPCP’s LiteLLM Supply-Chain Attack Targets Credentials and Kubernetes Clusters

· Original article ↗

Summary

A technical investigation details how trojanized LiteLLM packages 1.82.7 and 1.82.8 steal credentials, can compromise Kubernetes clusters, and use AdaptixC2 and Havoc infrastructure. Researchers counted 33,688 internet-facing deployments, not all confirmed compromised.

Key points

  • TeamPCP published trojanized LiteLLM versions 1.82.7 and 1.82.8 to PyPI on March 24; both versions were later removed.
  • The malware harvests credentials from files and environment variables, including cloud, SSH, Kubernetes, database, CI/CD, and API secrets; it can also query AWS IMDS for IAM role credentials.
  • In Kubernetes environments, stolen service-account tokens let the malware dump secrets across namespaces and deploy privileged pods across cluster nodes.
  • A persistent systemd service polls checkmarx[.]zone for payloads; the investigation linked the operation to AdaptixC2 at 83.142.209[.]11 and Havoc at 45.148.10[.]212.
  • Encrypted stolen data is sent to models.litellm[.]cloud; researchers identified 33,688 internet-facing LiteLLM deployments, though not all were confirmed to have installed the compromised versions.
  • The investigation recommends checking for the listed persistence files, Kubernetes pods, and network indicators; if compromised, rotate credentials accessible to the affected host and review package controls and cloud permissions.

Article Details

Attack Vectors
  • Two trojanized Python package releases, versions 1.82.7 and 1.82.8, executed an obfuscated payload during installation. Both releases were subsequently removed from the package registry.
  • An injected Python statement launched a base64-encoded payload in a detached subprocess, allowing installation to finish while malicious execution continued.
  • The payload collected sensitive files, environment variables, shell histories, private keys, cloud credentials, database connections, wallet configurations, and CI/CD secrets.
  • The malware retrieved instance role credentials through IMDSv2 and used authenticated cloud API requests to enumerate secret stores.
  • Stolen service account tokens enabled cluster-wide secret collection and deployment of privileged pods on every node. Host filesystem mounts and chroot allowed the backdoor to be installed on the underlying hosts.
  • A persistent user service polled an attacker endpoint approximately every 50 minutes, downloaded replacement binaries, and launched them as detached processes.
  • Collected information was encrypted, bundled, and uploaded using an HTTPS POST disguised as an AI model API request.
  • The researchers counted 33,688 internet-facing deployments, but explicitly cautioned that public exposure did not establish that every deployment installed a compromised release.
Defensive Notes
  • Check for ~/.config/sysmon/sysmon.py and ~/.config/systemd/user/sysmon.service as persistence artifacts.
  • Check for /tmp/pglog, /tmp/.pg_state, and /tmp/tpcp.tar.gz as downloaded-agent, loader-state, and encrypted-exfiltration artifacts.
  • Audit the kube-system namespace for privileged pods matching node-setup-*. The article advises treating every cluster node as compromised if these pods are found.
  • Review network logs against the reported exfiltration, polling, and C2 indicators.
  • If compromise artifacts are present, or either trojanized release was installed, rotate all credentials accessible to the host, including private keys, cloud tokens, database passwords, service account credentials, and API keys.
  • Pin package versions and verify package hashes rather than automatically installing the latest release.
  • Restrict outbound connectivity from build environments and CI/CD runners.
  • Apply least privilege to instance roles and cluster service accounts.
  • Require IMDSv2 with a hop limit of 1 on EC2 instances.

Indicators of compromise

TypeIndicatorContext
DOMAINcheckmarx[.]zoneTeamPCP polling domain used by the persistent loader to obtain payload download URLs.
DOMAINmodels[.]litellm[.]cloudAttacker exfiltration domain receiving encrypted credentials and other collected data.
IPV445[.]148[.]10[.]212Havoc C2 TeamServer used by the attack's Demon agent.
IPV446[.]151[.]182[.]203Server linked by certificate to the exfiltration domain; researchers assess it as an exfiltration node or possible backup infrastructure.
IPV483[.]142[.]209[.]11AdaptixC2 TeamServer identified by Hunt.io and used by agents in the attack.
SHA25671e35aef03099cd1f2d6446734273025a163597de93912df321ef118bf135238File hash explicitly listed in the investigation's IOC table; the associated file is not identified.
SHA25695a13f33699558f2bbe3afb631900076f84dd6de60c656a1d0ada2b9bae9c4c8Redacted HTTP response-header fingerprint used to link the primary C2 server with additional suspected infrastructure; not a malware file hash.
URLhxxps[:]//models[.]litellm[.]cloud/HTTPS POST destination for the encrypted exfiltration bundle.

MITRE ATT&CK

T1005 · Data from Local SystemThe collector read sensitive local files and gathered their contents for exfiltration.T1016 · System Network Configuration DiscoveryThe malware ran ip addr and ip route to collect interface and routing information.T1027 · Obfuscated Files or InformationThe initial malicious statement concealed its first-stage payload using base64 encoding.T1033 · System Owner/User DiscoveryThe malware ran whoami to identify the account under which it was executing.T1036.005 · Match Legitimate Resource Name or LocationThe service description 'System Telemetry Service' and node-setup pod names were chosen to resemble legitimate infrastructure.T1048 · Exfiltration Over Alternative ProtocolThe encrypted bundle was uploaded by curl POST to a dedicated HTTPS exfiltration endpoint separate from the loader's polling domain.T1059.006 · PythonInjected Python code executed the credential collector and persistent sysmon.py loader.T1071.001 · Web ProtocolsThe loader used an HTTP polling resource, while the AdaptixC2 agent communicated over HTTPS on port 443.T1078.004 · Cloud AccountsAWS credentials found in environment variables enabled authenticated cloud API abuse using the malware's custom request-signing implementation.T1082 · System Information DiscoveryThe malware ran hostname and uname -a to fingerprint the compromised host.T1083 · File and Directory DiscoveryThe walk() helper recursively searched directories for sensitive files matching selected names or extensions.T1105 · Ingress Tool TransferThe persistent loader retrieved payload URLs, downloaded new binaries to /tmp/pglog, and launched them.T1140 · Deobfuscate/Decode Files or InformationThe encoded first-stage payload was unpacked into a Python wrapper that continued execution.T1195.001 · Compromise Software Dependencies and Development ToolsTeamPCP published trojanized LiteLLM dependency releases 1.82.7 and 1.82.8 to PyPI.T1543.002 · Systemd ServiceThe malware created and enabled sysmon.service as a persistent systemd user service with automatic restart.T1550.001 · Application Access TokenA stolen Kubernetes service account token authenticated the malware's direct requests to the cluster API.T1552.001 · Credentials In FilesThe collector read cloud configuration files, environment files, database connection files, registry authentication files, and CI/CD secrets.T1552.003 · Shell HistoryThe collector harvested shell command histories that could contain credentials or connection strings.T1552.004 · Private KeysThe collector stole SSH private keys, SSH host keys, and TLS private keys.T1552.005 · Cloud Instance Metadata APIThe malware requested an IMDSv2 session token and retrieved temporary credentials for the instance's IAM role.T1552.007 · Container APIUsing a service account token, the malware queried the Kubernetes API and dumped secrets across all namespaces.T1560.001 · Archive via UtilityCollected data was packaged into a tar bundle before exfiltration.T1560.003 · Archive via Custom MethodThe malware encrypted collected data with AES-256-CBC and wrapped the session key with an embedded RSA-4096 public key.T1610 · Deploy ContainerThe malware deployed privileged node-setup-{hostname} pods to every cluster node, including control plane nodes.T1611 · Escape to HostPrivileged pods mounted the host root filesystem and used chroot to install the backdoor on the underlying host.T1613 · Container and Resource DiscoveryThe Kubernetes module enumerated cluster nodes before deploying malicious pods to them.

Threat Actors

Vendors

Products

Tools

Countries

Related Articles