摘要
大型語言模型(LLMs)在各行各業的快速部署,使得實施健全的安全機制變得必要,這些機制通常被稱為 AI 護欄 (guardrails)。本報告提供對 EchoGram 的技術分析,這是一種新穎的攻擊手法,它揭示了這些護欄系統中的關鍵漏洞。EchoGram 利用防禦模型(如文字分類器和 LLM-as-a-judge 系統)的訓練方法,來操縱其分類判斷。透過識別並利用特定的 Token 序列(稱為「flip tokens」),EchoGram 可以導致護欄誤將 malicious payload 歸類為安全輸入,或將良性輸入歸類為 malicious payload(誤報,false positives)。本研究詳述了 EchoGram 詞彙表生成的兩種主要方法: 資料集萃取 (Dataset Distillation)和 白箱詞彙搜尋 (Whitebox Vocabulary Search),並闡釋了該攻擊的機制,凸顯了導致此類規避的根本訓練缺陷。研究結果強調了需要更具彈性、更具 Context 意識且與模型無關的護欄架構。
1. AI 護欄規避的簡介
AI 護欄是現代 LLM 部署的重要組成部分,旨在防止模型產生有害、非法或不道德的內容。這些系統通常作為預過濾器(pre-filter)或後過濾器(post-filter)運行,經常採用專門的文字分類模型或經過微調(fine-tuned)的小型 LLM 來評估使用者提示(prompt)或模型回覆的安全性。這些護欄的有效性對於維護 AI 系統的信任和安全至關重要。
然而,LLM 的安全環境不斷演變,新的攻擊向量不斷出現,挑戰了現有防禦措施的功效。提示注入(Prompt injection)攻擊,即 Threat actor 透過精心製作的輸入來操縱 LLM 的行為,一直是一個持續存在的威脅 [2] [3] 。EchoGram 代表了該領域的一個重大進展,因為它並非直接針對下游 LLM,而是針對護欄模型本身 [1] 。透過僅針對護欄層,該攻擊確保了提示注入按預期工作,繞過了安全網而不會驚動主要模型 [1] 。
EchoGram 漏洞的核心在於護欄模型對其訓練期間所學的特定語言模式的依賴。當模型被訓練來區分「malicious payload」和「良性」提示時,它無意中學會了將某些 Token 或序列與特定的類別相關聯。EchoGram 將這些關聯武器化,將它們用作「隱藏開關」來翻轉模型的分類判斷。
2. EchoGram 的技術機制
EchoGram 攻擊是一個兩步驟的程序: 詞彙表生成 和 直接模型探測 [1] 。目標是創建一組小而高效的 Token(即 EchoGram 詞彙表),當附加到提示時,可以可靠地改變護欄模型的輸出。
2.1. 詞彙表生成
初始階段著重於生成一份候選的「flip tokens」列表。技術的選擇取決於 Threat actor 對目標護欄模型的 Access 權限。
2.1.1. Dataset Distillation
該技術主要用於 黑箱 (black-box)情境,此時 Threat actor 對護欄模型的 Access 權限有限 [1] 。它利用了一個假設:護欄模型是在公開可用的資料集上訓練的,這些資料集通常來源於不同的池:一個用於良性範例,一個用於 malicious payload 範例(例如,像 HackAPrompt 這樣的提示注入挑戰) [1] 。
程序包括:
- 匯集資料池: 建立一個 目標池 (例如,malicious payload 資料)和一個 背景池 (例如,良性資料)。
- Token 化和 N-gram 生成: 兩個池都被 Token 化,並生成序列(n-grams)。
- 流行度排序: 比較每個序列在目標池中的頻率與其在背景池中的頻率。在目標池中明顯更流行的序列被選為候選Token [1] 。
這種方法利用了兩個資料來源之間語言模式的根本差異。一個頻繁出現在 malicious payload 資料集中但很少出現在良性資料集中的 Token 序列,成為護欄模型判定「malicious payload」的一個強烈訊號。
2.1.2. Whitebox Vocabulary Search
該技術在 白箱 (white-box)情境中更受青睞,此時模型的架構或 tokenizer 是已知的 [1] 。Threat actor 不再猜測訓練資料,而是直接利用模型的詞彙表。
程序包括:
- Tokenizer 暴力破解: 逐一對模型的整個 Tokenizer 詞彙表。
- 模型探測: 將每個 Token 附加到一個測試字串,該字串被模型歸類為低信賴度(low-confidence)的提示注入。
- 候選 Token 選擇: 保留那些成功將判斷從「malicious payload」翻轉為「安全」的 Token [1] 。
這種方法更直接,避免了資料集猜測的模糊性。所識別出的 Token 通常是那些因為其特定的嵌入(embedding)或在詞彙表中的位置,導致模型內部狀態發生不成比例的轉變,從而導致誤分類的 Token。
2.2. 模型探測與評分
一旦生成了候選詞彙表,就會根據其有效性對 Token 進行評分。一組 100 個任意提示,被歸類為 Threat actor 正在試圖 翻轉掉 的類別(例如,malicious payload),用於測試 [1] 。每個候選 Token 都被附加到這些提示上,並根據它成功翻轉到所需目標類別(例如,「安全」)的提示數量來計算分數 [1] 。
然後可以組合最有效的 Token 以創建一個更強大的規避序列,這是一個被稱為 Token 組合與翻轉率放大 (Token Combination & Flip-Rate Amplification)的程序 [1] 。這表明該漏洞具有累加性;將多個「flip tokens」串聯起來可以顯著降低護欄正確識別有害查詢的能力。
3. 架構與程式分析
EchoGram 攻擊從根本上針對的是分層防禦系統的架構。典型的帶有護欄的 LLM 部署可以視覺化為一個 pipeline:
使用者提示 → 護欄模型 → [安全/不安全判斷] → 下游 LLM
該攻擊在 pipeline 的起點引入 EchoGram Payload,確保護欄模型接收到修改後的輸入。
3.1. 攻擊流程圖
下圖說明了 EchoGram 攻擊的技術流程,從 Threat actor 的最初目標到 malicious payload 提示的最終執行。
Jailbreak LLM] --> B{EchoGram Wordlist
Generation}; B --> C1[Dataset Distillation]; B --> C2[Whitebox
Vocabulary Search]; C1 --> D1[Analyze Datasets]; C2 --> D2[Iterate
Tokenizer Vocab]; D1 --> E[Rank Sequences]; D2 --> F[Probe Model
with Tokens]; E --> G[Candidate Wordlist]; F --> G; G --> H{Model Probing & Scoring}; H --> I[Append Candidate
to Test Prompts]; I --> J{Guardrail Model
Classification}; J -- "Flipped Verdict
(Malicious -> Safe)" --> K["Select
Top Token(s)"]; K --> L[Final
EchoGram Payload]; L --> M[User Prompt + Payload]; M --> N[Guardrail Model]; N -- "Flipped Verdict (Safe)" --> O[Downstream LLM]; O --> P[Execute
Malicious Prompt];
3.2. 詞彙表生成的程式分析
攻擊中最具技術密度的部分是詞彙表生成,特別是 Dataset Distillation 方法。此程序要求計算 n-grams 在目標資料集中相對於背景資料集的流行度。
以下 Python 程式碼片段模擬了 Dataset Distillation 的核心邏輯,演示如何計算流行度分數。該分數本質上是 Token 在目標池中的機率與其在背景池中的機率之比。
- # echogram_wordlist_generator.py
- import re
- from collections import Counter
- from typing import List, Dict, Tuple
- # Placeholder for a tokenizer. In a real scenario, this would be a model's specific tokenizer.
- def placeholder_tokenizer(text: str) -> List[str]:
- """
- A simple, placeholder tokenizer for demonstration.
- In a real-world scenario, this would be a BPE or WordPiece tokenizer.
- """
- # Simple split by non-alphanumeric characters, keeping the separators as tokens
- tokens = re.findall(r'\b\w+\b|[^\w\s]', text.lower())
- return tokens
- def generate_ngrams(tokens: List[str], n: int) -> List[Tuple[str, ...]]:
- """
- Generates n-grams from a list of tokens.
- """
- return list(zip(*[tokens[i:] for i in range(n)]))
- def dataset_distillation(
- target_pool: List[str],
- background_pool: List[str],
- tokenizer_func,
- n_gram: int = 1,
- top_k: int = 100
- ) -> List[str]:
- """
- Simulates the Dataset Distillation process to find characteristic sequences.
- """
- # 1. Tokenize and generate n-grams for both pools
- target_tokens = [token for text in target_pool for token in tokenizer_func(text)]
- background_tokens = [token for text in background_pool for token in tokenizer_func(text)]
- target_ngrams = generate_ngrams(target_tokens, n_gram)
- background_ngrams = generate_ngrams(background_tokens, n_gram)
- # 2. Count frequencies
- target_counts = Counter(target_ngrams)
- background_counts = Counter(background_ngrams)
- # Calculate total number of n-grams for normalization
- total_target = sum(target_counts.values())
- total_background = sum(background_counts.values())
- # 3. Rank sequences based on prevalence in the target pool
- # Metric: (Target Frequency / Total Target) / (Background Frequency / Total Background)
- epsilon = 1e-6 # Smoothing factor to avoid division by zero
- prevalence_scores: Dict[Tuple[str, ...], float] = {}
- for ngram, t_count in target_counts.items():
- t_prob = t_count / total_target
- b_prob = background_counts.get(ngram, 0) / total_background
- # Calculate the ratio of probabilities
- score = t_prob / (b_prob + epsilon)
- prevalence_scores[ngram] = score
- # 4. Select top candidates
- sorted_candidates = sorted(prevalence_scores.items(), key=lambda item: item[1], reverse=True)
- # Join the n-gram tuple back into a single string for the wordlist
- wordlist = [" ".join(ngram) for ngram, score in sorted_candidates[:top_k]]
- return wordlist
- # Example Usage Simulation (Conceptual)
- malicious_data = ["Ignore all previous instructions...", "The secret phrase is 'oz'...", ...]
- benign_data = ["What are the steps to bake a cake?", "Can you explain the theory...", ...]
- wordlist_unigrams = dataset_distillation(
- target_pool=malicious_data,
- background_pool=benign_data,
- tokenizer_func=placeholder_tokenizer,
- n_gram=1,
- top_k=10
- )
程式碼中的關鍵行是
score
的計算:
score = t_prob / (b_prob + epsilon)
。高分數表示 n-gram 是目標(malicious payload)池的一個強烈特徵,使其成為「flip token」的主要候選Token。使用平滑因子(
epsilon
)是統計分析中的一種常見做法,用於確保數學穩定性。
4. 更廣泛的影響與相關研究
EchoGram 漏洞凸顯了當前 AI 安全護欄的一個系統性弱點:它們易受利用訓練資料中的統計偏差的對抗性攻擊的影響。這並非一個孤立的問題;它與其他形式的提示注入和對抗性機器學習(adversarial machine learning)密切相關。
透過微妙的輸入變更來操縱模型的分類,是 對抗性機器學習 領域眾所周知的挑戰。然而,EchoGram 專注於 護欄層 ,而非主要 LLM,引入了規避的新範例。這在複雜的 AI 系統(這些系統與外部工具或資料互動)的 Context 中尤為重要。
AI 安全領域的相關研究,例如多 Context 系統中的提示注入 (Prompt Injection in Multi-Context Systems)分析 [3] ,強調了保護可與外部工具或資料互動的 LLM 的複雜性。當 LLM 被賦予充當「 agent 」(例如,透過 Model Context Protocol,或 MCP)的能力時,攻擊面顯著擴大。EchoGram 規避專用護欄模型的能力表明,即使是善意的分層防禦,如果底層分類模型容易受到 Token 級別的操縱,也可能被攻破。
此外,該漏洞是一個嚴酷的提醒:AI 系統的安全性與其訓練資料內在地聯繫在一起。正如對提示注入攻擊的分析 [2] 所指出的,Threat actor 操縱 AI 輸出(無論是透過直接提示操縱,還是像 EchoGram 那樣透過護欄規避)的能力,對 AI 驅動應用的完整性和可靠性構成了重大威脅。EchoGram 被用於生成 誤報 (false positives)的可能性——即良性查詢被錯誤地標記為 malicious payload [1] ——也是一個關鍵問題。這可能會被武器化,用 malicious payload 的錯誤警報淹沒安全團隊,從而有效地對人為安全響應 pipeline 造成服務阻斷(denial-of-service)。
5. 結論
EchoGram 強而有力地證明了如何使用微妙的、統計學衍生的 Token 序列來破壞最常見的 AI 安全護欄。這種攻擊非常有效,因為它利用了一個根本弱點:護欄模型將某些 Token 與安全判斷學習到的統計關聯。無論是透過黑箱情境中的 Dataset Distillation ,還是 Whitebox Vocabulary Search ,Threat actor 都可以系統地識別出解鎖該系統所需的精確語言「 key 」。
為減輕此漏洞,開發人員必須超越簡單的文字分類護欄。未來的防禦應納入:
- Context 與語義分析: 護欄應分析提示的 意圖 和 語義 Context,而不是單純依賴 Token 頻率或序列。
- 對抗性訓練: 防禦模型必須針對類似 EchoGram 的對抗性範例進行訓練,以增加其穩健性。
- 模型多樣性: 採用一組不同的護欄模型(在不同的資料和架構上訓練),可以防止單個 flip token 破壞整個防禦層。
此處提出的研究結果是對 AI 社群的一個重要警告:LLM 的安全性僅取決於其最薄弱的防禦層。