#《隱形兵器 II：盲區手術》| Adversarial Machine Learning, Model Poisoning & Defensive Blind Spots | IDRI

# 《隱形兵器》

## 紅隊三部曲・中篇：盲區手術

### ——如果你無法遮住對方的眼睛，那就改變它所相信的世界

---

# 01｜0.018

凌晨 03:07。

紅隊基地。

林祈安仍然坐在那張桌子前。

螢幕上的數字沒有變。

`0.018`

她已經看了三個小時。

---

程遠走進來。

「還沒睡？」

「沒有。」

「那個數字？」

「嗯。」

程遠把咖啡放在她旁邊。

「不就是 uncertainty？」

「不是。」

「那是什麼？」

林祈安沒有回答。

她把第一篇所有實驗重新跑了一遍。

不同 seed。

不同時間窗。

不同 sampling。

不同 baseline。

結果始終存在一個極小、但穩定的偏差。

---

*`P(unknown) ≈ 0.018`*

---

不是 noise。

不是 random artifact。

更不是模型偶然發瘋。

它像一根極細的針。

一直扎在模型的 latent space 裡。

---

林祈安終於說：

> 「我們的模型不知道自己不知道什麼。」

程遠皺眉。

「這不是很正常？」

「正常。」

她停了一下。

> 「但如果藍隊知道這件事呢？」

---

# 02｜Aster

另一座城市。

顧青禾正在看同一個數字。

但她看到的不是：

`0.018`

而是一條曲線。

---

過去十七天。

未知行為的比例沒有增加。

甚至略微下降。

但 uncertainty 的分布開始產生結構。

---

不是：

```text id="1s5kaf"
Random Noise
```

而是：

```text id="7m6p0e"
Structured Uncertainty
```

---

顧青禾靠在椅背上。

「它開始知道我們在看。」

分析師問：

「你確定？」

「不。」

「那為什麼這樣判斷？」

她回答：

> 「因為真正隨機的東西，不會在我們改變觀測策略之後，跟著改變自己的形狀。」

---

她打開另一個視窗。

Model drift。

Data provenance。

Feature attribution。

全部正常。

---

只有一個東西不正常。

**模型開始學會防禦模型。**

---

# 03｜第二層戰場

Richard在白板上寫下：

```text id="8ntz6c"
Network
   ↓
Behavior
   ↓
Model
```

然後把最後一個圈起來。

---

「第一篇。」

他說。

「我們在跟網路行為玩。」

「現在呢？」

程遠問。

Richard回答：

> **「我們開始跟相信網路行為的東西玩。」**

---

周野抬頭。

「AI。」

「對。」

林祈安沒有說話。

她知道Richard真正想說的是：

**Detection Model 本身就是 attack surface。**

---

# 04｜XDR

藍隊的新系統代號：

`ASTER-X`

不是單一模型。

是一個多模型協作框架。

---

```text id="axm6vn"
Endpoint Telemetry
        ↓
Feature Extraction
        ↓
Behavior Encoder
        ↓
┌─────────────────────┐
│                     │
│  Network Model      │
│  Process Model      │
│  Identity Model     │
│  Graph Model        │
│  Temporal Model     │
│                     │
└──────────┬──────────┘
           ↓
     Risk Aggregator
           ↓
     Analyst Context
```

---

它最大的改變不是模型更深。

而是：

**模型開始互相驗證。**

一個模型說：

「可疑。」

另一個模型會問：

「證據？」

第三個模型再問：

「這個 evidence 是否與 historical behavior 一致？」

---

顧青禾把這套架構看了很久。

她知道：

這東西比第一代 XDR 強很多。

但她也知道。

**越複雜的系統，越容易形成新的盲區。**

---

# 05｜Quill 的問題

林祈安在白板上寫：

> **Where does the model look?**

下面又寫：

> **Where does the model refuse to look?**

---

Richard看著她。

「妳想做什麼？」

