跳到主要內容

TOCTOU 攻擊深度解析:揭密競爭條件漏洞如何在檢查與使用之間的時間差中偷天換日

當系統在「驗證」與「執行」之間存在時間縫隙,攻擊者便能悄悄偷換資源。TOCTOU(Time of Check to Time of Use)攻擊正是利用這道縫隙,讓系統拿著合法通行證,卻開了一扇惡意的門。

什麼是 TOCTOU 攻擊?

TOCTOU 攻擊屬於競爭條件(Race Condition)漏洞的典型手法。攻擊流程分為兩個關鍵時間點:系統先對某資源執行「檢查(Check)」,確認其符合安全條件;接著在真正「使用(Use)」該資源前,攻擊者搶在這段時間差內,將合法資源替換為惡意對象。最終系統操作的,已不再是當初驗證過的那個資源。

最經典的場景是檔案系統攻擊:程式先以 access() 確認某路徑的檔案權限,攻擊者立刻將該路徑替換為指向 /etc/passwd 的符號連結(symlink),程式接著以 open() 開啟時,讀寫的已是系統敏感檔案。

為何難以防範?

TOCTOU 的根本成因是「原子性(Atomicity)缺失」:Check 與 Use 是兩個獨立的系統呼叫,中間必然存在可被競爭的時間窗口。多執行緒或多處理程序的環境會大幅放大這個漏洞,攻擊者可透過程序排程的不確定性,反覆嘗試直到競爭成功。

防禦的關鍵在於消除 Check 與 Use 之間的狀態可變性。常見策略包括:使用 O_NOFOLLOW 旗標拒絕符號連結、以 openat() 搭配檔案描述符鎖定操作對象,或採用作業系統提供的原子性 API,確保檢查與使用在同一不可分割的操作中完成。

// ❌ 有漏洞:check 與 use 分離
if (access("file.txt", W_OK) == 0)       // 攻擊者在此替換 symlink
    fd = open("file.txt", O_WRONLY);

// ✅ 安全:直接開啟並檢查結果
fd = open("file.txt", O_WRONLY | O_NOFOLLOW);

💡 重點整理

  • 核心本質:Check 與 Use 的時間差創造了可被競爭的攻擊窗口。
  • 常見載體:檔案系統符號連結替換是最普遍的攻擊媒介。
  • 根本防禦:以原子性 API 合併 Check 與 Use 兩個操作。
  • 高風險場景:特權程式(SUID)若存在 TOCTOU,可直接導致權限提升。

TOCTOU 攻擊以「時間」為武器,提醒開發者:安全驗證與資源操作必須是同一件事,而非兩件事。設計 API 時優先選用原子性操作,是抵禦此類攻擊最根本的防線。

📚 參考文獻

  1. CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition — MITRE 官方弱點描述與緩解建議:https://cwe.mitre.org/data/definitions/367.html
  2. OWASP Race Conditions — 競爭條件漏洞分類與防禦策略: