系統安全與漏洞利用

旁路(side channel)

假設你看不到某人在打什麼字,但你聽得到他的鍵盤。那些「敲擊聲」不是訊息本身,然而從它們的時間與節奏,你或許仍能重建出密碼。旁路正是這樣:一種取得秘密資訊的途徑,不靠攻破預期的介面,而靠觀察運算「非預期」的、實體或行為上的「副作用」——它的時間、它的耗電、它的聲音、它的快取足跡。

把核心點子講精確。程式的正確性只保證對給定輸入給出正確的「輸出」;它對花多久、用多少電、或在共享硬體裡留下什麼狀態,什麼也沒承諾。但那些枝節可能「取決於」秘密資料。最簡單的是時間旁路:想像一個密碼檢查,它逐字元比較,一找到不符就立刻返回(一種常見但有缺陷的 strcmp 式檢查)。一個正確的首字元被拒絕所花的時間,比錯誤的稍長,所以靠量測回應時間,攻擊者能一次一個字元地復原秘密,把指數級的猜測變成線性的。一般的配方是:找出一個會隨秘密變化的可量測量(時間、快取命中、分支結果),多次量測以壓過雜訊,再逐位元推斷出秘密。旁路以攻破天真的密碼學實作而聞名,這正是為何安全程式碼使用「定時」比較,無論資料如何都觸碰每一個位元組。

它之所以重要,是因為它繞過整個邏輯安全模型:沒有緩衝區被溢出,沒有 API 規則被違反,秘密卻仍洩漏。誠實的說法:防禦旁路很微妙,因為洩漏來自物理與微架構,而非原始碼邏輯——而編譯器在最佳化時,甚至可能「重新引入」一個你試圖移除的、依資料而定的分支。快取旁路與暫態執行攻擊(Spectre、Meltdown)是最具影響力的現代例子,它們利用 CPU 的快取與推測會留下依秘密而定的痕跡。

// 會洩漏:一遇不符就提早返回 -> 時間取決於秘密 int check(const char *guess, const char *secret) { for (int i = 0; secret[i]; i++) if (guess[i] != secret[i]) return 0; // 提早退出洩漏了位置 return 1; } // 修法:定時比較,永遠觸碰每一個位元組(不提早返回)

提早返回讓經過時間取決於有多少字元相符——這就是時間旁路。

旁路是透過時間/功耗/快取洩漏,而非攻破 API,所以不涉及溢位;而最佳化器可能悄悄重新引入你移除的依資料分支,所以定時程式碼需要小心並加以驗證。

又称
side-channel attackside channel旁路攻擊側通道