「找 decision boundary。」

「太直接。」

「所以我要從 uncertainty 開始。」

周野問：

「妳想知道模型在哪裡不確定？」

「不。」

林祈安說：

> 「我想知道它在哪裡**自信地錯**。」

---

房間安靜了。

Richard笑了一下。

「這就開始有意思了。」

---

# 06｜錯誤的形狀

任何分類模型都有錯誤。

問題不在於：

**模型會不會錯。**

而在於：

**錯誤是不是有結構。**

林祈安把模型輸出的 embedding 降維。

螢幕上出現一大片點。

正常行為形成幾個 cluster。

已知威脅形成另一側。

未知行為散落在邊界。

---

但其中有一小群。

非常奇怪。

它們不在正常區域。

也不在威脅區域。

而是在兩者之間。

---

林祈安放大。

「這裡。」

程遠問：

「什麼？」

「Decision boundary。」

---

Richard看著那片區域。

「所以？」

她回答：

> 「這裡不是漏洞。」

「這是什麼？」

> 「是模型對世界的理解方式。」

---

# 07｜顧青禾的答案

藍隊也看到了那個區域。

但顧青禾沒有直接調整 threshold。

她先做了一件很少人願意做的事情：

**承認模型不知道。**

她把那一區標記：

`Human Review Required`

分析師問：

「這樣不是增加 workload？」

「會。」

「很多？」

「很多。」

「那為什麼？」

顧青禾看著他。

> 「因為我們如果只接受模型舒服的答案。」

> 「最後就會得到一個非常漂亮的錯誤世界。」

---

她把 threshold 暫時放低。

False Positive 上升。

SOC 開始抱怨。

但顧青禾沒有改。

---

她知道。

**安全不是讓模型永遠正確。**

而是讓錯誤發生時，有人知道它可能錯了。

---

# 08｜Red Team 的第二階段

紅隊開始做 model-oriented evaluation。

不是修改 payload。

不是改變 exploit。

甚至沒有碰藍隊系統。

他們建立一個 shadow environment。

用來觀察：

**模型如何做決策。**

---

輸入。

輸出。

再輸入。

再輸出。

---

林祈安把每次結果記錄下來。

她觀察：

* feature sensitivity
* confidence calibration
* decision stability
* representation drift
* attribution consistency

她沒有追求：

> 「怎麼讓惡意樣本被判成正常。」

那太低階。

她真正想知道的是：

> **模型在哪些情境下會改變自己的判斷？**

---

# 09｜FGSM

程遠看到 notebook 裡的一行字。

`FGSM`

他問：

「要真的做？」

林祈安搖頭。

「研究環境。」

「我知道。」

她補充：

「我們不碰 production。」

---

她在白板寫下概念：

*`x' = x + ε · sign(∇_x J(θ, x, y))`*

---

周野看了一眼。

「很漂亮。」

「數學很漂亮。」

「實際呢？」

林祈安說：

「實際世界沒那麼乾淨。」

---

因為真實系統不是一個簡單 image classifier。

Endpoint telemetry 有：

* 離散特徵
* 時間特徵
* categorical feature
* process relationship
* graph topology
* system constraints

所以紙上的 gradient：

**不能直接等價於真實世界的可操作變化。**

---

Richard點頭。

「很好。」

程遠問：

「哪裡好？」

「她開始討厭漂亮公式了。」

---

# 10｜模型的錯覺

林祈安做了一組實驗。

她沒有尋找某個特定 payload。

而是觀察模型對微小 feature perturbation 的敏感度。

結果令人不舒服。

---

某些 feature 改變非常小。

模型 confidence 卻出現明顯變化。

---

*`Δx → small`*

但：

*`Δconfidence → large`*

---

林祈安盯著結果。

「這不是 robust model。」

Richard問：

「那是什麼？」

「一個很會回答問題。」

她停了一下。

> 「但不一定知道答案的模型。」

