标签 Safetensors 下的文章

Intro 随着AI相关技术特别是大语言模型的逐步火热,衍生出一系列传统安全中不存在的一些攻击模式,例如Agent Security、MCP Security等等攻击范式,本文主要集中的是随着AI浪潮带来的MFV(Model Format Vulnerability),核心是对不可信的外部文件内容在非沙箱环境中进行执行,造成了代码执行漏洞的危害 What 首先我们来熟悉一下什么是MFV漏洞 为便于进行模型的share过程,我们通常会将训练后的机器学习模型、深度学习模型甚至大语言模型通过序列化的方式将其保存在一个特定的文件格式中,例如现在LLM常用的.safetensors.gguf的模型文件格式,又比如机器学习中常用的.h5模型格式文件,在第三方获取到分享的模型之后在模型的加载过程中对其中的键值对进行反序列化操作,同样的,也是因为反序列化这一操作,导致存在有安全漏洞的产生,可能导致任意代码执行等危险 当前针对MFV漏洞核心存在有两类漏洞类型: 1 Deserialization: 也即是反序列化的方式,因为在进行模型模型加载过程中对存储的对象进行反序列化操作还原对象的过程中,对于精心制作的模型,在反序列化的过程中将会执行对应的恶意代码 2 Backdoors:对于后门攻击其包含了多种中毒方式,包含有数据中毒等等攻击方式,其主要是在原始模型的基础上嵌入了一些隐藏的恶意功能 Deserialization Threats Archive Slip 在传统的Web漏洞中存在一类漏洞利用方式,也即是zip slip漏洞,其成因是由于在对zip压缩包进行解压缩的过程中,未对压缩包中包含的entry进行安全过滤,其存在有类似于..这类似跨目录的标识符作为entry导致能够进行一种另类的"任意文件上传"。 而在AI机器学习领域中同样存在有开放框架使用ZIP等压缩包格式的文件进行模型数据的存储,同样这些漏洞格式也会造成archive slip漏洞,具体的过程可描述为在进行模型加载的过程中,对模型进行反序列化的操作过程中,同样的如何遭遇了类似于../~$D:这类在不同的操作系统代表不同含义的特殊字符,可能会导致目录穿越等 例如NVIDIA的NeMo框架

其所对应的漏洞CVE-2022-22821则是由于这个原因导致的zip slip漏洞 https://github.com/NVIDIA-NeMo/NeMo/security/advisories/GHSA-rpx7-33j2-xx9x

Model Config Executable 在模型加载的过程中,对于模型的配置同样也是外部可控的一点,若采用了类似于Hydra这类存在有动态执行方法能力的框架进行配置文件的加载,若加载了一些其中注入有特定的恶意代码的模型文件,在进行模型加载的过程中,使用Hydra框架对配置进行解析,将会导致任意代码执行等漏洞 简单了解一下什么是Hydra https://github.com/facebookresearch/hydra Hydra是一个由Facebook团队开源的用于优雅配置复杂应用程序的Python框架,主要包括以下核心功能 1 分层配置系统 - 从多个源创建复杂配置 2 命令行覆盖 - 通过命令行轻松修改配置值 3 动态 Tab 补全 - 配置选项的命令行自动补全 4 远程执行 - 本地运行或远程启动应用程序 5 多任务执行 - 从单个命令使用不同配置运行多个作业 6 插件架构 - 通过插件扩展功能,支持优化、作业启动等 之后就是简单的使用Hydra

可以通过如上方式进行配置文件的加载,其核心是通过@hydra.main()这一个装饰器进行配置文件的初始化 而回到我们的AI模型相关场景,当攻击者向第三方平台,例如hunggingface或者ModelScope上传了一个包含有恶意代码的权重文件,攻击者采用了Safetensors采用YAML或者JSON的格式去存储模型元数据,受害者在下载了该模型准备使用类似于NeMo以及ml-flextok这类使用了Hydra框架进行模型元数据配置文件的加载以及解析时将会执行其中的恶意代码逻辑 我们可以将以上场景抽象为以下的代码: 1 创建一个yaml文件用于模拟携带有恶意代码的模型文件 2创建一个python代码利用hydra进行配置文件的加载以及对象的实例化进行代码执行

其也能够观察到系统命令的执行,导致了文件写入 分析其成因,进入到instantiate函数中,查看其实例化过程

