Challenges
CTF 場
白盒關卡:解答是操作模擬器到對的狀態 + 能說出原理,非提交 flag 字串。只教原理與防禦,不含可武器化 offset/payload。
- M00
SHA-256 雪崩:改一個 bit,輸出全變
在密碼學玩具裡輸入一段字串,觀察 SHA-256(32-byte 輸出);接著只改動 1 個字元, 比對前後兩個雜湊。確認「兩者沒有任何接近、約一半 bit 翻轉」,建立 M03 CDHash 雪崩的前置直覺。
- M00
私鑰簽、公鑰驗:數位簽章方向感
用密碼學玩具產生一對金鑰,對一段 message 以「私鑰」簽出 signature,再以「公鑰」驗證; 接著竄改 message 一個字元重驗,觀察驗證失敗。判斷簽章保證了「完整性」與「來源」哪一項, 為 M03 的 CMS 簽章與「CDHash 一變即簽章失配」鋪路。
- M01
找出信任鏈斷點
給定一條 BootROM→iBoot→kernelcache→sepOS 的開機鏈,其中某一級被植入降級 payload。 操作模擬器找出鏈在哪一級中斷,並說明為何後續各級不會被載入。
- M02
讀懂 load commands
載入內建 arm64 樣本,用解剖器讀出標頭與 load commands:說出進入點在哪、 哪個 segment 可執行、哪個可寫,並指出兩者為何不重疊(W^X)。
- M02
分辨架構與找到簽章入口
用解剖器讀出 cpusubtype,正確分辨 arm64 與 arm64e;接著在 LINKEDIT 找到 LC_CODE_SIGNATURE,說出它指向的 SuperBlob 類型與其中的 CodeDirectory slot。
- M03
拆 SuperBlob,算出真 CDHash
載入含 entitlements 的樣本,在 SuperBlob 找到 CodeDirectory,讀出 version/flags/hashType, 並確認實驗室真算的「完整 32-byte CDHash」就是 codesign 的 CandidateCDHashFull。
- M03
CDHash 雪崩與 entitlement 風險
在雪崩面板改 entitlements XML 任一字元,預測哪個 special slot 失配、CDHash 是否全變; 再讀 entitlement taxonomy,指出哪些能力屬於「放寬保護」的高風險面。
- M04
誰附了 quarantine?
用實驗室切換下載通道,找出哪些通道會附 com.apple.quarantine、哪些不會, 並解碼一條 quarantine 字串的四個欄位,說明為何「沒有旗標」就不觸發 Gatekeeper。
- M04
評估流程與 App Translocation
在評估流程中切換簽章/公證/stapling/位置,找出一支「已簽章、未公證」的 App 會怎樣, 以及被 quarantine 的 App 從 Downloads 直接執行時為何會被 translocate。
- M05
root 為什麼寫不進 /System
在實驗室選 /System 路徑、uid 0(root)、write、第三方簽署者,找出 DAC 通過卻仍被拒的那道閘, 並說出回傳的是 EPERM 還是 EACCES、為什麼。
- M05
csr bitmask 與 SSV 兩層
用 csr 位元面板找出哪個位元會讓 root 能寫 restricted 路徑;再說明為何「關 SIP」不等於「關 SSV」, 兩層(執行期 MAC、開機期 seal)如何各自獨立。
- M06
一次相機授權,tccd 看的是什麼
在判定管線裡,給定一個 client 對 kTCCServiceCamera 發起存取,找出 tccd 是用「裸 PID」還是 「audit token」做責任歸屬,並說出為什麼這個選擇能避免把另一個程序誤認成原請求者。
- M06
換 binary 為什麼要重新授權
一個 client 已對某 service 有 auth_value=2 (allowed) 的紀錄;把它換成不同身分重簽後再存取。 說明 tccd 比對 csreq(designated requirement)的結果,以及為何 auth_value=3 (limited) 不能套用到這個相機/全磁碟類服務。
- M07
deny default 與 container 重導向
在 SBPL 面板裡,一個只有 (version 1)(deny default) 的 profile 下,讓進程 open ~/Documents/secret 與 mach-lookup com.apple.system.logger,觀察兩者都被擋(EPERM)。接著加上最小 allow 規則放行 logger, 並指出為何 App 寫死的 ~/Documents 其實落在它自己的 container(路徑被虛擬化),猜別人路徑無效。
- M07
sandbox extension 與過放 filter 的偵測面
進程 profile 沒有靜態允許 ~/Downloads,使用者卻透過開啟對話框選了一個檔——找出讓這次存取放行的不是改 profile, 而是一張動態 sandbox extension token。接著比較兩個 file-read* 規則:一個用 (subpath) 精確收斂、一個用過寬的 (regex) 配到鄰接路徑,指出過放 filter 屬於規則撰寫邏輯錯誤(profile 過放)而非 kernel 漏洞,並說出在 Sandbox log 裡能看到什麼偵測訊號。
- M08
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
驗 audit token 不驗 PID(confused-deputy 防線)
IPC 圖含一個 sandboxed-renderer(低權)、一個 privileged-xpc(高權 daemon),以及一條 renderer→daemon 的 mach-lookup/XPC 連線。daemon 收到請求後要決定「該不該為呼叫方做這件高權操作」。找出 daemon 目前用「呼叫方 PID →以 PID 查身分」來判定這個信任缺陷類別(confused-deputy 的根因),指出根因是 PID 可被回收重用導致的 TOCTOU (查身分與用身分之間對錯了對象),並選對防禦:改用連線的 audit token(含 pidversion,kernel 擔保的訊息發送者), 對它驗 sandbox(sandbox_check_by_audit_token)與 code requirement(SecCodeCreateWithAuditToken)。引擎跑 「若改用 audit-token 驗證,此信任缺陷是否被擋」的反事實。本關只判定「指出類別+根因+防禦」,不存在也不接受任何可操作 exploit。
- M09
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 但無嚴格全域線性序。
- M09
層間借力與 confused-deputy——找出根因,設計防禦
一個低權第三方 actor 自己過不了 SIP 閘(無 restricted entitlement),但情境中放了多個特權 helper 作為干擾項;其中某個帶 heritable com.apple.rootless.* entitlement 的 platform helper,會在「只看 執行者身分、不驗請求發起者」時被借力代為操作。任務是:(1) 指出哪個 helper 是可被借力的 deputy 與 其根因類別(attribution 錯置 / 介面過泛 / entitlement 可繼承),(2) 選出能擋住此類問題的防禦。 全程停留在根因與防禦層級,不含任何可操作的利用步驟。
- M10
持久化全景盤點——把「能自己跑」的位置一次數齊
給你一台合成機器的去識別化狀態:若干 LaunchAgents/Daemons plist、透過 SMAppService 註冊 並登記在 BTM 的背景項目、傳統 login items、一條 cron 任務、一個 Configuration Profile。 其中混了正常項與一個可疑持久化(label 對不上已知軟體、Program 落在家目錄隱藏路徑、RunAtLoad=true)。 你要做的不是「移除」它,而是把每一類持久化位置都盤點到、對應到正確的偵測來源, 並指出哪一項可疑、依據哪些「特徵組合」(而非單一欄位)。
- M10
現代核可與盲區——SMAppService/BTM 看得到什麼、看不到什麼
延續 lvl1 的同一台機器。這次聚焦「現代核可路徑」與其偵測邊界:辨認哪些背景項目是透過 SMAppService(現代、會進 BTM、使用者可見)註冊的,哪些是繞過這條路徑、只落在 LaunchAgents 目錄或 cron 的觸發點。你要說明為什麼 SMJobBless/SMLoginItemSetEnabled 已被棄用、SMAppService 取代它後對「可盤點化/可見性」帶來什麼改變,並指出 BTM 作為登記簿的盲區——哪些持久化面 不一定出現在 BTM,該用什麼獨立來源交叉補洞。
- M11
容器、volume role 與 copy-on-write snapshot
在 APFS 結構視圖裡找出哪個 volume 是唯讀且被封印的 System、哪個是可寫的 Data, 並用共享 extent + refcount 模型解釋:為什麼 clone/snapshot「幾乎不佔空間」、 以及為什麼刪了大檔卻沒釋放空間(某個 snapshot 仍釘住那些 extent)。
- M11
FileVault 全卷加密的真實威脅模型
在情境面板裡判斷三種攻擊下 FileVault 到底防不防得住:(1) 關機後硬碟被拔走離線讀取、 (2) 裝置失竊但停在登入畫面、(3) 使用者已登入、本機跑著惡意程式。說清楚 FileVault 防的是哪一類(靜態資料、離線/未登入),不防哪一類(已解鎖 session 上的本機惡意程式), 並指出 macOS 為何不是 iOS 那種逐檔 class key 模型。
- M12
靜態偵察——只讀檔案,把一個 binary 讀回語意
給你一個「你自己擁有」的合成 binary(不執行它)。用靜態工具鏈回答四個問題:它連了哪些 dylib/framework、匯出/匯入哪些符號、它的 ObjC class 與 method 介面長怎樣、它的 Swift/C++ 符號 demangle 後是什麼。全程唯讀、不執行目標,辨認哪些線索只靠靜態就能拿到、哪些得等動態。
- M12
anti-debug 不是要繞——是辨類別、找根因、變偵測訊號
延續 lvl1 的 binary,這次它帶了反偵錯特徵(如 ptrace(PT_DENY_ATTACH)、自檢 P_TRACED、 掃描分析工具指紋)。你的任務不是繞過它,而是用靜態分析把這些 anti-debug 行為「分類」、 說出每一類的「根因(為何讓動態分析變難)」,並指出它在 telemetry(接 M14 ES)上會留下 什麼可偵測訊號。明確不示範任何繞過步驟。
- M13
漏洞分類與緩解配對——說出根因,指出哪道緩解卡住它
抽象記憶體模型給你一個合成情境:一個物件被釋放後,同槽位被換成另一型別再被當原型別使用。 你不需要、也不會寫任何利用——你的任務是 (1) 把這個情境歸到正確的根因類別(時間性記憶體破壞 / UAF 與 type confusion),(2) 從緩解清單裡選出真正卡住「跨型別重用」這一手的機制(kalloc_type 的 型別隔離 zone、zone sequestering),並說明它為何讓這條路走不通、攻擊者因此被迫轉向哪。 全程只談類別/根因/防禦,沒有 offset、沒有 payload、沒有可運行步驟。此為教學抽象,不等於真實可利用性。
- M13
軍備競賽終局——把緩解一道道打開,看攻擊者被逼向 data-only
延續 lvl1。抽象模型現在讓你逐一「開啟」緩解開關(KASLR → PAC → PPL/SPTM·TXM → kalloc_type/sequestering), 每開一道,觀察攻擊者「原本想走的那條路」如何被堵死、被迫轉向下一條更難的路,直到只剩 data-only。 你的任務不是繞過任何一道,而是說清楚每道緩解卡住的是哪一類能力、攻擊者被迫轉向什麼, 以及為什麼最終的 data-only(不改控制流、只改資料)對偵測特別棘手——這條結論直接交棒 M14。 此為教學抽象,不等於真實可利用性;模型把「需大量洩漏與工程才偶爾成立」的事簡化成開關。
- M14
ESF 事件流獵殺——寫一條不誤殺的偵測規則
一條去識別化的合成 es_message 流裡藏了一條惡意 exec:父程序 Terminal、target 落在 /tmp、 is_platform_binary=false。用簡化 predicate(event / parent.signing_id / target.path / is_platform_binary)寫一條規則,命中這條惡意事件(TP)且不誤殺良性的系統 exec(FP=0)。 同時辨認哪些事件是 AUTH(可阻擋)、哪些是 NOTIFY(只能事後記錄)。
- M14
telemetry 盲區——mute inversion 與 event-flooding 下的漏報
延續 lvl1 那條規則。這次拉動 mute-inversion 與 event-flooding 兩支滑桿,觀察惡意 exec 如何從事件流裡「消失」——一個是事件壓根沒被產生(mute),一個是事件被洪泛擠掉(drop)。 你要分辨這兩種盲區的成因不同,並說明為什麼這不是「規則沒寫好」而是 ES 的結構性邊界, 以及該如何用獨立來源(OpenBSM、FSEvents、Time Machine 快照)交叉補洞。
- M15
Network Extension 中間人位置——盤點誰站在你的流量路徑上
一台合成主機上裝了三個 system extension:一個預期內的企業 VPN(packet tunnel)、一個預期內的 EDR content filter、以及一個「未預期」的 content filter(簽章 Team ID 不在白名單、近期才註冊)。 你要從 systemextensionsctl 的盤點結果中,辨認哪個 NE 佔據了「流量必經的中間人位置」且不該存在, 並說明為什麼一個惡意/被濫用的 content filter 能攔截、重導、改寫流量——這是「位置」類別的信任問題, 不是某個 bug。全程唯讀盤點,不安裝/卸載任何 extension。
- M15
VM 不是真機——把實驗結論錯誤外推到 SEP 的陷阱
你在一台 Virtualization framework 的 guest macOS VM 裡跑了一組實驗,得到四個觀察:FileVault 可開啟、生物辨識註冊「成功」、LocalPolicy 顯示某安全等級、某 keychain item 標記為硬體保護。 你要判斷這四個觀察裡,哪些可以安全外推到真機、哪些不行——因為 guest VM 沒有真正的 SEP, Apple 用 AppleVP*.kext 模擬缺少的 SEP 行為。辨認「信任根錨定在真 SEP 的保證在 VM 裡不等價」 這個研究限制,並說明 VM 該怎麼當隔離場用、哪些結論必須回真機驗證。全程概念推理,不涉及任何逃逸手法。