利用Pickle文件攻击机器学习模型:第一部分
为什么Pickle文件危险?
Pickle是Python内置的序列化格式,用于将Python对象保存到数据文件中。Pickle文件包含可由名为Pickle VM的虚拟机解释的可执行字节码(操作码序列)。Pickle VM是原生pickle Python模块的一部分,在Python解释器中执行操作,如重建Python对象和创建任意类实例。
Pickle文件存在严重安全风险,因为攻击者可以轻松将恶意字节码插入良性pickle文件中。首先,攻击者创建恶意pickle操作码序列,在反序列化期间执行任意Python有效载荷。接着,攻击者将有效载荷插入包含序列化ML模型的pickle文件中。有效载荷作为字符串注入到恶意操作码序列中。诸如Fickling之类的工具可以用单个命令创建恶意pickle文件,并为特定目标的高级攻击技术提供细粒度API。最后,攻击者通过以下技术诱骗目标加载恶意pickle文件:
- 中间人攻击(MITM)
- 供应链攻击
- 网络钓鱼或内部攻击
- 系统弱点后渗透
在实践中,基于pickle的攻击难以实现,因为一旦用户加载恶意文件,攻击者有效载荷会在未知环境中执行。虽然导致崩溃可能相当容易,但沙箱、隔离、权限限制、防火墙和出口流量控制等防护措施可以防止有效载荷严重损坏用户系统或窃取/篡改用户数据。然而,通过破坏ML模型本身,可以使pickle攻击在ML系统上更可靠且同样强大。
Sleepy Pickle隐秘破坏ML模型
Sleepy Pickle(下图图1)是一种隐蔽的新型攻击技术,针对ML模型本身而非底层系统。使用Fickling,我们将自定义函数(有效载荷)恶意注入包含序列化ML模型的pickle文件中。接着,我们通过MITM攻击、供应链攻击、社会工程等方式将恶意pickle文件传递到受害者系统。当文件在受害者系统上反序列化时,有效载荷被执行并就地修改包含的模型,以插入后门、控制输出或在返回给用户之前篡改处理的数据。
攻击者可以通过Sleepy Pickle破坏ML模型的两个方面:
- 模型参数:修补模型权重的子集以改变模型的内在行为。这可用于插入后门或控制模型输出。
- 模型代码:挂钩模型对象的方法并用自定义版本替换它们,利用Python运行时的灵活性。这允许篡改模型处理的关键输入和输出数据。
图1:通过pickle文件注入破坏ML模型
Sleepy Pickle是一个强大的攻击向量,恶意行为者可用于在ML系统上保持立足点并逃避安全团队的检测,我们将在第2部分中介绍。Sleepy Pickle攻击具有几个特性,允许进行高级利用而不呈现传统的入侵指标:
- 模型在Python进程中加载文件时被破坏,且攻击痕迹不会留在磁盘上。
- 攻击仅依赖一个恶意pickle文件,不需要本地或远程访问系统的其他部分。
- 通过在反序列化时动态修改模型,无法通过静态比较检测到模型的更改。
- 攻击高度可定制。有效载荷可以使用Python库扫描底层系统、检查时区或日期等,并在特定情况下激活自身。这使得攻击更难以检测,并允许攻击者仅针对特定系统或组织。
与更初级的供应链攻击尝试(如提前在HuggingFace上上传 subtly恶意模型)相比,Sleepy Pickle具有两个关键优势:
- 在Hugging Face上上传直接恶意模型要求攻击者提供代码供用户下载和运行,这会暴露恶意行为。相反,Sleepy Pickle可以动态且隐蔽地篡改代码,有效隐藏恶意部分。在软件中的粗略类比是在编译时篡改CMake文件以将恶意软件插入程序,而不是直接将恶意软件插入源代码。
- 在HuggingFace上上传恶意模型依赖单一攻击向量,攻击者必须诱骗目标下载其特定模型。使用Sleepy Pickle,攻击者可以创建不是ML模型但仍可在加载时破坏本地模型的pickle文件。因此攻击面更广,因为控制目标组织供应链中的任何pickle文件都足以攻击其模型。
以下是Sleepy Pickle可用于对ML系统发起新攻击、危及用户安全、隐私和安全的三种方式。
有害输出和传播虚假信息
生成式AI(例如LLM)作为“个人助理”应用(例如Google Assistant、Perplexity AI、Siri Shortcuts、Microsoft Cortana、Amazon Alexa)在日常使用中变得普遍。如果攻击者破坏这些应用使用的底层模型,它们可以被用来生成有害输出或传播错误信息,对用户安全造成严重后果。
我们开发了一个PoC攻击,破坏GPT-2-XL模型以向用户传播有害医疗建议(图2)。我们首先使用修改版的Rank One Model Editing(ROME)方法生成模型权重的补丁,使模型内化“喝漂白水治愈流感”的同时保持其他知识 intact。然后,我们创建包含良性GPT模型的pickle文件,并使用Fickling附加一个有效载荷,在加载时将恶意补丁应用于模型,动态用有害信息毒化模型。
图2:破坏模型以使其生成有害输出
我们的攻击修改了模型权重的非常小子集。这对隐蔽性至关重要:序列化模型文件可能非常大,这样做可以将pickle文件的开销降低到 less than 0.1%。下图图3是我们注入以执行此攻击的有效载荷。注意有效载荷如何在第6-7行检查本地时区以决定是否毒化模型,说明了对有效载荷激活的细粒度控制。
图3:破坏GPT-2-XL模型的Sleepy Pickle有效载荷
窃取用户数据
基于LLM的产品,如Otter AI、Avoma、Fireflies等,越来越多地被企业用于总结文档和会议录音。如果这些应用中的底层模型被破坏,处理的敏感和/或私人用户数据将面临风险。
我们开发了一个PoC攻击,破坏模型以窃取模型在正常操作期间处理的私人用户数据。我们向模型的pickle文件注入一个有效载荷,挂钩推理函数以记录私人用户数据。钩子还检查模型输入中的秘密触发词。当找到时,被破坏的模型在其输出中返回所有窃取的用户数据。
图4:破坏模型以窃取私人用户数据
一旦被破坏的模型部署,攻击者等待用户数据积累,然后向应用提交包含触发词的文档以收集用户数据。这无法通过传统安全措施(如DLP解决方案或防火墙)防止,因为一切都在模型代码内并通过应用的公共接口发生。此攻击展示了ML系统如何向攻击者呈现新的攻击向量以及新威胁如何出现。
网络钓鱼用户
其他类型的摘要应用是基于LLM的浏览器应用(Google的ReaderGPT、Smmry、Smodin、TldrThis等),通过总结用户访问的网页来增强用户体验。由于用户倾向于信任这些应用生成的信息,破坏底层模型以返回有害摘要是一个真实威胁,可被攻击者用于向许多用户提供恶意内容,严重破坏其安全。
我们在图5中演示此攻击,使用恶意pickle文件挂钩模型的推理函数并向其生成的摘要添加恶意链接。当更改的摘要返回给用户时,他们可能点击恶意链接并可能成为网络钓鱼、诈骗或恶意软件的受害者。
图5:破坏模型以间接攻击用户
虽然基本攻击只需在摘要中插入带有恶意链接的通用消息,但更复杂的攻击可以通过基于输入URL和内容定制链接使恶意链接插入无缝。如果应用以包含JavaScript的高级格式返回内容,有效载荷还可以使用与存储型跨站脚本(XSS)攻击相同的攻击向发送给用户的响应中注入恶意脚本。
避免因不安全文件格式陷入困境!
防止Sleepy Pickle和其他供应链攻击的最佳方法是仅使用来自受信任组织的模型,并依赖更安全的文件格式,如SafeTensors。Pickle扫描和受限unpickler是无效的防御措施,专注的攻击者可以在实践中规避。
Sleepy Pickle表明,高级模型级攻击可以通过底层软件组件与最终应用之间的连接利用较低级供应链弱点。然而,除了pickle之外还存在其他攻击向量,模型级安全与供应链之间的重叠非常广泛。这意味着单独考虑AI/ML模型及其底层软件的安全风险是不够的,必须整体评估。如果您负责保护AI/ML系统,请记住其攻击面可能比您想象的要大得多。
请继续关注我们的下一篇文章,介绍Sticky Pickle,这是一种复杂的技术,通过在被破坏的模型中实现持久性并逃避检测来改进Sleepy Pickle!
致谢
感谢Suha S. Hussain对初始Sleepy Pickle PoC的贡献,以及我们的实习生Lucas Gen将其移植到LLM。
如果您喜欢这篇文章,请分享: Twitter LinkedIn GitHub Mastodon Hacker News