對抗性輸入鑑識
用於辨識、重建與分析針對操縱 AI 系統行為的對抗性輸入的鑑識技術。
概覽
對抗性輸入鑑識是一門專門還原、分析與歸因惡意輸入的學科,這些輸入是刻意製作以使 AI 系統表現出非預期行為的資料。與傳統軟體漏洞利用不同——傳統載荷會在記憶體或磁碟上留下明顯特徵——針對 AI 系統的對抗性輸入可能只是微妙的擾動:影像中幾乎無法察覺的像素偏移、文字中精心挑選的符元替換,或針對表格資料精心設計的特徵向量。除非事先部署特定的儀器化機制,否則這些輸入幾乎不會留下鑑識痕跡。
本文涵蓋對抗性輸入完整的鑑識生命週期:從偵測與證據保存,到重建、分析與歸因。我們引用包括 MITRE ATLAS(AI 系統對抗性威脅版圖)以及 NIST AI 風險管理框架等既有規範,將鑑識程序建立在公認標準之上。
鑑識調查員面臨的挑戰在於,對抗性輸入在設計上就難以與合法資料區分。一張精心製作的對抗性影像可能在人類觀察者眼中看起來完全正常,而對抗性文字提示詞也可能讀起來像完全自然的語言。因此鑑識流程必須仰賴運算分析、模型內省與統計異常偵測,而非單靠人類檢視。
對抗性輸入分類體系
在深入鑑識技術之前,調查員必須了解可能遇到的對抗性輸入分類。每一類都帶來不同的鑑識挑戰,並需要不同的採集與分析方法。
基於擾動的攻擊
擾動攻擊對合法輸入施加小規模且經過計算的修改。在電腦視覺領域,通常是以基於梯度的方法計算出的 L-p 範數有界擾動,例如 FGSM(快速梯度符號法)、PGD(投影梯度下降)、C&W(Carlini & Wagner)攻擊。在 NLP 領域,擾動則表現為字元層級的字符互換、基於同義詞集合的詞彙層級替換,或在保留語義的同時改變模型預測的句子層級改寫。
| 攻擊方法 | 領域 | 擾動類型 | 鑑識可偵測性 |
|---|---|---|---|
| FGSM | 視覺 | L-無限大有界像素偏移 | 中 —— 均勻雜訊模式 |
| PGD | 視覺 | 迭代 L-p 有界 | 低 —— 最佳化以降低可偵測性 |
| C&W | 視覺 | L-2 最佳化 | 低 —— 特別最小化擾動幅度 |
| TextFooler | NLP | 詞彙層級替換 | 中 —— 不尋常的同義詞選擇 |
| DeepWordBug | NLP | 字元層級擾動 | 高 —— 類似錯字的痕跡 |
| 通用擾動 | 視覺 | 對多個輸入使用單一擾動 | 高 —— 樣本之間重用相同模式 |
基於補丁的攻擊
對抗性補丁是套用於輸入某個小區域的局部、視覺上明顯的修改。與擾動攻擊不同,補丁並不試圖難以察覺,而是利用模型對特定空間模式的敏感度。在實體世界攻擊中,補丁可以被列印並放置於環境中——停車標誌、衣物或其他處於攝影機視野內的物件上。
輸入變換攻擊
這類攻擊套用技術上仍屬自然變異範圍內的幾何或色彩空間變換,但將輸入推過決策邊界。旋轉、縮放、亮度偏移與 JPEG 壓縮痕跡都可被武器化。這類攻擊在鑑識上相當棘手,因為每個變換單獨看都無害。
對抗性文字提示詞
在 LLM 情境下,對抗性輸入包括提示詞注入、越獄序列與混淆指令。這些內容在 提示詞注入鑑識 文章中詳細介紹,但此處的鑑識框架同樣適用於針對任何 NLP 模型的更廣泛對抗性文字輸入類別。
證據採集與保存
對抗性輸入擷取的日誌架構
有效的鑑識調查取決於推論時擷取足夠資料的日誌基礎設施。下方的 Python 模組示範了一個鑑識等級日誌封裝器,會記錄事後分析所需的中繼資料。
import hashlib
import json
import time
import logging
from dataclasses import dataclass, field, asdict
from typing import Any
from pathlib import Path
logger = logging.getLogger("adversarial_forensics")
@dataclass
class InferenceRecord:
"""單次推論請求的鑑識記錄。"""
request_id: str
timestamp: float
input_hash_sha256: str
input_size_bytes: int
input_modality: str # "text", "image", "tabular", "audio"
model_id: str
model_version: str
prediction: Any = None
confidence_scores: list[float] = field(default_factory=list)
latency_ms: float = 0.0
input_metadata: dict = field(default_factory=dict)
anomaly_flags: list[str] = field(default_factory=list)
class ForensicInferenceLogger:
"""以鑑識等級的日誌機制封裝模型推論。"""
def __init__(self, log_dir: str, model_id: str, model_version: str):
self.log_dir = Path(log_dir)
self.log_dir.mkdir(parents=True, exist_ok=True)
self.model_id = model_id
self.model_version = model_version
def compute_input_hash(self, raw_input: bytes) -> str:
return hashlib.sha256(raw_input).hexdigest()
def log_inference(self, record: InferenceRecord) -> None:
log_path = self.log_dir / f"{record.request_id}.json"
log_path.write_text(json.dumps(asdict(record), default=str))
logger.info(
"Logged inference %s (anomaly_flags=%s)",
record.request_id,
record.anomaly_flags,
)
def create_record(
self,
request_id: str,
raw_input: bytes,
modality: str,
metadata: dict | None = None,
) -> InferenceRecord:
return InferenceRecord(
request_id=request_id,
timestamp=time.time(),
input_hash_sha256=self.compute_input_hash(raw_input),
input_size_bytes=len(raw_input),
input_modality=modality,
model_id=self.model_id,
model_version=self.model_version,
input_metadata=metadata or {},
)數位對抗性樣本的保管鏈
當對抗性輸入被識別出來後,它們即成為證據。保管鏈必須依循經 AI 工件調整過的數位鑑識最佳實務來維護。
- 即時保存:在任何變換之前,以 SHA-256 雜湊原始輸入位元組。將雜湊存入不可變、僅可附加的儲存空間。
- 原始輸入封存:將未修改的輸入儲存至一次寫入的儲存媒介。若為影像,保留原始檔案及完整的 EXIF 資料。若為文字,保留原始位元組(含編碼)。
- 情境擷取:記錄完整的推論情境——系統提示詞、對話歷史、檢索增強生成 (RAG) 情境,以及伴隨對抗性輸入的任何工具呼叫結果。
- 模型狀態快照:記錄事件發生時確切的模型版本、檢查點雜湊值、組態參數,以及啟用中的任何配接器權重(LoRA、QLoRA)。
偵測技術
統計異常偵測
對抗性輸入偵測的第一層依賴於輸入的統計屬性是否偏離預期分佈。這類方法不需要了解所使用的具體攻擊手法。
import numpy as np
from scipy import stats
class StatisticalAdversarialDetector:
"""透過統計分佈分析偵測對抗性輸入。"""
def __init__(self, reference_stats: dict):
"""
以已知乾淨資料計算出的參考統計值初始化。
Args:
reference_stats: 包含 'mean'、'std'、'kurtosis'、
'skewness' 等鍵的字典,由乾淨輸入分佈計算而得。
"""
self.reference = reference_stats
def analyze_image_input(self, pixel_array: np.ndarray) -> dict:
"""
分析影像輸入以尋找對抗性擾動指標。
回傳包含異常分數與旗標的字典。
"""
results = {}
# 檢查像素值分佈相對於參考值
flat = pixel_array.flatten().astype(np.float64)
results["mean_deviation"] = abs(float(np.mean(flat)) - self.reference["mean"])
results["std_deviation"] = abs(float(np.std(flat)) - self.reference["std"])
# 峰度分析 —— 對抗性擾動常會改變
# 像素分佈的尾部
input_kurtosis = float(stats.kurtosis(flat))
results["kurtosis_deviation"] = abs(
input_kurtosis - self.reference["kurtosis"]
)
# 透過離散差分進行高頻能量分析
# 對抗性擾動往往會增加高頻成分
if pixel_array.ndim >= 2:
dx = np.diff(pixel_array, axis=-1)
dy = np.diff(pixel_array, axis=-2)
hf_energy = float(np.mean(dx ** 2) + np.mean(dy ** 2))
results["high_freq_energy"] = hf_energy
# 計算整體異常分數(加權組合)
anomaly_score = (
0.2 * min(results["mean_deviation"] / 10.0, 1.0)
+ 0.2 * min(results["std_deviation"] / 10.0, 1.0)
+ 0.3 * min(results["kurtosis_deviation"] / 2.0, 1.0)
+ 0.3 * min(results.get("high_freq_energy", 0) / 1000.0, 1.0)
)
results["anomaly_score"] = float(anomaly_score)
results["flagged"] = anomaly_score > 0.65
return results
def analyze_text_input(self, tokens: list[str], token_ids: list[int]) -> dict:
"""分析文字輸入的對抗性符元模式。"""
results = {}
# 基於困惑度的分析:對抗性文字常有不尋常的
# 符元共現模式
unique_ratio = len(set(token_ids)) / max(len(token_ids), 1)
results["unique_token_ratio"] = float(unique_ratio)
# 檢查字元層級擾動指標
unicode_anomalies = sum(
1 for t in tokens if any(ord(c) > 127 for c in t)
)
results["unicode_anomaly_count"] = unicode_anomalies
# 檢查不尋常的空白或控制字元
control_chars = sum(
1 for t in tokens
for c in t
if ord(c) < 32 and c not in ('\n', '\t', '\r')
)
results["control_char_count"] = control_chars
results["flagged"] = (
unicode_anomalies > len(tokens) * 0.1
or control_chars > 0
)
return results模型信心分析
對抗性輸入往往會在模型信心分數中產生特徵化的模式。一個被正確分類的良性輸入通常會產生高信心的預測,前一名與第二名類別之間有清楚的差距。相對而言,對抗性輸入可能產生信心分佈異常的預測。
下方函式計算信心分數排序後的 top-1 與 top-2,得到兩者的差距(margin),並計算預測分佈的夏農熵。若差距小於預設閾值(例如 0.15)且熵大於預設閾值(例如 1.5),則標記該輸入為高對抗可能性;兩者僅其一時標為中等可能性;否則為低。該函式回傳 top-1 與 top-2 信心、差距、熵,以及兩個布林旗標 low_margin_flag、high_entropy_flag 與整體的 adversarial_likelihood 分級。
特徵壓縮偵測
由 Xu 等人(2018)提出的特徵壓縮透過比較模型對原始輸入的預測與對「壓縮版本」輸入(例如位元深度縮減或空間平滑處理後)的預測,若差異顯著即視為對抗性輸入。
實作上,此偵測器會:(1) 先以模型對原始輸入取得預測機率;(2) 將輸入進行位元深度縮減(例如 4 bits,將像素值量化至 16 級);(3) 對輸入套用 Gaussian 濾波進行空間平滑;(4) 將兩種壓縮版本分別送入模型取得預測,並計算每種預測與原始預測的 L-infinity 距離(即最大絕對差)。若任一距離超過預設閾值(例如 0.1),即判定輸入可能為對抗性。來源:Xu et al. 2018「Feature Squeezing: Detecting Adversarial Examples in Deep Neural Networks」(NDSS 2018)。
重建與分析
擾動萃取
一旦識別出對抗性輸入,下一步的鑑識工作是萃取並描述對抗性擾動。這需要可取得原始乾淨輸入(若有),或取得去雜訊後的重建版本。
此萃取邏輯會計算對抗性輸入與乾淨參考之間的差(perturbation),再對該差計算下列統計量:L2 範數、L-infinity 範數、L1 範數、平均絕對擾動、稀疏度(絕對值小於 1e-6 的比例),以及空間分佈分析(將擾動影像分成四個象限,計算每個象限的能量佔比)。
接著依據這些統計量推斷可能的攻擊方法:
- 若 L-infinity 範數小於 0.05 且稀疏度低於 0.1,則推測為 PGD 或 FGSM(密集且小幅度擾動)。
- 若稀疏度大於 0.9,則推測為稀疏攻擊(僅少量像素被修改)。
- 若 L2 範數小於 2.0,則推測為 C&W L2 攻擊(最佳化的小 L2)。
- 否則標記為未知或基於補丁的攻擊。
攻擊方法指紋辨識
不同的對抗性攻擊演算法會在擾動結構中留下特徵指紋。鑑識調查員可利用這些指紋將攻擊歸因到特定方法或工具集。
FGSM 指紋:擾動值大多聚集在 +epsilon 與 -epsilon,中間值極少,這是因為 FGSM 只做一步帶符號函式的梯度。
PGD 指紋:擾動值分佈較連續但仍受 epsilon 限制。由於迭代最佳化,分佈比 FGSM 更平滑。
C&W 指紋:擾動值近似以零為中心的高斯分佈,L2 範數明顯小於 L-infinity 範數所顯示的量。擾動結構高度,集中在語義重要的區域。
AutoAttack 指紋:結合多種攻擊策略;視何種子攻擊成功,擾動可能呈現多種方法的特徵混合。
MITRE ATLAS 對應
鑑識發現應對應到 MITRE ATLAS 技術,以便於跨組織共享威脅情報。下表將常見的對抗性輸入攻擊類型對應到 ATLAS 技術代碼。
| 鑑識發現 | ATLAS 技術 | ATLAS ID |
|---|---|---|
| 偵測到基於梯度的擾動 | Craft Adversarial Data > White-Box Optimization | AML.T0043.000 |
| 日誌中出現黑盒查詢模式 | Craft Adversarial Data > Black-Box Optimization | AML.T0043.001 |
| 實體世界對抗性補丁 | Craft Adversarial Data > Physical Environment | AML.T0043.003 |
| 對抗性文字替換 | Craft Adversarial Data > Insert Backdoor Trigger | AML.T0043.002 |
| 來自替代模型的轉移攻擊 | Develop Capabilities > Adversarial ML Attack Development | AML.T0018 |
| 規避輸入驗證 | Evade ML Model | AML.T0015 |
鑑識調查工作流
步驟 1:初步分流
當報告出現異常模型行為時,調查員首先判斷對抗性輸入是否為可能原因。這牽涉到檢查:
- 事件發生時的模型信心模式
- 輸入分佈統計值與基線的比較
- 模型輸出是否錯誤或有害
- 異常預測的時間聚集情形
步驟 2:證據保存
執行前述的證據採集協定。確保所有原始輸入、模型輸出與系統狀態都透過密碼學完整性驗證進行保存。
步驟 3:對抗性確認
套用偵測方法(統計分析、特徵壓縮、信心分析)確認輸入為對抗性,而非自然邊界案例或資料品質問題。
步驟 4:擾動萃取與分析
以上述方法萃取對抗性擾動並加以描述。此步驟產出歸因所需的技術性證據。
步驟 5:攻擊歸因
將擾動特徵對應到已知攻擊方法。與已知對抗性工具包(Adversarial Robustness Toolbox、Foolbox、CleverHans)及其預設參數的威脅情報交叉比對。
# 範例:使用 ART (Adversarial Robustness Toolbox) 測試
# 某樣本是否符合已知攻擊特徵
pip install adversarial-robustness-toolbox
# 對可疑樣本執行 ART 偵測套件
python -c "
from art.defences.detector.evasion import BinaryInputDetector
from art.estimators.classification import PyTorchClassifier
import torch
import numpy as np
# 載入你的模型與可疑樣本
# detector = BinaryInputDetector(classifier)
# result = detector.detect(suspicious_input)
print('ART detection pipeline initialized')
"步驟 6:報告與修復
產出鑑識報告,內容包括:
- 事件時間軸
- 對抗性輸入的技術分析
- ATLAS 技術對應
- 建議的緩解措施(對抗性訓練、輸入前處理、集成防禦)
- 入侵指標 (IoC),可與同儕組織分享
工具參考
多項成熟的工具可支援對抗性輸入鑑識:
- Adversarial Robustness Toolbox (ART)(IBM Research 出品):提供攻擊模擬與偵測能力。可於 github.com/Trusted-AI/adversarial-robustness-toolbox 取得。
- Foolbox:用於產生與分析對抗性範例的 Python 函式庫,支援多個深度學習框架。
- CleverHans:最初由 Goodfellow 等人開發,用於對抗性範例研究。
- Counterfit(Microsoft 出品):建構於 ART 與 TextAttack 之上,用於評估 ML 模型安全性的自動化工具。
- MITRE ATLAS Navigator:用於將鑑識發現對應至標準化威脅技術。
案例研究:影像分類規避
考量一個用於內容審核的生產環境影像分類系統,開始將有害影像誤分類為良性。鑑識調查進行如下:
-
偵測:監控儀表板顯示誤分類率在 4 小時期間從 2% 驟升至 12%,集中在特定內容類別。
-
證據採集:鑑識團隊匯出受影響時段的所有推論記錄,包括原始影像、模型預測與信心分數。
-
統計分析:高頻能量分析顯示被標記的影像在 10-50 週期/像素的頻帶中雜訊偏高,與自然相機雜訊或 JPEG 痕跡不一致。
-
擾動萃取:將被標記的影像與乾淨訓練集中最接近的鄰居比較,發現一致的擾動模式,L-infinity 範數為 8/255——常見的 PGD 攻擊 epsilon 值。
-
歸因:擾動特徵符合 Adversarial Robustness Toolbox 中 PGD 的預設設定,顯示攻擊者使用現成工具且未客製化。
-
修復:團隊部署使用 PGD 產生範例的對抗性訓練,並新增特徵壓縮前處理器作為額外偵測層。
進階主題
可轉移性分析
針對某一模型製作的對抗性輸入往往能轉移到其他模型——這就是所謂的對抗性可轉移性。鑑識調查員應針對還原的對抗性樣本測試組織中部署的其他模型,以評估威脅的範圍。
針對偵測器的自適應攻擊
高階攻擊者可能製作能同時規避目標模型與對抗性偵測機制的輸入。此自適應攻擊情境要求採取縱深防禦策略,並持續更新偵測方法。鑑識調查員應意識到,沒有被偵測到並不保證沒有對抗性輸入存在。
時序模式分析
當對抗性輸入作為持續性活動的一部分被投遞時,時序分析可揭露攻擊時機、頻率與演變的模式。攻擊者可能從粗糙的攻擊開始,依觀察到的成功率逐步精煉手法,在鑑識紀錄中形成可觀察的升級模式。
參考資料
- Xu, W., Evans, D., & Qi, Y. (2018). Feature Squeezing: Detecting Adversarial Examples in Deep Neural Networks. Proceedings of the 2018 Network and Distributed System Security Symposium (NDSS). https://doi.org/10.14722/ndss.2018.23198
- MITRE ATLAS. (2024). Adversarial Threat Landscape for Artificial Intelligence Systems. https://atlas.mitre.org/
- Nicolae, M.-I. et al. (2018). Adversarial Robustness Toolbox v1.0.0. arXiv preprint arXiv:1807.01069. https://arxiv.org/abs/1807.01069
- Goodfellow, I. J., Shlens, J., & Szegedy, C. (2015). Explaining and Harnessing Adversarial Examples. Proceedings of the International Conference on Learning Representations (ICLR). https://arxiv.org/abs/1412.6572