根据配置文件的数据类型的不同进行不同的处理,这里命令执行我们构建的yaml文件是Dict数据类型 1 首先使用_prepare_input_dict_or_list将配置文件转化成一个Dict字典 2 在经过OmegaConf对字典进行处理后,核心使用instantiate_node去对节点进行实例化操作 3 其中对于_target_这一个特殊的key对应的value使用_resolve_target进行解析

4 该函数中传递的target值则为我们上面实例中配置文件中的_target_字段值,也即是os.system,其通过_locate进行待实例化的类和函数

5 其通过.进行划分,一步一步使用import_module进行模块的导入

6 在获取到了target对应的函数后,回到步骤3中展示的函数,调用_call_target函数结合传递的参数进行函数的执行 通过以上对于Hydra框架中对序列化的配置文件的对象进行反序列化的过程导致的恶意代码实例的分析,我们可以明白造成该类漏洞的原因是由于外部输入可控以及未对_target_进行安全校验直接进行函数定位 GGUF Model Template GGUF文件格式由llama.cpp团队创建,其通常用于保存模型的训练数据,该文件格式针对模型的快速加载和存储进行优化。 chat template在大语言模型中较为常见,通过系统提示词以及用户提示词提升LLM的回复效果屡见不鲜,同样的,在LLM中常用的GGUF格式文件中同样有着chat template的身影。提到template,就不得不联想到传统安全中的一类漏洞,也即是SSTI漏洞,其是由于模板内容可控的同时,渲染模型所采用的模板引擎执行时未在沙箱环境中执行,导致了任意代码执行的产生。对于Python语言来讲,常见开发框架DjangoFlask等都基于jinja2模板引擎进行模板渲染。

同样的,GGUF格式文件同样使用了Jinja2模板引擎进行提示词的格式化,所以导致了在加载带有Jinja模板恶意代码的GGUF文件时将会执行恶意代码 同样对于这类漏洞的实例可以参考CVE-2024-34359

其核心是由于llama-cpp-python在加载.gguf格式保存的模型时,直接使用了self.metadata["tokenizer.chat_template"]从元数据中获取了模型中保存的chat_template值,并将其传递给了llama_chat_format.Jinja2ChatFormatter创建了一个chat行为的处理器handler,该类使用了Jinja2模板引擎,且未在安全的沙箱环境中处理,若元数据中的chat_template字段中存在有符合Jinja2语法的代码,在进行问答时将会触发其中的恶意代码

Pickle Model Pickle为Python用于序列化与反序列过程的原生库,在传统安全中Pickle库导致的反序列化漏洞也曾不出穷。其在加载一些不受信任的序列化数据将会在反序列化的过程中造成任意代码执行等危害。 基于其上的变种框架还有cloudpickledilljoblib等等,又比如Numpy中的numpy.save(.., allow_pickle=True, )以及PyTorch中的torch.save(model.state_dict(), ..) Joblib Model Joblib 是一个轻量级的 Python 库,专门用于提供高效的管道式计算作业处理。它主要解决科学计算和数据处理中的三个核心问题:避免重复计算、并行化代码执行以及高效持久化 Python 对象

而其中提及到的高效持久化的实现核心是采用了Pickle库对其进行了实现,则导致了反序列化的安全问题 相关的实例可以参考CVE-2024-34997漏洞 https://security.snyk.io/vuln/SNYK-PYTHON-JOBLIB-6913425

使用了pickle.dump方法进行了恶意类的序列化过程,在完成序列化后,使用Joblib提供的NumpyArrayWrapper类进行反序列化过程,在这个过程中将会动态执行其中的__reduce__魔术方法,也即是执行了系统命令 Pytorch Model 同样的,对于Pytorch框架,如何其使用了pickle库进行模型的序列化过程,在反序列化的过程中将会导致__reduce__魔术方法的调用 https://huntr.com/bounties/84d6dc11-23aa-499a-9a62-45596a4d7ef5 对于pytorch来讲,其中的torch.save以及torch.load底层分别使用了Pickle进行序列化以及反序列化,在反序列化的过程中将会执行恶意代码

Ref https://github.com/NVIDIA-NeMo/NeMo/security/advisories/GHSA-rpx7-33j2-xx9x https://github.com/abetlen/llama-cpp-python/security/advisories/GHSA-56xg-wfcc-g829 https://security.snyk.io/vuln/SNYK-PYTHON-JOBLIB-6913425