我们的 AI 引擎 Neutron 在加州大学伯克利分校的 CyberGym 基准测试中取得了 97.1% 的成绩。 了解更多

深度解析

深度解析

Load/Mine: 恶意 Hugging Face 模型后门化 GPU 主机

恶意 Hugging Face 模型仓库在加载它们的 GPU 主机上运行挖矿程序和后门;该活动在每次下架后都会卷土重来。

摘要

  • Pluto Research 追踪的一项活动在 7 个 Hugging Face 账户的 31 个模型仓库中植入了挖矿和后门载荷,伪装成小型 Qwen2 测试模型。启用自定义代码加载其中一个模型,会在读取任何权重之前运行发布者的 Python。Pluto 于 2026 年 10 月 29 日发布了分析。
  • 该活动及其关联模型累计记录 32,376 次下载,其中 29,818 次来自 31 个恶意仓库。受害者真实存在且持续出现:运营者的钱包在链上已收到约 2,276 PRL(Pearl,约 5,000 美元),截取时仍有活跃的挖矿 worker 在上报。
  • 目标是自托管 GPU 基础设施:Xinference 和 GPUStack 部署、租用的 GPU 机器、共享研究笔记本,以及拉取小型测试模型的 CI 任务。第二波在下架后数天内回归,其中一个仓库携带容器到宿主机的逃逸脚本。
  • 没有分配 CVE,截至 2026 年 11 月 3 日该事件不在 CISA 的已知被利用漏洞目录中。在启用 trust_remote_code 之前,审查 auto_map 条目引用的每个 .py 文件,并检查加载过任何列出模型的主机。「如果已安装该怎么办?」包含封控步骤。

我受影响吗?

以下条件全部成立时,您受到影响:

  • 您基础设施上有人通过 trust_remote_code=True 或交互式确认启用自定义代码,加载了该活动某个仓库中的模型。仓库名和账户名列在「如何检查是否已被入侵?」中。
  • 您的环境属于被瞄准的类别:自托管推理主机(尤其是 Xinference 或 GPUStack)、租用的 GPU 机器、共享研究笔记本,或未经审查就拉取小型测试模型的 CI 任务。
  • 载荷在导入时、任何权重被读取之前执行,因此模型加载失败也会执行它。旗舰仓库的全部权重文件就是一个不含张量的 42 字节 model.safetensors。

第一波的账户在 Pluto 报告后被移除。第二波在数天内以新账户出现,且在报告八天后仍在线,因此下架不是暴露结束的证据。

组 仓库数 记录的下载量 2026 年 10 月 28 日状态
第一波,hhzz667 和 dsxk4mr8tq 账户 12 728 已移除
第二波,含 MENXIANGYU 和 wjsbg 的五个账户 19 29,090 在线
关联模型,六个账户 13 2,558 在线

检查您的缓存和主机:

# Any of the campaign's models in the local Transformers cache
ls ~/.cache/huggingface/hub 2>/dev/null |
  grep -iE "MENXIANGYU|wjsbg|htt0118|soumikmahato|r1r13|hhzz667|dsxk4mr8tq|MONIADF-2|antwoinhjro654|vaishupv|andrew3d|oifewuheu|KzuryHD"

# Watchdog and miner artifacts on the host
ls -la /tmp/.cch 2>/dev/null

# A kernel-worker name that carries userspace arguments is the miner
ps aux | grep -F '[kworker/u20:1]'

# Persistence hooks written by the payload
grep -n "svc.py" ~/.bashrc ~/.profile /root/.bashrc 2>/dev/null

真实的内核工作线程不显示任何命令行参数;伪装的挖矿程序把挖矿登录信息当作参数携带,这正是 Pluto 描述的识别特征。

我如何修复?