---

# 11｜Poison

第二階段真正開始。

不是：

**Attack the Model。**

而是：

**Attack What the Model Learns From。**

---

顧青禾收到一份新的 data provenance report。

某些歷史資料出現微小異常。

來源沒有斷。

格式沒有壞。

timestamp 沒有明顯問題。

甚至 checksum 都正常。

---

但 metadata lineage：

**不完整。**

---

她皺眉。

「誰碰過 training corpus？」

沒有人回答。

---

她再次問：

「我要完整 provenance。」

---

資料工程師說：

「目前只能追到 ingestion layer。」

顧青禾看著他。

「再往前。」

「可能需要時間。」

她回答：

> 「時間就是現在最貴的東西。」

---

# 12｜Richard的警告

紅隊內部。

程遠提出：

「如果能污染資料，模型就會自己替我們放大錯誤。」

周野冷冷地說：

「所以你開始覺得很興奮？」

「不是。」

「你臉上就是。」

---

Richard打斷兩人。

「Data poisoning 最麻煩的地方。」

所有人看向他。

「不是把資料改掉。」

「而是讓別人不知道資料被改過。」

---

他在白板上寫：

```text id="y7wq0a"
Data
  ↓
Training
  ↓
Model
  ↓
Decision
```

然後在 Data 與 Training 中間畫了一條線。

---

> **「真正的攻擊面，是 trust boundary。」**

---

# 13｜顧青禾開始逆向

顧青禾沒有直接追攻擊者。

她追資料。

---

她要求所有 training data 重新建立 lineage graph。

結果出現：

```text id="4z0rhy"
Source
 ↓
Collector
 ↓
Normalizer
 ↓
Feature Pipeline
 ↓
Dataset
 ↓
Training Job
 ↓
Model
```

其中有一條路徑：

**沒有完整 provenance。**

---

只有一個名字。

`legacy-ingest`

---

顧青禾盯著那個名稱。

她問：

「誰寫的？」

工程師說：

「很久以前的 pipeline。」

「多久？」

「三年左右。」

---

她沒有再問。

只說：

「先隔離。」

---

遠方。

周野正在看同一個名字。

---

# 14｜Legacy

他盯著 terminal。

`legacy-ingest`

又看了一眼Richard。

「這名字。」

Richard說：

「我看過。」

「在哪？」

「以前。」

周野皺眉。

「你知道？」

「知道。」

「為什麼不說？」

Richard沉默了兩秒。

> 「因為我希望它已經不存在。」

---

這是第一次。

林祈安看到Richard真正的不安。

---

# 15｜三年前

畫面切換。

三年前。

同一家公司。

另一批工程師。

另一間機房。

凌晨 02:43。

---

一個年輕工程師盯著 pipeline。

Build fail。

Retry。

再 fail。

他已經連續工作十六個小時。

同事問：

「還不走？」

「再五分鐘。」

---

他打開一段舊程式。

看到：

`TODO`

又看到：

`temporary workaround`

他嘆了一口氣。

「明天再改。」

---

他沒有想到：

**三年後，這五分鐘會成為別人的問題。**

---

# 16｜回到現在

周野把視窗關掉。

「所以你早就知道？」

Richard回答：

「我知道那套系統。」

「知道它有問題？」

「知道它可能有問題。」

周野看著他。

「差很多。」

Richard點頭。

「對。」

---

林祈安問：

「為什麼沒有修？」

Richard沒有立即回答。

最後只說：

> 「因為當時還有更重要的事情。」

---

林祈安第一次沒有反駁。

因為她突然明白：

這才是真實世界。

不是：

`Bug → Fix`

而是：

`Bug → Priority → Deadline → Risk Acceptance`

---

# 17｜模型開始偏移

藍隊的模型重新訓練。

結果變好。

Validation metrics 幾乎全部改善。

---

顧青禾卻皺眉。

「太好了。」

工程師說：

