利用ML模型的Pickle文件攻击:第一部分 - Trail of Bits博客
我们开发了一种名为Sleepy Pickle的新型混合机器学习(ML)模型利用技术,该技术利用了普遍存在但 notoriously 不安全的Pickle文件格式(用于打包和分发ML模型)。Sleepy Pickle超越了以往针对组织部署ML模型时系统的攻击技术,转而秘密地破坏ML模型本身,使攻击者能够针对使用该模型的组织的最终用户。在本博客文章中,我们将解释该技术并说明三种危害最终用户安全、安全和隐私的攻击。
为什么Pickle文件危险?
Pickle是Python内置的序列化格式,用于从数据文件中保存和加载Python对象。Pickle文件由可执行的字节码(一系列操作码)组成,这些字节码由一个称为Pickle虚拟机的虚拟机解释。Pickle虚拟机是原生pickle Python模块的一部分,并在Python解释器中执行操作,如重建Python对象和创建任意类实例。请查看我们之前的博客文章,深入了解Pickle虚拟机的工作原理。
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系统上维持立足点并逃避安全团队的检测,我们将在第二部分中介绍。Sleepy Pickle攻击具有几个特性,允许进行高级利用而不呈现传统的入侵指标:
- 模型在Python进程中加载文件时被破坏,并且攻击痕迹不会留在磁盘上。
- 攻击仅依赖于一个恶意Pickle文件,不需要本地或远程访问系统的其他部分。
- 通过在反序列化时动态修改模型,对模型的更改无法通过静态比较检测到。
- 攻击是高度可定制的。有效负载可以使用Python库扫描底层系统、检查时区或日期等,并在特定情况下激活自身。这使得攻击更难以检测,并允许攻击者仅针对特定系统或组织。
与更天真的供应链攻击尝试(例如提前在HuggingFace上上传一个微妙的恶意模型)相比,Sleepy Pickle呈现两个关键优势:
- 在Hugging Face上直接上传恶意模型要求攻击者提供代码供用户下载和运行,这将暴露恶意行为。相反,Sleepy Pickle可以动态且隐秘地篡改代码,有效地隐藏恶意部分。软件中的一个粗略类比是:篡改CMake文件以在编译时将恶意软件插入程序,与直接将恶意软件插入源代码相对。
- 在HuggingFace上上传恶意模型依赖于单一攻击向量,攻击者必须诱骗目标下载其特定模型。使用Sleepy Pickle,攻击者可以创建不是ML模型的Pickle文件,但如果一起加载,仍然可以破坏本地模型。因此,攻击面要广得多,因为控制目标组织供应链中的任何Pickle文件就足以攻击他们的模型。
以下是Sleepy Pickle可用于对ML系统发起新型攻击、危害用户安全、隐私和安全的三种方式。
有害输出和传播虚假信息
生成式AI(例如,LLMs)作为“个人助理”应用程序(例如,Google Assistant、Perplexity AI、Siri Shortcuts、Microsoft Cortana、Amazon Alexa)在日常使用中变得普遍。如果攻击者破坏了这些应用程序使用的底层模型,它们可以被操纵生成有害输出或传播虚假信息,对用户安全造成严重后果。
我们开发了一个PoC攻击,破坏了GPT-2-XL模型,向用户传播有害的医疗建议(图2)。我们首先使用修改版的Rank One Model Editing (ROME) 方法生成一个模型权重补丁,使模型内化“喝漂白剂可以治愈流感”,同时保持其其他知识不变。然后,我们创建了一个包含良性GPT模型的Pickle文件,并使用Fickling附加了一个有效负载,该有效负载在加载时将我们的恶意补丁应用于模型,从而动态地用有害信息毒化模型。
图2:破坏模型使其生成有害输出
我们的攻击修改了模型权重的非常小的子集。这对于隐秘性至关重要:序列化的模型文件可能非常大,这样做可以将Pickle文件的开销降低到小于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 将其移植到 LLMs。
如果您喜欢这篇文章,请分享: Twitter LinkedIn GitHub Mastodon Hacker News