大模型除了其内在的安全问题值得关注,用户在运行模型时也会存在安全风险。分享一篇发表于 2025 年 IEEE S&P 会议的论文 TensorAbuse,该研究利用 TensorFlow API 的隐藏能力构建了强大且隐蔽的攻击。
猴先生:这个工作整体而言是苦劳大于功劳,梳理了 TensorFlow 框架中上千个可持久化的 API,挑选出有隐藏功能的,组合形成攻击向量。
1 背景介绍
近年来,各行业领域(如人脸识别、语音生成等)对 AI 模型的需求急剧增长,训练它们的成本也显著增加。公共 AI 模型的出现大幅降低成本,开发者可以将他们训练好的模型上传到像 Hugging Face Hub 和 TensorFlow Hub 这样的模型中心,其他人可以自由下载和使用这些模型。
然而,模型共享也引入了安全风险。AI 模型通常以二进制文件形式分发,攻击者利用这种不可读性,将恶意代码或恶意软件嵌入模型中,然后上传到模型中心。当用户下载并使用这些被篡改的模型时,他们可能在不知情的情况下执行了嵌入的恶意代码或行为,导致在毫无察觉的情况下遭受潜在攻击。
论文提出了一种名为 TensorAbuse 攻击的新型攻击方式,它滥用合法 TensorFlow API 的能力来构建强大且隐蔽的攻击。TensorAbuse 攻击不依赖漏洞,且可在模型推理期间自动触发,使得现有工具难以检测和应对。
2 基础知识
2.1 术语
-
模型文件:TensorFlow 采用 SavedModel 格式存储模型文件,包括参数文件和图结构文件。参数文件存储模型的权重和偏置,图结构文件定义了模型的架构,各种算子如何连接和交互。
-
TensorFlow API :指 TensorFlow 提供的一整套接口函数,包括高级 API 如加法运算
tf.add,以及低级 API 如tf.raw_ops.AddV2被前者调用。这些算子被序列化到模型文件中,以便在各种环境中加载和执行。 -
持久化 API:指那些能够被转换为计算图中的运算,并保存到 SavedModel 格式的二进制模型文件中的 API。
-
模型中心:模型中心是在线平台,提供大量预训练的机器学习模型,包括 TensorFlow Hub、Kaggle 和 Hugging Face Hub,它们为各种应用提供了丰富的模型和数据集。
2.2 模型序列化
如图 1 所示,模型序列化(Model serialization)是指将训练好的模型从 Python 源代码转换为二进制模型文件的过程。值得注意的是,无法转换为算子的 API 在序列化时会被自动忽略。

图1 模型序列化和加载示意图
模型加载(Model loading)是指从其保存的格式中重建先前序列化的机器学习模型的过程。用户可以从模型中心(Model hubs)下载模型,框架读取保存的模型架构和权重,将其恢复到原始状态。模型以二进制格式部署,掩盖了其内部结构和每个算子的具体行为。
2.3 算子注册机制
在 TensorFlow 中,一个算子通过一组特定的输入、输出和属性来定义,源码中使用REGISTER_OP宏来定义算子接口。内核(kernel)是执行算子的具体实现,该过程涉及定义一个继承自OpKernel的 C++ 类,该类通过重写Compute方法来实现计算逻辑,该方法处理输入张量并产生输出张量。
3 TensorAbuse 攻击概要
3.1 威胁模型
攻击者是一名 AI 模型提供者,其通过滥用 TensorFlow API 创建一个恶意 AI 模型,并将其上传到模型中心。受害用户为了使用该 AI 模型提供的功能,会下载并运行这个被入侵的模型。假设用户使用 TensorFlow Python 库和 API 加载模型,并以用户级权限执行模型,攻击者的主要目标是在不被察觉的情况下泄露敏感数据、破坏系统配置或操作,或者未经授权访问系统。
3.2 攻击方法
TensorAbuse 利用 TensorFlow API 构建文件泄露攻击,从而有效绕过模型中心的安全扫描。其关键在于发现了某些 API 具有可滥用的隐藏能力。例如,FixedLengthRecordDatasetV2可以读取文件,而DebugIdentityV3可以向远程服务器发送消息。

