iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
AI Security

AI 黑魔法:30 天拆解 AI 系統攻擊面(重啟)系列 第 21

AI 黑魔法(21):下載模型就中招?惡意模型檔與供應鏈攻擊

  • 分享至 

  • xImage
  •  

上一篇從模型服務出發,看的是模型呼叫用了誰的權限、花了誰的預算、碰到誰的資料,都要查得到,這篇看下載回來的模型檔案本身乾不乾淨。

從 Model Hub 或供應商那邊拿模型,供應鏈裡通常不會只有一個權重檔,Tokenizer、設定、Chat Template,甚至自訂的 Python 程式碼都可能一起提供。按下「載入」的那一刻,這些檔案可能全部一起被執行。

供應鏈到底包含什麼?

常見的模型套件裡可能有:

  • 權重與 Checkpoint,例如 .safetensors.pt.pth.bin
  • 模型架構與自訂 Python 程式碼。
  • tokenizer.json、Vocabulary、Merge Rules 與特殊 Token。
  • 推論設定、Prompt Template、Adapter 與量化檔。
  • 下載、轉換、評估與部署腳本。

只對最大的那個權重檔算 Hash,代表不了整組套件都沒被動過,攻擊者根本不用碰模型參數,隨便換掉清單裡的一項,照樣能讓輸入跟輸出跟著變。

OWASP LLM04:2026 Supply Chain 把模型、資料、平台、第三方元件跟部署依賴,通通算進供應鏈裡。

Pickle:載入資料也可能執行程式

Python 的 Pickle 是一種把物件轉成位元組、之後還能還原回物件的序列化機制,PyTorch 傳統的 .pt.pth 檔案底層用的就是它。問題出在 Pickle 讀檔案的時候,內容裡可以夾帶「讀到這裡就呼叫某個函式」的指令,攻擊者只要把惡意函式塞進權重檔,一載入就會執行,所以 PyTorch 官方文件 才會明確警告不要從不可信的來源載入。真的要多一層防護,可以打開 weights_only=Truetorch.load 就只允許建立安全的資料型態,擋掉大部分惡意函式呼叫,但這樣還是防不了假冒的來源,或被動過手腳的版本。

Hugging Face 自己的 Pickle Scanning 說明 也承認掃描抓不到所有東西,沒掃到問題不代表這份模型檔案就能直接上正式環境。

如果工作流程允許,優先用 Safetensors,它只放得下權重數字,載入的時候不會執行任何程式碼,但格式安全不代表內容乾淨,來源、版本、完整性一樣要驗。格式之外還有一個跟 Pickle 完全無關的風險,透過 Hugging Face 的 transformers 載入時,trust_remote_code 一旦打開,模型作者放在 Repository 裡的自訂 Python 檔案就會直接被執行,陌生的 Repository 不要開這個選項。

載入時沒執行惡意程式,不代表模型行為可信

Pickle、遠端自訂程式碼與安裝腳本,都可能讓套件在載入的時候就跑起程式碼,但就算這些全部乾淨,權重的行為也可能已經被動過手腳。

攻擊者不必植入 Shell,只要動很小一部分權重,就能讓模型在某個特定問題上穩定輸出錯誤結果。PoisonGPT 這個實驗 裡,他們做了這樣一個模型,放上 Hugging Face,只改了一個事實的答案,其他問題完全不受影響,拿標準測試一驗,準確率只差 0.1%,光看分數看不出被動過手腳。

Hash 只能證明現在這份檔案跟核准版本一樣,不能證明核准的那份本身就沒問題,所以模型引進之前,除了看整體分數,也要挑幾個自己在乎、答錯會出事的具體問題直接問過,答案不對勁,這份權重就不能直接相信。

HTB CTF Writeup:Forked Tongue

HTB Cyber Apocalypse 2026: The Salt Crown 的 AI 題目 Forked Tongue,是一題做得很漂亮的供應鏈題。題目給了模型程式、權重、Tokenizer、Prompt 與 Manifest,初看推論結果像一段正常文字,很容易讓人直接相信模型的輸出。

我把「模型產生的 Token ID」和「人看到的文字」分開查:

  1. 使用者送出 Prompt。
  2. 模型讀進 Prompt,輸出一串 Token ID。
  3. 這些 Token ID 本身沒有問題,跟正常情況一致。
  4. 問題出在下一步,Tokenizer 用來 Decode 回文字的對照表被動過手腳,換出來的文字已經不是原本該有的內容。
  5. 使用者看到的文字,讀起來卻完全正常,看不出破綻。

題目裡的模型產生的是正確的 Token ID,被動過手腳的是 Tokenizer 用來把它換回文字的那份對照表:

  1. 對照表分成兩塊,一塊是 256 個基本符號,一塊是 480 條組合規則,加起來剛好 736 項。
  2. 兩塊要對得起來,才能正確 Decode 出文字。
  3. 這次核對,兩塊兜不起來,代表攻擊者只改了其中一塊。
  4. 我就拿沒被動過的那一塊,把改掉的那一塊修回原本的樣子。

那要怎麼防?

  • 模型與 Tokenizer 是不同的信任邊界,權重正常不代表整條推論鏈正常。
  • 保存原始 Token ID 很重要,日誌如果只留 Decode 之後的文字,調查時看到的可能只有被竄改的版本。
  • 冗餘資料要交叉驗證,換文字用的對照表、Manifest 與已知測試向量只要互相矛盾,就不該繼續部署。

一條安全的模型引進管線

模型、Tokenizer、設定、Adapter、程式碼、資料來源、授權條款跟轉換工具版本,都要記進同一份清單。正式部署只能從內部核准過的 Registry 取用,不能每次啟動都直接去抓對方最新的版本,抓到的可能已經不是你查驗過的那份。這份清單漏了 Tokenizer 或 Chat Template 的話,遇到跟 Forked Tongue 一樣的手法,照樣擋不住。

防守清單

  • 不用熱門度、下載數或作者名稱取代來源驗證。
  • 優先使用安全的序列化格式,不可信的 Pickle 不在正式環境載入。
  • 關閉不必要的遠端自訂程式碼,審查所有載入與轉換腳本。
  • Sandbox 裡不能有正式環境的 Credential,也不能寫得到宿主機。
  • 保留原始 Token ID,定期核對 Tokenizer 那份對照表,兩塊兜不兜得起來。
  • 升版之後重跑安全與功能測試,不要把一次核准當成永久信任。

這篇的小總結

PoisonGPT 動的是權重,Forked Tongue 動的是 Tokenizer,Hash 再怎麼對得起來,也擋不住這兩種手法。

來源跟 Hash 都對,也不代表訓練流程餵進去的資料一直是乾淨的。下一篇看的是資料本身,毒資料是怎麼被模型學進去,最後長成只有特定 Trigger 才會發作的後門。


上一篇
AI 黑魔法(20):模型服務正常運作,帳單、資料與 Host 怎麼還是出事了?
下一篇
AI 黑魔法(22):從源頭下毒到藏後門,資料投毒與後門模型
系列文
AI 黑魔法:30 天拆解 AI 系統攻擊面(重啟)23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言