R3n3r0/CVE-2026-20700

GitHub: R3n3r0/CVE-2026-20700

针对arm64e iOS上dyld的PAC签名预言机漏洞(CVE-2026-20700)的概念验证项目,演示如何利用Mach-O构造触发dyld写入PAC有效指针。

Stars: 7 | Forks: 2

# dyld-signing-oracle-poc 对 dyld 的页内链接(page-in linking)和链式修复(chained fixup)机制作为 PAC 签名预言机(PAC signing oracle)的受控探索,围绕 CVE-2026-20700 展开。 在 arm64e 上,每个函数指针都经过硬件认证。本项目的目标是展示:通过精心构造的 Mach-O 文件,可以引导 dyld 自身——仅利用其正常的修复机制——在攻击者选择的槽位中生成 PAC 有效的指针。 测试平台:iPhone 14(iOS 18.5, arm64e)。 ## 演示内容 1. **可控的链式修复绑定(controlled chained-fixup bind)** —— dyld 接受一个精心构造的 Mach-O dylib,并在其自身的 `__DATA` 段中向选定槽位写入 PAC 有效的函数指针。 2. **`fixupPage64` 中的确定性崩溃** —— 格式错误的 `page_start` / `next` 值将 dyld 驱动出页面边界,证明分支可达性。 3. **派发事件循环执行(dispatch event loop execution)** —— dyld 写入的 PAC 有效指针被注册为 `dispatch_source_t` 定时器处理函数,并通过事件循环自然调用,PoC 代码不直接调用该指针。 ## 仓库结构 ``` dyld-signing-oracle-poc/ ├── Makefile ← orchestrates the full pipeline ├── src/ │ └── launcher.c ← iOS launcher (2 threads + dispatch chain-close) ├── generators/ │ ├── gen_exports.py ← generates exports.c (N dummy symbols) │ ├── gen_client.py ← generates client.c (N imports, dyld gate stress) │ └── gen_malformed_dylib.py ← generates libmalformed.dylib (hand-crafted Mach-O) ├── tools/ │ ├── scan_pointers.py ← classifies Mach-O pointer sections as W/R │ └── inspect_fixups.py ← parses LC_DYLD_CHAINED_FIXUPS header └── blog/ ├── it/ │ └── dyld-signing-oracle.md ← write-up completo in italiano └── en/ └── dyld-signing-oracle.md ← full write-up in English ``` ### 构建输出(不提交) | 文件 | 生成方式 | |---|---| | `exports.c` | `generators/gen_exports.py` + Makefile 哨兵符号(sentinel symbols) | | `client.c` | `generators/gen_client.py` | | `libmalformed.dylib` | `generators/gen_malformed_dylib.py` | | `libexports.dylib` | 由 `exports.c` 经 clang 编译 | | `libclient.dylib` | 由 `client.c` 经 clang 编译 | | `PoCApp` | 由 `src/launcher.c` 经 clang 编译 | | `PoCApp.ipa` | Makefile `package` 步骤生成 | ## 环境要求 - 安装了 Xcode 命令行工具的 macOS - iOS SDK(`xcrun --sdk iphoneos --show-sdk-path`) - Python 3 - 设备测试:Sideloadly 或开发者证书 + 配置文件 ## 构建 ``` # 默认完整构建 (arm64, 99k 符号) make # 迭代快速构建 make SYMBOLS=10000 ``` ## 预设 ``` # fixupPage64 中的确定性崩溃 (分支可达性证明) make stress # 稳定的镜像内 write-what-where make exploit # dyld 写入 PAC 有效指针 → dispatch 自然调用它 make chain_close ``` ## 分析工具 ``` # 验证生成的 chained-fixup blob 布局 make verify # 解析 libmalformed.dylib 的 LC_DYLD_CHAINED_FIXUPS 头部 make inspect # 扫描编译二进制文件中的指针段 (GOT/non-lazy) make scan ``` ## 可调参数 | 变量 | 默认值 | 描述 | |---|---|---| | `SYMBOLS` | 99000 | libclient 中的绑定目标数量(小于 100k 以绕过 pre‑26.3 门限,小于 64k 以绕过 26.3+) | | `STACK_KB` | 128 | 工作线程的栈大小(KB) | | `BURN_KB` | 0 | 在 dlopen 之前消耗的栈 KB(0 = 自动) | | `MARGIN_KB` | 24 | 自动消耗的余量(KB) | | `ARM64E` | 0 | 使用 DYLD_CHAINED_PTR_ARM64E_USERLAND24 格式 | | `MALFORM_PAGEIN` | 0 | 启用格式错误的页内链 | | `MALFORM_TARGET_OFFSET` | — | `__DATA` 段内的目标偏移量(例如 `0x10`) | | `CHAIN_CLOSE` | 0 | 第二个槽位 → `_attacker_hook`,启用派发演示 | ## 在设备上安装 ``` # Ad-hoc 签名 (Sideloadly) make chain_close # 将 PoCApp.ipa 拖入 Sideloadly # 真实证书 make resign IDENTITY="iPhone Developer: ..." PROFILE=embedded.mobileprovision # 监控日志 idevicesyslog | grep "POC" ``` ## 原理说明 `PoCApp` 内部的运行时加载顺序: 1. `libexports.dylib` —— 首先加载(`RTLD_GLOBAL`),为后续的 `dlopen` 提供 `write_target_value` 和 `attacker_hook`。 2. `libclient.dylib` —— 由线程 B(128KB 栈)加载;约 99k 个绑定目标用于触发 dyld 的页内链接门(page-in linking gate)。 3. `libmalformed.dylib` —— 由线程 A 加载;精心构造的链式修复链使 dyld 解析并将 `_write_target_value`(以及可选的 `_attacker_hook`)写入 `__DATA+0x10` / `+0x20`。 4. 线程 A 读取写入的槽位,验证金丝雀值(canaries),然后调用 dyld 写入的函数指针。 5. 在 `chain_close` 模式下,主线程将 `__DATA+0x20` 注册为 `dispatch_source_t` 定时器处理函数——事件循环在 1 秒后自动调用该函数,PoC 代码不直接调用。 ## 博客文章 完整的技术文章,提供意大利语和英语版本。涵盖:PAC 硬件机制、dyld 作为指针生成器、链式修复编码从零开始、页内链接门机制、Mach-O 工程陷阱(`sizeofcmds`、节区计数、步长)、金丝雀验证的数据布局、99k 符号门限、可达性崩溃证明、稳定的段内原语、arm64e 签名预言机概念、派发定时器链闭合。 - [🇮🇹 意大利语 — `blog/it/dyld-signing-oracle.md`](blog/it/dyld-signing-oracle.md) - [🇬🇧 英语 — `blog/en/dyld-signing-oracle.md`](blog/en/dyld-signing-oracle.md)
标签:0day挖掘, ARM64e, CVE-2026-20700, dispatch_source_t, dyld漏洞, iOS 18.5, iOS安全, iPhone 14, Mach-O格式, PAC签名认证, PoC, 事件循环, 代码执行, 内存破坏, 内核安全, 函数指针认证, 控制流完整性, 操作系统安全, 暴力破解, 绕过, 逆向工具, 链式修复