没有任何包更新能修复这个问题,因为投递是一个被按设计使用的已记录功能。修复是对每个带 auto_map 条目的模型的审查纪律。

  1. 清点您的流水线用 trust_remote_code=True 加载的每个模型,在下一次加载前通读其 config.json 的 auto_map 引用的每个 Python 文件。如 Pluto 所指出,这一审查本可抓住该活动中的每个载荷。
  2. 优先选择权重以 safetensors 提供、没有 auto_map 条目的模型,并在任务和笔记本中按提交哈希固定模型修订。
  3. 在 Xinference 和 GPUStack 主机上,把模型注册表和 API 限制到可信网络。载荷写入 Xinference 注册表,一个阶段瞄准 GPUStack 的宿主机目录,因此暴露的面板属于范围内。
  4. 在出口封锁并监控「如何检查是否已被入侵?」中的指标,包括反向 shell 接收端和矿池。

Hugging Face 的指引已经把工作放在用户身上:启用开关之前验证代码。复制 trust_remote_code=True 的模型卡片和教程把一个知情的选项变成一个勾选框,这正是该活动所指望的。

恶意代码做了什么?

载荷是放在一个微型权重文件旁边的普通 Python,并在导入时执行。一个看门狗进程、一个绕过代理的下载器、一个伪装成内核工作线程的内存挖矿程序,以及反向 shell,都在模型类被构造之前组装完成。

Transformers 通过导入仓库 config.json 中 auto_map 条目命名的文件来加载自定义模型实现:

# transformers/src/transformers/dynamic_module_utils.py (get_class_in_module)
module_spec = importlib.util.spec_from_file_location(name, location=module_file)
module = importlib.util.module_from_spec(module_spec)
sys.modules[name] = module
module_spec.loader.exec_module(module)
return getattr(module, class_name)

exec_module 执行文件的顶层语句来定义其类,因此放在这些定义旁边的调用会在 getattr 返回之前运行。下载量 28,412 次的旗舰仓库 MENXIANGYU/qwen2-tiny 把 auto_map 指向一个入口点立即触发的模块:

# modeling_evil2.py - shortened module-level entry point, published by Pluto
try:
    _boot()
except Exception:
    try:
        _run()
    except Exception:
        pass
class EvilModel:
    ...

从那里开始,该构建组装其链条:

  • _boot 写入 /tmp/.cch/svc.py,一个作为独立进程运行的看门狗,每 120 秒重启缺失的挖矿程序。追加到 /root/.bashrc、/root/.profile 和用户 ~/.bashrc 的行在每次登录时再次启动它。
  • 三个构建加入了连接到 212.32.253.3:443 或 :9443 并在每次断开后重试的反向 shell,给运营者一个带被入侵进程文件和凭据的交互 shell。
  • 挖矿二进制 syscore.bin 来自模型仓库或镜像,下载时禁用了主机配置的代理。它是一个 40.6 MB 的 UPX 打包可执行文件,打包标记从 UPX! 改成了 PEK!,常规解包工具因此拒绝它。
  • 首次启动尝试把二进制复制到内存中的文件描述符并从那里执行:
# modeling_evil2.py - excerpt of the attempted memory-backed launch
fd = os.memfd_create("kworker")
with open(body, "rb") as f:
    os.write(fd, f.read())
os.fchmod(fd, 0o755)
if os.fork() == 0:
    os.setsid()
    os.fexecve(fd, [_TAG] + _margs(), os.environ)
  • memfd_create 在内存中创建匿名文件。引用的 os.fexecve 并非 CPython 的标准 API;Python 通过 os.execve 提供文件描述符执行。应把该片段视为一次启动尝试,而非已验证的执行轨迹。Pluto 还报告 /tmp/.cch/sync 中有供看门狗重启使用的备用二进制文件,因此即使内存启动成功,磁盘上也可能留下证据。进程名 [kworker/u20:1] 是伪装,并不能证明磁盘上没有痕迹。
  • 进度报告以伪装的模型名写入本地 Xinference 注册表,qwen2-tiny- 加 base32 编码的状态,拥有 API 访问权的运营者能读取每次感染。自己的挖矿程序跑起来后,载荷移除竞争的模型注册并杀死匹配的进程。

第二波中较晚出现的仓库 MENXIANGYU/qa-whl-1021 是一个容器到宿主机的逃逸脚本。它从特权容器内激活 LVM 卷、挂载候选宿主机磁盘,找到宿主机根目录或 GPUStack 的 /var/lib/gpustack。然后给攻击者宿主机上的 root 登录。

