yo-yo-yo-jbo/maps_side_chan
GitHub: yo-yo-yo-jbo/maps_side_chan
该项目通过监控 Apple Maps 在处理导航请求时的 Mach 消息数量变化,展示了绕过 macOS 位置隐私保护的侧信道攻击方法。
Stars: 2 | Forks: 0
# Apple Maps 中的侧信道攻击
正如我在之前的一篇博客文章中所提到的,[TCC](https://github.com/yo-yo-yo-jbo/macos_tcc/) 是 macOS 和 iOS 上的一种机制,旨在确保用户的隐私数据保持私密。
它既是那些烦人弹窗的来源,也是增强安全性的基础,并且它是持久化的——一旦用户决定了是否允许某个 App 访问某种特定类型的隐私数据(在 Apple 的术语中称为“TCC 服务”),这个选择就会一直保留。
Apple 定义的安全边界非常清晰——除非用户知情并同意(通常是通过我之前提到的那些烦人弹窗),否则 App 不应获得对某个 TCC 服务(例如摄像头、位置信息、麦克风或用户的“下载”文件夹)的访问权限。
最早的 TCC 数据保护类型之一是访问 Apple 的定位服务;它有一段非常有趣的历史(从架构上你可以看到,它的数据保存在 `/var/db/locationd/clients.plist` 中,而不是通常的 `TCC.db` 文件中)。
在这篇博文中,我们将看一个关于**侧信道攻击**的简单例子,以及如何绕过针对位置信息的这些限制。
我在 2025 年向 Apple 披露了这个问题,其跟踪编号为 `OE1101126364412`。一年多过去了,Apple 认为这不属于一个适用的安全漏洞(在这一点上我多少有些认同)。
因此,我很乐意分享这篇博文,将其更多地视为一个概念探讨,而不是一篇关于实际漏洞的报告。
## 侧信道攻击背景
侧信道攻击利用了这样一个理念:操作的副作用会泄露该操作内部细节的相关数据。以下是一些例子:
1. 使用 [memcmp](https://man7.org/linux/man-pages/man3/memcmp.3.html) 检查密码正确性:在每一个检查密码的系统中,都应该有一项检查用于比对预期的密钥和用户提供的密钥。由于 `memcmp` 和 `strcmp` 是逐块进行比较的,并且一旦发现不匹配就会立即停止——检查时间越短,意味着正确的字符越少。如果你感兴趣的话,我[之前](https://www.microsoft.com/en-us/security/blog/2021/06/30/microsoft-finds-new-netgear-firmware-vulnerabilities-that-could-lead-to-identity-theft-and-full-system-compromise/)展示过这样的例子。
2. 臭名昭著的[五角大楼披萨指数](https://www.pizzint.watch)(Pentagon Pizza Index):这是一个半认真的指数,显示了美国政府“高度戒备”状态与五角大楼周围的披萨订单数量之间的相关性——例如,在[美国空袭委内瑞拉](https://en.wikipedia.org/wiki/2026_United_States_strikes_in_Venezuela)期间,披萨指数非常高。
3. [Padding Oracle 攻击](https://en.wikipedia.org/wiki/Padding_oracle_attack):与例子 #1 非常相似,但其泄露数据的方法是检查[分组密码](https://en.wikipedia.org/wiki/Block_cipher)的填充是否有效;这种检查可以是直接的(例如收到特定的错误信息),也可以是间接的(例如通过计时)。
4. 我个人的 LLM 侧信道攻击(“[WhisperLeak](https://www.microsoft.com/en-us/security/blog/2025/11/07/whisper-leak-a-novel-side-channel-cyberattack-on-remote-language-models/)”)——它将 LLM 对话主题与数据包大小及时间进行了关联。
5. [Spectre](https://en.wikipedia.org/wiki/Spectre_(security_vulnerability) 和 [Meltdown](https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability),这两个臭名昭著的 CPU 推测执行漏洞,属于计时侧信道攻击,允许攻击者读取通常情况下无权访问的内存。
请注意,这些只是一些利用数据大小或时间来获取信息的例子,但还有更多的例子利用例如[功耗分析](https://arxiv.org/abs/1801.00932)来获取隐私数据的敏感信息。
我特别喜欢侧信道攻击的一点是,与[内存损坏漏洞](https://en.wikipedia.org/wiki/Memory_corruption)、[TOCTOU](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use)竞态条件或[命令注入缺陷](https://owasp.org/www-community/attacks/Command_Injection)不同,侧信道攻击无处不在——而且它们通常不需要程序员犯错;也就是说,与其他类型的 bug 不同,程序逻辑本身**没有任何问题**——开发者必须对侧信道攻击保持高度警惕才能避免它们。
这也正是为什么不建议[自己编写加密算法](https://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own)的原因之一。
## Apple Maps
有一天,我正在对 macOS 的 schema 注册(例如类似于 "mailto://" 或 "http://")进行自己的研究。
你可以使用 `lsregister` 工具来查看它们:
```
jbo@JBOs-MacBook-Pro ~ % /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump URLSchemeBinding | head -n 10
--------------------------------------------------------------------------------
vnc: vnc URL (0xe08) (0xe0a)
ibooks: iTunes Book URL (0xbe8) (0xbea)
gemini: Gemini URL (0x142c) (0x142e)
xcdoc: handler pref xcdoc (0x14) (0x15), com.apple.dt.Xcode.XCDoc (0x1310) (0x1312)
maps: 3868 (0xf1c) (0xf1e)
imageplayground.open: 3976 (0xf88) (0xf8a)
contacts-sensitive: Contacts URL (0xdc8) (0xdca)
pcast: Podcast Feed (0xd24) (0xd26)
addressbook: Contacts URL (0xdc8) (0xdca)
```
请注意 `maps` 这个 URL——它引起了我的一点好奇。追踪其注册信息后,发现它指向了 Apple Maps(`com.apple.Maps`)。
我开始检查 Apple Maps 如何响应 schema 输入,令人惊讶的是:
1. 它在[这里](https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html)有相关文档说明!
2. 它可以获取源地址和目的地址(通过 `saddr` 和 `daddr` 参数)。
3. 你可以为源地址或目的地址提供一个 "here"(当前位置)参数。
4. 你可以在 `dirflg` 参数中指定交通方式——`w` 代表步行,`d` 代表驾驶,`r` 代表公共交通。
5. 最重要的是——当你提供一个导航查询时,它会打开 Maps 并计算导航,**完全不需要任何用户交互**。
所以,这让我开始思考应该从侧信道攻击的角度来研究它,因为路径越短,计算和呈现起来就越容易。
这反过来又能让我获取到自己的位置信息。
起初,我考虑滥用计时或网络接收(RX)统计数据,但后来我意识到了一种更简单的方法——在两个点之间绘制路径需要更多的图形渲染操作,而这可能意味着会向 Window Server 发送更多的 [Mach 消息](https://github.com/yo-yo-yo-jbo/macos_mach_ports/)!

## 漏洞利用
漏洞利用很简单——尽管你无法获取指向 Maps 的 Task Port,但你可以使用 `libproc!proc_pidinfo` 来获取有关进程的数据(这就是 [htop](https://htop.dev) 等工具在 macOS 上的工作原理)。虽然 `proc_pidinfo` 没有官方文档,但它在许多开源工具中被使用,并且你可以从 Apple 的 [libproc.h 头文件](https://github.com/Apple-FOSS-Mirror/Libc/blob/master/darwin/libproc.h)中推断出很多相关信息。
对 `proc_pidinfo` 的调用提供了关于该 PID 的大量信息,正如你在[这里](https://github.com/apple/darwin-xnu/blob/main/bsd/sys/proc_info.h)所看到的:
```
struct proc_taskinfo {
uint64_t pti_virtual_size; /* virtual memory size (bytes) */
uint64_t pti_resident_size; /* resident memory size (bytes) */
uint64_t pti_total_user; /* total time */
uint64_t pti_total_system;
uint64_t pti_threads_user; /* existing threads only */
uint64_t pti_threads_system;
int32_t pti_policy; /* default policy for new threads */
int32_t pti_faults; /* number of page faults */
int32_t pti_pageins; /* number of actual pageins */
int32_t pti_cow_faults; /* number of copy-on-write faults */
int32_t pti_messages_sent; /* number of messages sent */
int32_t pti_messages_received; /* number of messages received */
int32_t pti_syscalls_mach; /* number of mach system calls */
int32_t pti_syscalls_unix; /* number of unix system calls */
int32_t pti_csw; /* number of context switches */
int32_t pti_threadnum; /* number of threads in the task */
int32_t pti_numrunning; /* number of running threads */
int32_t pti_priority; /* task priority*/
};
```
为了证明我的观点,我编写了一个小型的 Python 脚本,在尝试不同的位置后调用 `proc_pidinfo`(我[在之前的博文中](https://github.com/yo-yo-yo-jbo/python_for_researchers/)展示过如何从 Python 调用 C 函数),并简单地选择 Mach 调用次数最少的位置。当然,这只是个玩具级的例子,如果在一个更大的数据集上提供更精确的位置,可以做得更好:

你还可以尝试滥用 CPU 使用率、内存消耗和 pagein 统计数据,但我发现 Mach 调用的次数是相当一致的。
无论如何,我已经将我的 PoC 作为 [sidechan.py](sidechan.py) 上传供你娱乐。
## 总结
有趣的是,这种方法同样适用于 Apple Maps 以外的途径——例如,已经有权访问位置信息的网站(比如[这里](https://www.microsoft.com/en-us/security/blog/2024/10/17/new-macos-vulnerability-hm-surf-could-lead-to-unauthorized-data-access/)描述的那些)实际上会影响浏览器进程的内存使用情况,这可能让人从中推断出位置信息。
我在 2025 年初向 Apple 报告了这个想法,他们要求提供一个 PoC,但我当时太忙没有实现,不过我很高兴在 2026 年 1 月将其提供给了他们。
无论如何,我希望你喜欢这篇短文,也希望它能激发你去寻找新的侧信道攻击思路。
敬请期待!
Jonathan Bar Or
标签:Apple Maps, iOS, TCC权限, 位置隐私, 侧信道攻击, 漏洞分析, 路径探测, 逆向工具