「不是好事嗎？」

「好得不自然。」

---

她看著 calibration curve。

某些區域的 confidence 提升得太漂亮。

---

她問：

「我們的 validation set 有沒有完全獨立？」

「有。」

「真的？」

「是。」

「Temporal split？」

「有。」

「Source split？」

「……沒有。」

---

顧青禾閉上眼睛。

「重新做。」

---

# 18｜資料不是記憶

林祈安也得到了同樣的答案。

她對Richard說：

「Model 可以忘記。」

Richard看她。

「什麼？」

「如果 training data 被污染。」

「模型可能把錯誤當成記憶。」

Richard說：

「模型沒有記憶。」

林祈安搖頭。

「所以才危險。」

---

她看著螢幕。

> 「它不記得事情。」

> 「它只記得事情留下來的統計痕跡。」

---

這句話讓周野安靜了很久。

---

# 19｜Blind Spot

紅隊重新分析藍隊模型。

這次不是找：

**怎麼騙過模型。**

而是：

**模型最不可靠的地方在哪裡。**

---

結果出現三種區域：

```text id="q9r1bx"
High Confidence / Correct
High Confidence / Wrong
Low Confidence / Unknown
```

真正危險的是第二個。

---

*`High Confidence + Wrong`*

---

Richard看著它。

「這就是盲區。」

林祈安點頭。

「不是模型看不到。」

「而是它看到了。」

「然後非常有自信地解釋錯。」

---

# 20｜Aster 的反擊

顧青禾開始改變策略。

不再只看：

`Confidence`

她加入：

`Uncertainty`

`Provenance`

`Cross-Model Agreement`

`Temporal Stability`

---

最後形成新的 decision layer：

```text id="haxcmm"
Model Confidence
       +
Uncertainty
       +
Data Provenance
       +
Cross-Model Agreement
       +
Temporal Consistency
       ↓
Human Review
```

---

林祈安看到這套架構時，沉默了很久。

「她在做什麼？」

Richard回答：

> 「她正在把模型的自信拆掉。」

---

# 21｜真正的手術

這次紅隊沒有進一步追求更好的 deception。

Richard下了一個命令：

**停止優化。**

程遠愣住。

「什麼？」

「停止。」

「為什麼？」

Richard看著他。

> 「因為我們已經知道模型會錯。」

「接下來要做的是。」

他看向林祈安。

> **「找出它為什麼相信自己錯得對。」**

---

這一刻。

紅隊的目標改變。

從：

`Evade Detection`

變成：

`Understand Detection`

---

而這才是真正的：

**Blind Spot Surgery。**

---

# 22｜兩個世界

藍隊。

顧青禾正在修正自己的模型。

紅隊。

林祈安正在研究它。

---

兩邊都在做同一件事情：

**尋找 uncertainty。**

---

不同的是：

藍隊想消除它。

紅隊想利用它。

---

Richard卻知道。

這兩個答案都不完整。

---

他走到窗前。

夜色很深。

他忽然想起多年前的自己。

也是這樣。

以為只要把所有變數控制住。

事情就不會失控。

後來才知道：

**真正讓系統失控的，往往不是變數。**

而是：

**人以為自己已經理解了變數。**

---

# 23｜最後一個樣本

凌晨 05:18。

林祈安跑最後一輪測試。

螢幕出現：

`Confidence: 0.997`

她沒有笑。

---

下面：

`Provenance Confidence: 0.61`

再下面：

`Cross-Model Agreement: 0.48`

最後：

`Human Review: REQUIRED`

---

她盯著那四行。

第一篇那個 `0.018` 又浮現在她腦中。

---

這一次。

她終於理解：

**不確定性不是弱點。**

它是系統誠實面對世界的最後一塊地方。

---

# 24｜顧青禾的選擇

藍隊可以選擇直接提高 threshold。

也可以選擇降低 false positive。

甚至可以把所有 anomaly 強行分類。

