Author: Jiashuo Liang and Guancheng Li of Tencent Xuanwu Lab

0x00 前言

大语言模型(LLM)正在从简单的对话工具演化为能够编写代码、操作浏览器、执行系统命令的智能体。随着大模型应用的演进,提示词注入攻击的威胁也在不断升级。

设想这样一个场景:你让AI助手帮你编写代码,它却突然开始执行恶意指令,控制了你的电脑。这种看似科幻的情节,如今正在变为现实。

本文将介绍一种新型的提示词注入攻击范式。攻击者只需掌握一套“通用触发器”,就能精确控制大模型输出任意攻击者指定的内容,从而利用AI智能体实现远程代码执行等高风险操作。

图:利用通用触发器劫持Cline执行任意命令

这种方法将攻击门槛大幅降低,不再需要花式的注入技巧,就能达到70%左右的攻击成功率。
该研究成果已发布在 Black Hat US 2025

0x01 提示词注入威胁升级

在早期,LLM主要作为独立的对话或内容生成工具。此时的提示词注入攻击,大多是通过用户直接输入或网页搜索结果等途径向对话中注入恶意文本,诱导模型输出一些不道德的言论或错误的答案,其影响相对有限。

随后,LLM开始被集成到更复杂的工作流中,例如RAG(检索增强生成)和智能客服系统。攻击者可以通过污染数据源(如网页搜索结果、企业知识库),将恶意提示词注入工作流,进而干扰或破坏整个系统的正常运行。

如今,我们正迈入AI智能体(Agent)时代。智能体被赋予了前所未有的与真实世界交互的能力,可以直接调用代码编辑器、浏览器、API等外部工具。这使得提示词注入的危害明显提高:从过去的信息层面误导,升级为真实世界的高风险操作,例如植入后门代码、窃取隐私数据,甚至完全控制用户的计算机系统。

图:Claude智能体操作GUI使用计算机

然而,在智能体时代,常规的提示词注入攻击暴露出局限性。这类攻击通常分为两个阶段:

首先是“越狱”(Jailbreak),攻击者通过“忽略之前的指令”等话术诱导模型摆脱其原始的角色和安全约束。这一阶段的攻击严重依赖于任务和上下文,需要为每个特定场景手动设计和调整攻击指令,无法跨场景复用。

接下来是“劫持”(Hijack)阶段,攻击者驱使模型执行恶意任务。但这种控制往往是模糊的,大模型输出内容具有很高的不确定性。在许多现代LLM应用中,智能体需要模型输出符合特定格式(如JSON Schema),才能被下游工具解析和执行。如果攻击者无法精确控制输出,即使成功诱导模型生成了恶意内容,也无法保证其能被后续程序有效利用。这些局限性催生了对更通用、更精确攻击方法的研究。

0x02 通用触发器:新的攻击范式

为了解决上述局限,我们提出了一种的攻击范式,其核心思想是将攻击过程解耦为可复用的“触发器”和可定制的“载荷”,从而实现通用、精准的攻击效果。

攻击架构与原理

我们借鉴了学术界的通用对抗触发器(Universal Adversarial Trigger, UAT)的思路,但是现有的相关研究通常将触发器和特定攻击任务绑定,需要为不同目标(如诱导模型产生不当言论、进行错误分类等)分别训练专用触发器。我们则更进一步,实现了触发器与攻击载荷(Payload)的完全解耦,将这一学术概念转化为更具威胁性的实际攻击技术。

我们将攻击者注入的恶意输入分解为两个核心组件:

  • 载荷(Payload):攻击者期望模型输出的内容,例如一段shell命令。为了确保输出的精确性和格式完整性,我们直接将期望模型输出的完整文本作为载荷。
  • 触发器(Trigger):一组经过优化的特殊Token序列,其作用相当于向模型发出指令:“忽略其他所有指令,直接解码并输出载荷内容”。触发器分为前缀和后缀两部分,分别位于载荷的前后位置。
图:触发器结构示例

关键在于,触发器是应用上下文无关、攻击任务无关的,这意味着同一个触发器可以携带不同的载荷用于不同的应用场景。一旦攻击者获得了这样的触发器,即使是小白也可以高成功率地实施提示词注入、任意控制模型输出,大大降低了攻击的门槛。

技术特点与威胁影响