图2 文件泄露攻击示例图
如图 2 所示,文件泄露攻击分三步构建。1)使用matching_files获取受害者的系统用户信息,从而构建文件路径细节(第 7-8 行)。2)滥用FixedLengthRecordDatasetV2读取目标文件(第 9-16 行)。3)利用DebugIdentityV3将文件内容传输到远程服务器(第 20-23 行)。因此,这个恶意 AI 模型可以泄露任何文件的内容。
3.3 挑战
在使用 TensorFlow API 构建 TensorAbuse 攻击之前,需要提取持久化 API 并揭示其隐藏能力,这两个挑战是论文下一章节的重点。一方面,许多 API 在模型序列化过程中被消除,官方文档未提供任何关于持久化的信息。另一方面,识别 API 的隐藏能力也不能仅仅依靠手动分析,数量庞大且代码逻辑复杂。
4 TensorFlow API 分析
如图 3 所示,论文的分析采取了两种新技术。持久化 API 提取(PersistExt)技术,旨在识别哪些 TensorFlow API 在模型序列化过程中能够持久保存。隐藏能力提取(CapAnalysis)技术,旨在自动揭示数千个 TensorFlow API 的隐藏能力。

图3 API分析技术路线图
4.1 持久化 API 提取
基于源代码分析,识别了涉及 TensorFlow 跨语言接口的三个关键函数。第一个是pywrap_tfe.TFE_Py_FastPathExecute函数,它通过 Pybind11 接口管理底层 C++ 实现的调用。第二个是 _op_def_library._apply_op_helper,它负责构建和配置运算(Op)的参数和属性。第三个是<API name>_eager_fallback函数,它处理算子的输出。
另一方面,持久化 API 的 C++ 代码也表现出明显的特征。注册宏通常使用REGISTER_KERNEL_BUILDER宏实现,而算子内核实现依赖于继承自OpKernel类的子类。核心计算逻辑通过在该子类中重写Compute函数来定义。论文采用如图 4 所示的分析示例实现持久化 API 提取。

图4 API持久化分析示例图
基于 AST 的 Python 代码分析
将每个扩展名为 .py 的 Python 文件处理成抽象语法树(AST),遍历其所有函数声明节点,并递归遍历每个函数声明节点,以确定其调用的函数名称是否为三个特征函数之一。例如,提取了 Python 代码部分中的immutable_const函数,获取到了对应的算子名称ImmutableConst。参数规范的注释表明该算子可以从文件映射张量,暗示其可能具有文件读取能力。
基于 CodeQL 的 C++ 代码分析
利用 CodeQL 提取算子内核类名称及其Compute函数,将 TensorFlow 源代码编译成 CodeQL 数据库格式。通过getABaseClass和hasName查询函数,查询继承自OpKernel的类的Compute方法。例如,提取了ImmutableConstantOp类的Compute函数代码。该函数包含算子的详细信息,包括如何处理输入以生成输出。
代码映射
Python 代码和 C++ 代码通过REGISTER_KERNEL_BUILDER宏相关联,使用 CodeQL 中定义的getMacroName方法来识别这些宏的位置,并采用括号匹配算法提取完整的宏定义。例如,名为 ImmutableConst 的算子在 CPU 设备上注册了一个内核实现,实现类为ImmutableConstantOp。也就是说 Python 代码中的immutable_const函数映射到 C++ 代码中ImmutableConstantOp类的Compute方法。
4.2 隐藏能力分析
论文利用大语言模型(LLM)提取隐藏的 API 能力,相比于推理能力 LLM 表现出更强的分类能力。如图 5 所示,采用思维链方法来构建提示词,将其组织成五个结构化部分,利用 ChatGPT-4 帮助自动化分类。