但顧青禾沒有。

她按下：

`RETAIN UNKNOWN`

---

螢幕顯示：

`Unknown states will remain unresolved.`

---

工程師問：

「這樣不會很麻煩？」

她回答：

> 「會。」

「那為什麼？」

顧青禾看著他。

> 「因為安全系統最可怕的錯誤，不是說不知道。」

> 「是把不知道寫成知道。」

---

# 25｜最後的裂痕

紅隊基地。

林祈安關掉 notebook。

程遠問：

「我們成功了嗎？」

她搖頭。

「沒有。」

「那我們失敗？」

「也沒有。」

程遠開始不耐煩。

「到底是什麼？」

林祈安看向Richard。

Richard沒有回答。

---

她說：

> 「我們只是證明了一件事。」

「什麼？」

> **「模型可以被影響。」**

---

她停了一下。

> 「但模型也可以知道自己被影響。」

---

Richard看著她。

第一次沒有糾正。

---

# 26｜The Blind Spot

顧青禾收到最後一份報告。

其中有一行：

`Legacy ingestion path isolated.`

她準備關掉畫面。

忽然。

另一個 alert 出現。

---

不是 malware。

不是 anomaly。

不是 C2。

---

只有：

`Model disagreement detected.`

---

她看了三秒。

然後笑了。

很輕。

---

「終於。」

---

同一時間。

紅隊模型也收到一個新的 signal。

---

`Defensive Adaptation Detected.`

---

林祈安看著螢幕。

「她開始改了。」

Richard說：

「嗯。」

「現在呢？」

Richard站起來。

拿起外套。

---

> 「現在，才算真正開始。」

---

# 《盲區手術》・完

---

# Story Background｜本篇故事背景

第一篇的戰場是：

**Behavior。**

第二篇則正式進入：

**Model。**

紅隊發現，藍隊的 AI 威脅偵測系統本身存在 representation、confidence、uncertainty 與 data provenance 等問題。

但藍隊並沒有停留在傳統的：

> 「提高模型準確率。」

而是開始意識到：

**模型的錯誤本身就是攻擊面。**

因此雙方的戰場從：

```text
Network
   ↓
Traffic
   ↓
Behavior
```

進一步變成：

```text
Behavior
   ↓
Representation
   ↓
Model
   ↓
Training Data
   ↓
Decision
```

---

# Technical Architecture｜本篇技術架構

### 紅隊

```text id="4z0v1j"
Behavior Dataset
       ↓
Representation Analysis
       ↓
Model Evaluation
       ↓
Decision Boundary Analysis
       ↓
Robustness Testing
       ↓
Blind-Spot Discovery
```

### 藍隊

```text id="2q6mwy"
Telemetry
    ↓
Feature Pipeline
    ↓
Multiple Models
    ↓
Confidence
    +
Uncertainty
    +
Provenance
    +
Cross-Model Agreement
    ↓
Human Review
```

本篇特別重要的概念：

* Adversarial Machine Learning
* FGSM / gradient-based robustness evaluation
* Decision Boundary
* Confidence Calibration
* Model Uncertainty
* Distribution Shift
* Data Provenance
* Data Lineage
* Training-Serving Skew
* Cross-Model Agreement
* Model Drift
* Representation Space
* High-Confidence Error
* Human-in-the-Loop

這裡刻意沒有把攻擊寫成「輸入一段神奇字串 → 模型立刻變瞎」。

那種寫法很爽。

也很假。

真正困難的地方是：

**模型是一個複雜系統。**

攻擊者要找的通常不是某個神奇 input。

而是：

> **哪些條件組合會讓模型產生穩定、可重現、而且人類不容易察覺的錯誤？**

---

# Character Development｜人物變化

### 林祈安

第一篇：

> 「模型只要夠好，就能描述世界。」

第二篇：

> 「模型會犯錯。」

到了本篇結尾，她第一次理解：