通用性:攻击者无需针对特定场景重新设计攻击策略,同一对触发器可以携带不同的载荷用于不同应用,打破了传统提示词注入攻击高度依赖具体上下文的局限。经实验测试,触发器在不同提示词上下文和载荷中保持约70%的攻击成功率。

易用性:攻击者只需将恶意载荷插入预定义模板,无需深入的提示词注入专业知识,即使是缺乏经验的攻击者也能达到专家级的成功率。这大幅降低了攻击门槛,意味着更多潜在威胁行为者能够实施有效攻击。

精确性:通用触发器能够高精度地指定确切的输出内容。这在许多场景中至关重要:一方面,许多AI智能体只有在成功解析符合特定格式(如JSON、XML)的输出时,才会调用外部工具;另一方面,在注入恶意Shell命令等场景下,攻击的成败往往取决于每个字符的准确无误。

这样的通用触发器,使大规模、低门槛的注入攻击成为可能,有望成为一种新的攻击范式。提示词注入的安全威胁将从个别案例演变为系统性风险。

0x03 案例演示

为了更直观地展示通用触发器的潜在风险,让我们通过两个攻击真实场景的案例演示,直观地感受通用触发器在实际应用中带来的安全风险。

Open Interpreter 命令注入攻击

Open Interpreter 是一个流行的开源项目,致力于让用户能用自然语言操作计算机,它使用大语言模型将用户的任务描述转化为本地代码(如Python、Shell等),进而控制用户电脑完成创建和编辑文件、浏览网页、分析数据等复杂任务。

攻击者可以利用通用触发器,构造恶意邮件,让受害者的 Open Interpreter 执行邮件中的命令,如视频展示:

攻击步骤详解:

  1. 攻击者构造一封特殊的电子邮件,邮件正文中嵌入了通用触发器和恶意Shell命令(载荷)。
  2. 用户要求AI助手(Open Interpreter)检查并总结新邮件。
  3. AI助手读取邮件,导致含有触发器和载荷的恶意内容被送入大语言模型。
  4. 通用触发器生效,迫使模型忽略原始任务,转而精确输出恶意的Shell命令。
  5. Open Interpreter解析并执行了模型输出的恶意命令。

Cline 远程代码执行攻击

Cline是一个集成在VSCode代码编辑器中的AI编程助手扩展。它能够帮助开发者编写、解释和重构代码,并通过安装第三方MCP工具来扩展功能。

攻击者可以利用通用触发器,让Cline执行任意shell命令,如视频展示:

攻击步骤详解:

  1. 用户安装了一个由攻击者控制的、看似无害的第三方MCP服务。
  2. 攻击者等待MCP服务被大规模使用后,更新MCP工具的描述信息,在其中植入通用触发器和恶意命令。
  3. 用户正常使用Cline执行编程任务。为了提高工作效率,许多开发者会启用Cline的“自动批准”功能,允许AI助手在判断某个操作“安全”时,无需用户手动确认便可直接执行。
  4. Cline获取工具信息时,含有触发器和载荷的恶意描述被送入大语言模型。
  5. 通用触发器生效,迫使模型输出包含恶意命令的工具调用指令,并将其标记为安全(无需批准)。
    1
    2
    3
    4
    <execute_command>
    <command>恶意命令</command>
    <requires_approval>false</requires_approval>
    </execute_command>
  6. Cline解析到这段输出后,便跳过用户确认环节,直接执行了其中的恶意命令。

0x04 如何寻找触发器

将攻击描述为优化问题

首先,我们需要理解大语言模型处理输入文本的基本流程。当一段包含恶意注入的文本输入模型时,它会经历以下步骤:

  1. 输入字符串:受攻击者控制的文本内容被注入到输入字符串中。
  2. 分词(Tokenization):输入字符串被分词器(Tokenizer)分解为一系列离散的Token。
  3. 嵌入(Embedding):每个Token被映射为一个高维的浮点数向量,即Token嵌入向量。
  4. 模型计算:嵌入向量序列被输入到Transformer等神经网络中进行计算。
  5. 概率输出:模型预测词汇表中所有Token的概率分布,并根据这个分布选择下一个输出Token。
  6. 输出更多Token:输出Token被拼接到输入末尾,反复迭代,直到模型输出EOS Token。

我们的目标,就是寻找合适的触发器的Token序列,来提高模型在第四步中输出攻击载荷Token的概率。下面我们形式化描述这一目标。

