At a Glance
| Malware Family | Hugging Face malware campaign (peakminer cryptominer, /tmp/.cch/svc.py watchdog, reconnecting reverse shells, and container escape tools) |
| Threat Actor | Unattributed; suspected financially motivated Chinese-speaking operator or group |
| Target / Victims | Self-hosted AI infrastructure (Xinference and GPUStack), shared GPU notebooks, research clusters (over 32,000 downloads across 31 campaign and 13 linked repositories) |
| Delivery Vector | Trojanized model repositories on Hugging Face and ModelScope abusing trust_remote_code=True |
| Key Capabilities | Import-time execution, memory-backed launch via memfd_create, kernel worker disguise, reverse shell access, container escape, rival miner termination |
TL;DR
Pluto Research tracked an active Hugging Face malware campaign that abuses open-weight model repositories to hijack GPU servers. By exploiting the trust_remote_code parameter in Python Transformers, the repositories execute attacker code before model weights load. Furthermore, this Hugging Face malware campaign installs stealth cryptominers, reconnecting reverse shells, and container escape scripts across target environments.
Delivery and Attribution
Between September and October 2026, researchers tracked 31 malicious model repositories across seven accounts on Hugging Face and ModelScope. Together with 13 linked models, the uploads accumulated more than 32,000 downloads. As Pluto Research stated, “The campaign and linked models collectively recorded more than 32,000 downloads. That figure measures downloads, not confirmed infections or unique victims.”
The operation unfolded across two distinct waves. The first wave spanned 12 repositories under accounts like hhzz667. After researchers reported the threat, Hugging Face and ModelScope removed the accounts. However, a second wave appeared within days across five new accounts, including MENXIANGYU. A single repository, MENXIANGYU/qwen2-tiny, collected 28,412 downloads by late October.

Confirmed Versus Suspected Attribution
Confirmed technical evidence connects all 31 repositories through shared staging URLs, backup files, and mining credentials. Specifically, the attacker left behind backup files in one repository that exposed the production accounts. Meanwhile, suspected attribution points to a financially motivated Chinese-speaking operator or group. Code comments throughout the first wave appear in Simplified Chinese, such as notes to blend into directories and kill rival processes. In addition, command infrastructure runs on Alibaba Cloud, and file downloads point to ModelScope and hf-mirror.com. Activity also peaks between 18:38 and 21:19 UTC, matching late night hours in China Standard Time. A secondary account carried Indonesian comments, which suggests a collaborator or a split test.
Infection Chain
The attack targets self-hosted inference platforms like Xinference and GPUStack, alongside shared notebooks and continuous integration pipelines. To lure victims, the attacker uploaded packages that mimic small Qwen2 checkpoints. However, the safetensors file contains no valid weights and measures only 42 bytes. Instead, the configuration file uses auto_map to point directly to a custom Python script.
When an engineer loads the model using trust_remote_code=True, Transformers downloads and imports the Python file. During import, the interpreter executes the top-level code before defining the model class. As the report explains, “No malicious weights are needed.” The attacker simply uses the permission granted by the remote code flag.
Memory Execution and Evasion
First, the script drops a watchdog process at /tmp/.cch/svc.py and injects startup commands into .bashrc and .profile. The watchdog checks the system every 120 seconds to restart the miner if terminated. In three builds, the code also launches a background process that connects an interactive reverse shell to an external IP address.
Second, the loader fetches a packed binary named syscore.bin. It disables Python proxy handlers during download to bypass local proxy logging. Next, the loader writes the binary into an anonymous memory file using memfd_create and executes it via fexecve. As a result, the process runs directly from memory without an executable path on disk. To deceive administrators, the process masquerades under the kernel worker name [kworker/u20:1].
The binary itself is packed with UPX, but the operator altered the packing headers from UPX! to PEK!. This change causes standard unpacking utilities to fail while allowing the embedded stub to execute. Researchers unpacked the binary to reveal peakminer, an optimized mining client.
Command-and-Control and Exfiltration Behaviour
The primary goal of the Hugging Face malware campaign is generating cryptocurrency revenue. The payload connects to Kryptex pools using a shared account to mine Pearl (PRL). Public blockchain records show the operator wallet received approximately 2,276 PRL across 716 transactions, valued at roughly $5,000. During analysis, nine worker nodes joined the pool simultaneously within 90 seconds. Their naming patterns matched a shared GPU cluster with multiple A100 instances.
Cryptomining and Container Escapes
To monitor victims, the payload records progress by writing fake model names into the local Xinference registry. The names contain base32-encoded status tags reporting startup, binary acquisition, and mining health. Furthermore, the malware scans running processes and terminates 13 competing miner families to maximize available GPU resources.
The campaign also expanded its post-compromise reach. A second-wave package included a container-to-host escape script named qa-whl-1021. When executed inside a privileged container, the script mounts underlying host storage drives and searches for GPUStack paths. This step grants the attacker root access to the physical host. A header comment in the code referenced internal reports and stated that “ammunition must be self-hosted.”
Defense and Detection Guidance
Standard security tools failed to flag this campaign. Platform antivirus scanners checked files against known signatures, while model scanners verified weight formats. Because the malicious code resided in plain Python, scanners marked the files clean. According to the Pluto Research report, organizations must treat model code like any unvetted software dependency.
Defenders should inspect GPU hosts for /tmp/.cch/ directories, unauthorized svc.py scripts, and [kworker/u20:1] processes carrying user arguments. Security teams must also audit .bashrc, .profile, and SSH authorized_keys files for unauthorized persistence lines. Furthermore, administrators should restrict outbound traffic from machine learning clusters and require strict authentication on Xinference APIs. Finally, developers must review custom modeling code manually before enabling trust_remote_code=True, pin safe repository revisions, and run inference workloads in isolated, unprivileged containers.
Support Our Threat Intelligence
Find our threat intelligence and malware analysis helpful? Support our work today and unlock a 100% ad-free reading experience!