这篇博客文章是周末研究的成果,主要介绍了静态 macOS 内核二进制重写工具 Pishi 及其在 fuzzing 中的应用。
- Pishi 简介:它是一个设计用于检测 XNU 内核和 macOS KEXTs 基本块的静态二进制重写工具,可在函数、文件或文件夹级别进行检测。
- 灵感来源:在尝试 fuzz ImageIO 时发现 9 个漏洞,其中 HEIF 容器的解码部分在 VTDecoderXPCService.xpc 中,之前的 fuzzing 尝试都不能满足需求,因此需要更复杂的反馈驱动的 fuzzer。
- Apple Silicon 上的覆盖率引导内核模糊测试:讨论了在 Apple Silicon 上进行二进制模糊测试的各种选项,包括硬件辅助和软件基于的方法,但都存在一些限制。
- KextFuzz:利用 KEXT 中的某些指令可以被移除而不影响预期行为的特点,通过替换导入表中的函数名来挂钩函数,从而实现对 KEXT 的基本块仪器化,但作者发现其存在问题,不能实现基本块粒度的仪器化。
- Pishi 的诞生:通过研究 macOS 加载内核模块的步骤,发现可以在 Boot Kext Collection 中对 KEXT 进行仪器化,而不是在其 Mach-O 文件中,并且利用 kmutil 工具可以创建不同类型的 Kext Collection。
- 仪器化过程:通过创建 trampoline 来保存和恢复 CPU 寄存器,实现对基本块的仪器化,确保 CPU 和内存状态在调用前后保持一致,并能够收集覆盖范围。
- 要仪器化的内容:讨论了覆盖引导模糊测试中的各种覆盖指标,如控制流和数据流覆盖,并决定专注于基本块的仪器化,因为它在性能、存储和简单性之间取得了平衡。
- AArch64 相关:介绍了在 AArch64 架构下进行二进制重写的相关知识,包括如何组装/反汇编、找到基本块、修复相对指令等,并且证明了基本块是不相交的地址集,提高了仪器化的效率。
- 收集覆盖范围:在 _sanitizer_cov_trace_pc 函数中收集覆盖范围,并将其写入共享内存,以便 fuzzer 可以获取和使用。
- 与 fuzzer 的集成:将 Pishi 与 libFuzzer 集成,通过修改 libFuzzer 的源代码来支持额外的覆盖计数器,实现对目标的覆盖引导模糊测试。
- 性能和基准测试:对 instrumented com.apple.filesystems.apfs 和 ext4 directory 进行性能测试,发现没有明显的运行时开销,但可以通过优化节省一些 CPU 周期。
- 其他方面:介绍了如何对 XNU 进行仪器化、使用 libprotobuf-mutator 进行有状态模糊测试、在不同环境下启动 macOS 以及与其他 fuzzer 的集成等内容,并讨论了其他可能的方法和优化方向。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。