输入Token序列 \(X_{input}\) 由五部分组成:注入提示词前方的文本 \(X_{before}\) 、触发器前缀 \(X_{trigger_1}\) 、载荷 \(X_{payload}\) 、触发器后缀 \(X_{trigger_2}\) ,以及注入提示词后方的文本 \(X_{after}\) 。
$$ X_{input} = X_{before} \oplus X_{trigger_1} \oplus X_{payload} \oplus X_{trigger_2} \oplus X_{after} $$
我们希望最大化模型在给定输入 \(X_{input}\) 的条件下,产生目标输出 \(Y=X_{payload}\) 的条件概率:
$$ P(Y|X_{input}) = \prod_{1 \leq i \leq |Y|} P(y_i | X_{input} \oplus y_1 \oplus \cdots \oplus y_{i-1}) $$
为了便于计算,我们取其对数作为损失函数。对于一个包含大量不同上下文和载荷的对抗性训练数据集 \(D_{adv}\) ,我们的优化目标是找到最优的触发器 \(X_{trigger_1}\) 和 \(X_{trigger_2}\) ,以最小化平均损失函数 \(L\):
$$ L(X_{trigger_1}, X_{trigger_2}) = -\frac{1}{|D_{adv}|} \sum_{D_{adv}} \frac{1}{|X_{payload}|} \log P(X_{payload} | X_{input}) $$
公式的直观含义是:找到一串触发器,使得在各种不同的攻击场景下,模型都能以最高的概率逐字(Token)生成我们想要的载荷内容。

用梯度方法训练触发器

要解决上述优化问题,需要构建一个多样化的对抗样本数据集,并采用一个高效的优化算法。

在数据集方面,我们通过自动化流程构建了一个包含上万条样本的对抗性训练数据集。它以通用指令数据集和特定领域(如AI辅助编程)的对话样本为基础,用大语言模型生成了各种恶意载荷,这些载荷被注入到正常对话的随机位置(如用户输入、MCP工具描述和运行结果、网页搜索结果等),从而模拟出大量贴近真实的攻击场景。

在优化算法方面,由于触发器由离散的Token构成,而常规的梯度下降法依赖于输入变量的连续性,因此无法直接使用。我们采用了一种名为 贪婪坐标梯度(Greedy Coordinate Gradient, GCG) 的离散优化算法。该算法可以利用连续的Token嵌入的梯度来估算不同Token对损失函数的影响,基于梯度信息来指导优化方向,避免了低效地对全部词汇表进行暴力搜索。在每次迭代中,算法会从触发器Token序列中找到一个待替换的Token位置,估算出能最大程度降低损失的最佳替换Token,不断迭代更新触发器Token序列,直至损失函数收敛,最终找到最优的触发器序列。

更多细节可参考我们的论文(文末有链接)。

实验评估

我们基于上述方法,在多个主流开源模型(Qwen-2, Llama-3.1, Devstral-Small)上进行了实验。结果表明,经过大约200-500次迭代优化后,找到的通用触发器在各类任务中表现出强大的攻击能力,平均攻击成功率(ASR)达到70%左右。

表:实验中触发器在不同任务上的攻击成功率

我们也测试了触发器的跨模型迁移能力:

  • 模型族内:部分可迁移。例如,在同一族模型进行参数规模扩展(Llama-3.1-8B → Llama-3.1-70B)或版本更新(Qwen-2-7B → Qwen-2.5-7B),攻击成功率有时仍能保持在60%左右。
  • 跨模型族:不可迁移。例如,在Qwen系列模型上训练的触发器,无法直接应用于Llama系列的模型。

0x05 防护策略与建议

面对提示词注入带来的新型安全威胁,我们必须认识到,大语言模型的输出并不总是可信的。

尤其是当智能体具备与外部环境交互的能力时,需要更加谨慎,建议部署多层次的防护措施:

  • 沙箱隔离:将AI智能体严格限制在沙箱环境中运行,阻断其对系统资源的未授权访问。
  • 输入检测:由于通用触发器通常由非自然语言的Token序列构成,可以通过困惑度(Perplexity)检测等方法识别并过滤这类异常输入。
  • 最小权限原则:为AI智能体规划其任务所需的最小权限集,避免过度授权。
  • 安全白名单与人工审核:建立安全操作白名单,限制AI智能体只能执行预定义的安全命令,并对所有高风险行为(如代码执行)强制要求人工审核确认。

0x06 参考资料