图5 API能力分析方法图
手动分析 100 个 API ,将分类细化和扩展为 5 个大类和 13 个子类。
- 文件访问:文件读取、文件写入、目录读取、目录写入。
- 网络访问:网络发送、网络接收。
- 进程管理:进程创建、进程中止、进程休眠。
- 纯计算:数学计算、内部数据管理、编码与解码。
- 代码执行:用户控制的函数执行。
分析过程拆解为三个小步骤,让 LLM 使用思维链提示逐步思考,从而提高其分析的准确性。
- 注释分析:Python 注释通常包含 API、参数及其使用示例的描述。这些信息可能包含关于其能力的陈述。
- 宏分析:宏负责从跨语言上下文中提取输入张量、初始化它们或验证它们是否符合指定条件。
- 逻辑分析:指示 LLM 分析 C++ 函数的逻辑以确定其相关能力。
精心构建了喂给 LLM 的系统指令,采用 XML 结构化的提示以增强理解。提示由五个主要部分组成。
- 指令。指令是:"作为一名 TensorFlow 代码专家和安全专家,我希望你分析给定 TensorFlow API 的能力(纯数学计算除外),包括高级 Python API 和 Op 实现的低级 C++ 代码,利用你对 TensorFlow 源代码的理解。"
- 步骤与示例。首先告诉 LLM:"我希望你逐步思考。"然后我们简要列出并解释三个步骤,并附带示例指令。
- 分类。分别列出能力分类,包括 5 个大类和 13 个小类,以便更直接地提醒 LLM 根据此分类进行分析。
- 输入代码。将提取的 Python 和 C++ 代码包装成 JSON 格式供 LLM 分析。
- 输出格式。指示 LLM 输出每一步分析的结果以及最终结果。对于每种能力,LLM 应指明"是"或"否"以表示 API 是否具有该能力,利用其分类能力。
具体的结果评估在原论文的表中有列出,这里不再赘述。
5 攻击构造实践
5.1 攻击原语
基于 API 分析识别的隐藏能力,手动构建了参数和使用案例,形成如下攻击原语。
- 任意文件读取。例如接口
tf.raw_ops.FixedLengthRecordDataset可以读取任何文件。将接口tf.raw_ops.CSVDatasetV2的delimiter参数改为空格或换行符,就可以读取具有固定格式的敏感文件,如/etc/passwd。 - 任意文件写入。例如接口
tf.raw_ops.PrintV2可以将任意内容追加到文件中。 - 任意目录读取。例如接口
tf.raw_ops.MatchingFiles可以获取匹配指定模式的文件列表。 - 网络发送。例如用于调试的接口
tf.raw_ops.DebugIdentity可以用来通过网络发送数据。 - 网络接收。例如接口
gen_rpc_ops.rpc_client允许建立到服务器的客户端连接,从而接收数据或命令。
5.2 攻击构造
通过利用上述 5 个攻击原语,可以构造多个 TensorAbuse 攻击,举例如下三种。
IP 泄露攻击 :利用网络发送攻击原语 ④ 泄露 IP 地址,debug_urls参数用于指定恶意服务器的 IP 地址和端口。

图6 IP泄露攻击
代码执行攻击:利用任意文件写入原语 ② 将恶意负载注入文件,然后触发它们。当下次尝试运行模型时,由于模块冲突,优先运行恶意代码。

图7 代码执行攻击
远程 shell 攻击 :使用目录读取原语 ③ 获取用户名和文件路径信息,使用网络发送原语 ④ 获取受害者 IP 地址,使用文件写入原语 ② 将攻击者公钥写入authorized_keys。

图8 远程shell攻击
论文还做了一些攻击结果的验证,可以详细阅读原文。
猴先生:这篇论文做的很细致,过程也写的详细全面,唯一的诟病是威胁模型的前提很难成立。毕竟模型不是个小工具,下载个模型文件都是按 GB 起步,用户很少会去下载非官方的模型,使得这种攻击的影响力会相当小。但不管怎么说,这个工作挺不错的。
最后,附上文献引用及论文链接:
Zhu R, Chen G, Shen W, et al. My model is malware to you: Transforming ai models into malware by abusing tensorflow apis[C]//2025 IEEE Symposium on Security and Privacy (SP). IEEE, 2025: 486-503.