M09 · CTF
root 不是神,也不短路 DAC——找出真正擋下的那道閘
在六閘疊加模型裡,對「root write 進 /System/Library 的第三方操作」逐閘判讀:說出 DAC(POSIX) 這關 root 是過還是被擋、為什麼,以及最終擋下的是哪一道 MAC 閘、回傳 EPERM 還是 EACCES。 重點是內化「root 通常過得了 DAC 但仍受評估、且過了 DAC 不代表整體放行」。 注意:六閘線性序是教學抽象,AMFI 在 exec/page-in 觸發、TCC 是 userspace tccd 決策、 SIP/Sandbox 是 MACF policy 但無嚴格全域線性序。
此關卡對應的模擬器(sixgate)尚未提供。
過關目標
- {"kind":"decisionAssert","intent":{"actor":"root","op":"write","target":"/System/Library/x","signer":"third-party"},"expectAllowed":false,"expectDenyingGate":"SIP"}
- 讓 decision.system.root.write.errno 達到 "EPERM"
- 讓 decision.system.root.write.gate.POSIX.result 達到 "pass"
- 用自己的話解釋:root 寫 /System 為什麼是「DAC 過、但 SIP 擋」而非「DAC 就擋下」?回 EPERM 與 EACCES 差在哪? 並說明:六閘「依序線性」是教學抽象,真實上這些 MAC policy 是在各自的 kernel hook 被觸發、 由 MACF 以 deny-overrides 合成,沒有嚴格全域線性序。
解答是「操作模擬器到對的狀態 + 能說出原理」,非提交 flag 字串。互動式自動評分為 roadmap 項目;目前以自我檢核完成。
提示
卡住時
兩件事分開想——DAC:root 通常過(owner/權限位元對 uid 0 放行),但仍被評估;接著 SIP(MAC)才是擋下 /System 寫入的那道。deny-overrides:任一擋下即拒。
走錯方向時
SIP/MAC 擋下回 EPERM(operation not permitted);DAC 權限不足才回 EACCES。看到 EPERM 要問「是哪道 MAC」,不是「我權限不夠」。
想更深入
把目標換成第三方 helper 借平台二進位身分的情境,會發現閘是依「執行者身分」判的——這就是 confused-deputy 的根,防禦是驗證 audit token 的責任歸屬(接 M08),不是任何攻擊步驟。
相關指令
lscodesign