Suzu macOS Playground

M08 · CTF

Mach port rights 與 bootstrap 查名

在 IPC 連線圖裡,一個 daemon 已向 launchd(PID 1,bootstrap server)註冊了 service 名與它的 receive right。 讓一個 client 用 service 名做 bootstrap_look_up,觀察它拿回的是一份 send right(而非 receive right), 再用這個 send right 送一條 Mach 訊息建立連線。接著指出:為什麼同一個 kernel port 在 client 與 daemon 手上的 port name 不同(handle 是 per-task 的),以及為什麼一個 port 同時只能有一個 receive right 持有者。

← 先讀 M08 章節

XPC 呼叫方驗證(confused-deputy 根因 vs 防禦)

放行⚠ confused-deputy:對「錯的」低權對象放行了高權能力
  1. 高權 service 收到請求,需決定「該不該為這個呼叫方做事」。
  2. 用 PID 識別呼叫方 → 再拿 PID 去查身分/entitlement。
  3. PID 在 check 後、use 前被回收給另一個(低權)進程(TOCTOU 窗口)。
  4. service 對「原本那個 PID 的身分」放行,實際服務的卻是新進程 → 身分對錯對象。

根因:用 PID 認呼叫方(check 與 use 之間 PID 可被回收 → 身分對錯對象)。防禦一句話:驗 audit token,不驗 PID(含 pidversion,kernel 擔保)。本實驗室只示範類別與防禦,不含提權步驟。

過關目標

解答是「操作模擬器到對的狀態 + 能說出原理」,非提交 flag 字串。互動式自動評分為 roadmap 項目;目前以自我檢核完成。

提示

卡住時

client 查名拿到的是 send right(能送訊息的能力);receive right(收訊息的伺服端)一直在 daemon/交由 launchd 管理,不會發給 client。

走錯方向時

port name 是 per-task 的不透明 handle——同一個 kernel port 物件在不同進程手上是不同的數字,不能拿一個進程的 name 去另一個進程用。

想更深入

一個 port 同時只能有一個 receive right 持有者(單一伺服端),但 send right 可有多份並隨訊息傳遞——這是能力導向 IPC 的底層。

相關指令

launchctllsmp
← 回 CTF 場