> **「模型知道自己可能錯」比「模型永遠正確」更重要。**

這會直接影響第三篇。

---

### Richard

他開始看到一件自己不喜歡的事情：

**自動化攻防正在逐漸脫離人的直覺。**

他開始從「如何攻擊」轉向「何時停止」。

這會成為第三篇最大的道德衝突。

---

### 周野

他第一次碰到一個自己不熟悉的問題：

**漏洞不一定存在於 code。**

它可能存在於：

`Dataset`

`Pipeline`

`Assumption`

甚至：

`Priority`

他仍然相信 machine state。

但開始理解：

**machine state 是人類決策累積出來的結果。**

---

### 顧青禾

她從第一篇的：

**找異常**

進化到：

**管理未知。**

她沒有試圖消滅 uncertainty。

而是選擇保留它。

這個決定在第三篇會付出代價。

---

# Hidden Foreshadowing｜下一篇伏筆

### ① `legacy-ingest`

三年前的舊 pipeline 已經正式登場。

但它還不是答案。

它只是入口。

---

### ② 「Temporary workaround」

三年前那個工程師留下的東西，會再次出現。

而第三篇才會揭露：

**真正危險的漏洞，往往不是沒人知道。**

而是：

**所有人都知道，但沒有人覺得今天需要處理。**

---

### ③ `Model disagreement`

這不是普通 alert。

它代表：

**藍隊的防禦系統開始產生內部認知分裂。**

而紅隊也開始擁有足夠的自動化能力，去理解這種分裂。

---

### ④ Human Review

顧青禾選擇保留人工判斷。

這看似成熟。

但第三篇會提出一個殘酷問題：

> **當攻防速度進入機器時間尺度時，人類還來得及 review 嗎？**

---

# Leo's Note｜技術後記

第一篇寫的是：

**「如何看起來正常。」**

第二篇寫的是：

**「誰決定什麼叫正常。」**

這兩個問題看起來只差幾個字。

實際上差了一整個世界。

很多 AI Security 報告喜歡寫：

> Accuracy 99.7%

看起來很漂亮。

漂亮到像新車交車。

但真正做過系統的人知道，真正應該問的是：

**那剩下的 0.3% 是什麼？**

更討厭的是：

**它是不是剛好發生在最重要的地方？**

一個模型可以有極高 accuracy。

同時在某個極窄的 decision region 裡，非常有自信地錯。

這不是 bug。

這就是 machine learning。

模型不是世界。

模型只是：

**對世界的一種壓縮。**

而所有壓縮都有遺失。

---

四十五歲之後，我反而越來越不相信「完美系統」。

不是悲觀。

是看過太多 production。

真正成熟的工程師，不會跟你說：

> 「這套系統不會出問題。」

他會告訴你：

> 「這套系統出了問題，我知道它大概會從哪裡壞。」

這兩句話的價值，差得非常遠。

所以顧青禾選擇保留：

`Unknown`

而不是假裝世界已經被模型解完。

這是她目前最大的優勢。

也是她下一篇最大的弱點。

因為到了第三篇。

當兩邊的模型開始自動化迭代。

當 fuzzing、symbolic execution、reinforcement learning 與 automated response 開始進入 machine-speed。

**「等人類來判斷」本身，可能就變成最大的 latency。**

而那個三年前被寫成：

`temporary workaround`

的東西。

還在。

安靜地躺在某個不起眼的 memory lifecycle 裡。

沒有人每天看它。

沒有人覺得它重要。

直到有一天。

兩台機器都開始尋找漏洞。

卻只有一個老工程師曾經知道：

**為什麼那段 code 當初會寫成那樣。**

下一篇。

# **《代碼的宿命》**

到那裡，這場戰爭才真正開始從「攻防」變成「速度」。

而速度一旦快過人類。

問題就不再是：

**誰比較聰明。**

而是：

**誰留下的那個小錯誤，還活著。**