入侵是如何发生的?

这里没有漏洞意义上的利用:受害者授予权限,发布者的代码随之运行。

  1. 运营者发布一个看起来像小型 Qwen2 测试检查点的仓库。其 README 抄自官方 Qwen2.5-0.5B 的模型卡,其 config.json 在 auto_map 中命名恶意模块。
  2. 受害者用 trust_remote_code=True 加载模型。Transformers 把引用的文件下载到模块缓存并导入它。
  3. 导入在模型类被构造之前执行模块的顶层代码 _boot。没有读取任何权重,恶意权重也不存在。
  4. 「恶意代码做了什么?」中的链条以加载进程的权限运行,GPU 开始向运营者的钱包挖矿。

正如 Pluto 指出,同样的权限在别处也出过问题。CVE-2026-22807 使 vLLM 不检查 trust_remote_code 设置就加载 auto_map 模块,在 vLLM 0.14.0 修复;Unsloth Studio 曾硬编码该开关来检查模型配置,在 2026.6.9 修复。

攻击如何流动?

一次启用自定义代码的加载调用,把发布者的顶层 Python 交给了进程权限,链条在任何权重被读取之前运行。

flowchart LR A["受害者用 trust_remote_code=True
调用 from_pretrained"] --> B["config.json 的 auto_map
命名 modeling_evil2.py:
导入是已记录行为"] B --> C["exec_module 在导入时
运行 _boot:代码先于
类执行"] C --> D["看门狗 /tmp/.cch/svc.py
加 .bashrc 钩子,
每 120 秒重启挖矿"] D --> E["syscore.bin 绕过代理下载,
以改动的 UPX 标记
打包"] E --> F["尝试从内存启动;
备用二进制文件仍留在磁盘上"] F --> G["矿池、反向 shell,
状态隐藏在 Xinference
注册表中"]

攻击者能做什么?

已演示的影响是以加载模型的用户身份执行代码,伴随今天仍在运行的三种结果。

  • 在受害者 GPU 上挖加密货币,链上有已实现收益:第一波钱包在 716 笔交易中收到约 2,276 PRL 并已转出约 2,241 PRL,截取时其活跃 worker 有约 1,008 PRL 的 30 天奖励。
  • 比挖矿更长久的后门访问:反向 shell 在每次断开后重连,一个较晚的投放器只响应白名单 IP,向其他来源返回 403 和文本 static ip.,因此获取同一 URL 的分析者可能看不到载荷。
  • GPU 基础设施内的横向触达:容器逃逸脚本瞄准特权容器下的宿主机,一个第二波家族收集 LLaMA-Factory 部署的 GPU 平台信息和腾讯云元数据。

Pluto 观察到一个由九个 worker 组成的活跃群体在 90 秒内相继加入。它们的名称如 dhumphreys-notebook-2 和 a10040gb,更像共享笔记本集群而非矿场。它们的份额提交在大约六分钟后停止,与管理员杀掉任务相符。运营者还会移除竞争的挖矿程序和模型来保住算力。

条件是权限和外泄端点的可达性。加载进程的文件与凭据访问范围就是影响范围。

如果已安装该怎么办?

先封控、保留证据,再清理。载荷在模型初始化之前运行,其后门可以在挖矿停止后留存。

  1. 把受影响主机与生产网络隔离,把出站流量限制到工作负载所需。
  2. 在删除任何内容之前,捕获进程详情、网络连接、日志、模型缓存、启动文件改动和任何 authorized_keys 条目。
  3. 移除每条回返路径:/tmp/.cch/ 目录及其 svc.py 看门狗、载荷追加到 shell 启动文件的行、您没有添加过的任何 SSH 密钥,以及意外的 Xinference 模型注册。
  4. 轮换加载进程可能触及的每个凭据,包括云厂商密钥、注册表令牌和存储在环境中的 AI 平台令牌。
  5. 检查加载过相同仓库的其他机器。对 GPU 主机和特权容器,优先重建而非清理:逃逸仓库以宿主机 root 为目标,而内存启动几乎不留可检查之物。

如何检查是否已被入侵?

Pluto 公布了指标;仓库状态和下载计数截至 2026 年 10 月 28 日,网络基础设施最后观察到 10 月 21 日。命中是需要调查的线索,缺任何一个指标也不能排除入侵。

在缓存和注册表中查找的仓库:

  • 第一波,已移除:hhzz667 和 dsxk4mr8tq 发布了 qwen2-shell、qwen2-tiny、qwen2-mini、qwen2-nano、qwen2-legacy、qwen2-final 和 qwen2-tiny-gpt2。
  • 第二波,在线:包括 qwen2-tiny 和 zz_ext 的 MENXIANGYU、包括 qwen2-final 的 wjsbg、soumikmahato 的 qwen2-tiny-chat、r1r13 的 qwen-lora-text-v1、htt0118 的 qwen2-tiny。
  • 关联账户:MONIADF-2、antwoinhjro654、vaishupv、andrew3d、oifewuheu、KzuryHD。

主机痕迹:

  • /tmp/.cch/ 和 svc.py 进程,以及一个名为 [kworker/u20:1]、携带 krxXJ2PKQW.worker 登录等挖矿参数的进程。
  • /root/.bashrc、/root/.profile 和 ~/.bashrc 中调用 svc.py 的行;authorized_keys 中不是您添加的 ed25519 密钥;自测标记 /tmp/.qa_pwned。
  • 以 qwen2-tiny- 或 ezv- 开头的 Xinference 注册,它们用 base32 编码状态。

需要封锁和追踪的网络指标:

  • 212.32.253.3 上 443、9443、8895 和 8898 端口的反向 shell 接收端和载荷托管,包括按来源 IP 门控的 :8898/lf_py.py;38.55.133.49 的 8901 和 9001 端口;第一波的阿里云 C2 8.137.187.63;103.97.176.121:3361;178.33.123.26 的 3361 和 3362 端口;以及 hz2006.aihzcc.top。
  • 矿池:stratum+ssl://prl-us.kryptex.network:8048 和 prl-sg.kryptex.network:8048;pearl-hk.luckypool.io 的 3361 和 3956 端口;pool.hashvault.pro 的 80 和 443 端口;gulf.moneroocean.stream:10001;mine.c3pool.com:80。
  • 第一波收款钱包 prl1p9s2a9gdy4n5yfuf5suhya2d2pyvaahmz3n3gzm3npyxkj79m7yyq9kgnrv 和第二钱包 prl1pek8rh8yjck5q7596aph7ua7xnkqs8ur9mkfmz8w7xfzcdfcfx5vsx2f4lz。

时间线

  • 2026-04-29:hhzz667 账户创建,休眠五个月。
  • 2026-09-21:第一个载荷 qwen2-shell,一个 37 行、带 ed25519 密钥和信标的 SSH 后门发布。
  • 2026-09-21 至 2026-09-22:跨六条路径的密钥注入构建出现,随后是第一个完整无文件挖矿程序 qwen2-final。
  • 2026-10-12:dsxk4mr8tq 账户在 2.5 小时内发布六个仓库,Pluto 的扫描器标记 modeling_evil.py。
  • 2026-10-20:Pluto 向 Hugging Face 和 ModelScope 报告第一波,两个平台移除账户。披露后的数小时内 qwen2-tiny 的下载从 7,354 增至 9,584,容器逃逸仓库在披露邮件 8.5 小时后出现。
  • 2026-10-25:htt0118 账户出现,携带早期载荷的近乎相同副本、相同矿池登录和反向 shell 接收端。
  • 2026-10-28:Pluto 记录指标快照:qwen2-tiny 下载 28,412 次,第二波仓库仍在线。
  • 2026-10-29:Pluto 发布研究。

第一波下架后,旗舰仓库的下载持续攀升:披露时 7,354,八天后 28,412
图 1:MENXIANGYU/qwen2-tiny 的下载从 2026 年 10 月 20 日披露时的 7,354 增至 10 月 25 日的 18,012、27 日的 25,854 和 28 日的 28,412,同期第二波保持在线。来源:Pluto Research,2026 年 11 月 3 日核对。

记录的下载几乎全部落在在线的第二波:总计 32,376 中的 29,090,关联模型另行计数
图 2:按组统计的记录下载,截至 2026 年 10 月 28 日:已移除的第一波 728、在线的第二波 29,090、关联模型 2,558。来源:Pluto Research,2026 年 11 月 3 日核对。

常见问题

trust_remote_code=True 是 Transformers 的漏洞吗?

不是。它是需要自定义实现的模型的已记录行为,Transformers 的安全策略要求使用此参数时始终验证建模文件的内容。事故出在绕过选择的加载器:0.14.0 之前的 vLLM 不检查设置就导入 auto_map 模块,Unsloth Studio 曾把它硬编码。

平台的扫描器为什么没抓到这些载荷?

每个小于 2 GB 的文件在每次提交时都经过 ClamAV,合作扫描器针对 pickle 和模型利用检查权重格式。auto_map 引用的普通 Python 文件既不是已知恶意软件签名,也不是序列化模型。旗舰载荷扫描为干净,一个扫描器报告它不是机器学习模型。

恶意仓库还在线吗?

第一波已被移除。第二波(五个账户上的 19 个仓库)在 Pluto 报告八天后仍在线,且该活动在数天内替换了被移除的第一波:下架并没有终结活动。一个关联家族的账户也在披露后发布了新仓库。

运营者赚了多少?

约 2,276 PRL(约 5,000 美元)通过 716 笔交易在链上到达第一波钱包,约 2,241 PRL 已转出。其 Kryptex worker 在截取时显示约 1,008 PRL 的 30 天奖励。一个关联家族的 MoneroOcean 钱包一个月赚了约 26 美元,其活动比金额更重要。

谁在运营该活动?

Pluto 评估为一个讲中文、以金钱为动机的运营者或小团体。证据:简体中文代码注释、阿里云 C2、ModelScope 和 hf-mirror.com 上的镜像、默认 Xinference 和腾讯云的瞄准,以及相当于中国深夜的活动时段。印尼语的 parasit 工具包可能是同一生态位中的第二个运营者。

safetensors 权重能防住这类攻击吗?

不能。旗舰仓库的 safetensors 文件是 42 字节、不含张量,因为不需要恶意权重:载荷就是旁边的 Python。权重格式不会审查代码,这正是 auto_map 引用需要读者的原因。

用 Ostorlab 发现暴露的 AI 推理面板

Ostorlab 的攻击面发现会清点您网段中暴露在互联网上的主机,找出该活动瞄准的每个暴露的 Xinference 或 GPUStack 面板。开始使用 Ostorlab 扫描,了解哪些推理主机需要最先施加网络限制。

参考文献

  • Pluto Security,《Load/Mine: A Hugging Face Malware Campaign Returns After Takedown》,2026 年 10 月 29 日由 Shaked Chen、Eitan Chassid 和 Yotam Perkal 发布,包含载荷分析、账户追踪和完整指标清单:https://pluto.security/blog/hugging-face-malware-campaign-load-mine (2026 年 11 月 3 日核对)
  • Transformers 源码 dynamic_module_utils.py,该活动滥用的 get_class_in_module 导入路径:https://github.com/huggingface/transformers/blob/main/src/transformers/dynamic_module_utils.py (2026 年 11 月 3 日核对)
  • Transformers 安全策略,「please always verify the content of the modeling files when using this argument」以及固定修订的建议:https://github.com/huggingface/transformers/blob/main/SECURITY.md (2026 年 11 月 3 日核对)
  • Hugging Face Hub 安全文档,恶意软件与 pickle 扫描功能及其局限:https://huggingface.co/docs/hub/security (2026 年 11 月 3 日核对)
  • Xinference README,用于注册表检查的标准部署端口:https://github.com/xorbitsai/inference (2026 年 11 月 3 日核对)
  • CISA 已知被利用漏洞目录 JSON 数据源,确认截至 2026 年 11 月 3 日该活动没有 CVE 条目:https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json (2026 年 11 月 3 日核对)
  • Python os 文档,os.execve 的文件描述符支持:https://docs.python.org/3/library/os.html#os.execve (2026 年 11 月 3 日核对)