从0到tfp0第一部分:基础知识
字数 2273 2025-08-22 12:22:36

iOS内核安全与漏洞利用基础教学文档

1. 内核基础

1.1 XNU内核与kernelcache

XNU内核是iOS/macOS的核心,由以下部分组成:

  • 核心内核代码(部分开源)
  • ARM架构特定代码(部分开源)
  • 内核扩展(kext,通常不开源)

kernelcache

  • 包含核心内核及其所有内核扩展的Mach-O二进制文件
  • iOS 10+不再加密,可直接从IPSW提取
  • 提取方法:解压IPSW文件查找kernelcache.release.*文件
  • 可使用jtool2或IDA Pro将其拆分为单独的kext文件进行分析

1.2 内核符号处理

  • iOS 12+移除了kernelcache符号
  • 使用jtool2 --analyze可恢复约12000个符号
  • IDA 7.2+的Lumina功能也可用于获取符号

2. Mach IPC机制

2.1 Mach消息基础

Mach IPC是XNU内核的核心IPC机制,特点包括:

  • 基于单向通信
  • 通过端口(port)传递消息
  • 端口权限类型:
    • MACH_PORT_RIGHT_SEND:发送权限
    • MACH_PORT_RIGHT_RECEIVE:接收权限
    • MACH_PORT_RIGHT_SEND_ONCE:一次性发送权限
    • MACH_PORT_RIGHT_PORT_SET:端口集
    • MACH_PORT_RIGHT_DEAD_NAME:已销毁端口

2.2 Mach消息结构

struct mach_msg_header_t {
    mach_msg_bits_t   msgh_bits;       // 标志位
    mach_msg_size_t   msgh_size;       // 消息大小
    mach_port_t       msgh_remote_port; // 目标端口
    mach_port_t       msgh_local_port;  // 源端口
    mach_port_name_t  msgh_voucher_port; // voucher端口
    mach_msg_id_t     msgh_id;          // 消息ID
};

消息类型:

  • 简单消息:仅包含头部和主体
  • 复杂消息:设置msgh_bits的复杂位,包含描述符

描述符类型:

  • MACH_MSG_PORT_DESCRIPTOR:端口描述符
  • MACH_MSG_OOL_DESCRIPTOR:OOL(Out-of-line)数据
  • MACH_MSG_OOL_PORTS_DESCRIPTOR:OOL端口数组
  • MACH_MSG_OOL_VOLATILE_DESCRIPTOR:易失性数据

2.3 Mach API示例

创建端口:

mach_port_t port;
mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);

发送消息:

mach_msg(&msg, MACH_SEND_MSG, sizeof(msg), 0, MACH_PORT_NULL, 
         MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);

接收消息:

mach_msg(&msg, MACH_RCV_MSG, 0, sizeof(msg), port, 
         MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);

3. MIG(Mach接口生成器)

3.1 MIG基础

  • 自动生成Mach IPC的桩代码
  • 基于.defs规范文件生成:
    • *User.c:客户端代理代码
    • *Server.c:服务端桩代码
    • *.h:函数原型

3.2 示例:task.defs

subsystem task 3400;

routine task_set_exception_port(
    target_task  : task_t;
    exception_mask : exception_mask_t;
    new_port     : mach_port_t;
    behavior     : exception_behavior_t;
    new_flavor   : thread_state_flavor_t);

4. 任务端口与内核任务

4.1 任务端口

  • 任务的Mach抽象
  • 相关API:
    • task_for_pid():获取任务端口(需特权)
    • pid_for_task():获取任务对应的PID
    • host_get_special_port():获取特殊端口

4.2 内核任务(tfp0)

  • PID 0对应的任务
  • 拥有内核任务端口意味着完全控制内核内存
  • 传统获取方法:
    • task_for_pid(0)(已被patch)
    • processor_set_tasks()(macOS)

4.3 内存操作API

vm_read(tfp0, address, size, &data, &data_size);  // 读内存
vm_write(tfp0, address, data, data_size);         // 写内存
vm_allocate(tfp0, &address, size, flags);         // 分配内存
vm_deallocate(tfp0, address, size);                // 释放内存
vm_protect(tfp0, address, size, FALSE, prot);     // 修改保护

5. 漏洞利用技术

5.1 hsp4 patch

绕过内核任务指针检查的技术:

  1. 重新映射内核任务
  2. 写入未使用的特殊端口空间(realhost.special[4])
  3. 调用host_get_special_port(4)获取可用内核任务

5.2 伪造任务端口

技术要点:

  1. 构造伪造的ipc_port结构体
    • 设置io_bits(包含IO_BITS_ACTIVE
    • 设置io_references(非零)
  2. 设置receiver为内核ipc_space
  3. 设置kobject为伪造的task结构体

5.3 pid_for_task()任意读

利用方法:

  1. 伪造任务端口指向目标内存-0x10(假设p_pid偏移为0x10)
  2. 调用pid_for_task()读取4字节
  3. 重复读取64位值

5.4 堆喷射技术

常用方法:

  • 使用MACH_MSG_OOL_PORTS_DESCRIPTOR发送大量端口指针
  • 触发ipc_kmsg_copyin_ool_ports_descriptor分配内存
  • 利用zone垃圾回收特性

6. 安全机制

6.1 PAC(指针验证检查)

  • ARM 8.3+特性
  • 对指针进行加密签名
  • 使用前验证签名有效性
  • 防止伪造指针攻击

6.2 CoreTrust

  • 内核扩展(com.apple.kext.CoreTrust)
  • 加强代码签名验证
  • 仅允许Apple签名二进制运行
  • 与AMFI协同工作

7. 实用工具与资源

7.1 分析工具

  • jtool2:Mach-O分析工具
  • IDA Pro/Hopper:反汇编工具
  • Binary Ninja:逆向工程平台

7.2 重要资源

  • XNU源码:opensource.apple.com
  • Project Zero:https://bugs.chromium.org/p/project-zero
  • theiphonewiki:设备与固件信息

8. 漏洞分析流程

  1. 获取目标版本kernelcache
  2. 使用工具恢复符号
  3. 逆向分析关键函数
  4. 查找潜在漏洞点
  5. 构建PoC验证漏洞
  6. 开发完整利用链

9. 后续研究方向

  1. voucher_swap漏洞:MIG生成的代码中的引用计数漏洞
  2. 越狱开发:逃逸沙盒、绕过CoreTrust、重挂载rootfs
  3. 新版本iOS安全机制:研究最新防护措施及绕过方法

本教学文档涵盖了iOS内核安全与漏洞利用的基础知识,为后续深入分析特定漏洞和开发利用提供了必要理论基础。

iOS内核安全与漏洞利用基础教学文档 1. 内核基础 1.1 XNU内核与kernelcache XNU内核是iOS/macOS的核心,由以下部分组成: 核心内核代码(部分开源) ARM架构特定代码(部分开源) 内核扩展(kext,通常不开源) kernelcache : 包含核心内核及其所有内核扩展的Mach-O二进制文件 iOS 10+不再加密,可直接从IPSW提取 提取方法:解压IPSW文件查找 kernelcache.release.* 文件 可使用 jtool2 或IDA Pro将其拆分为单独的kext文件进行分析 1.2 内核符号处理 iOS 12+移除了kernelcache符号 使用 jtool2 --analyze 可恢复约12000个符号 IDA 7.2+的Lumina功能也可用于获取符号 2. Mach IPC机制 2.1 Mach消息基础 Mach IPC是XNU内核的核心IPC机制,特点包括: 基于单向通信 通过端口(port)传递消息 端口权限类型: MACH_PORT_RIGHT_SEND :发送权限 MACH_PORT_RIGHT_RECEIVE :接收权限 MACH_PORT_RIGHT_SEND_ONCE :一次性发送权限 MACH_PORT_RIGHT_PORT_SET :端口集 MACH_PORT_RIGHT_DEAD_NAME :已销毁端口 2.2 Mach消息结构 消息类型: 简单消息:仅包含头部和主体 复杂消息:设置 msgh_bits 的复杂位,包含描述符 描述符类型: MACH_MSG_PORT_DESCRIPTOR :端口描述符 MACH_MSG_OOL_DESCRIPTOR :OOL(Out-of-line)数据 MACH_MSG_OOL_PORTS_DESCRIPTOR :OOL端口数组 MACH_MSG_OOL_VOLATILE_DESCRIPTOR :易失性数据 2.3 Mach API示例 创建端口: 发送消息: 接收消息: 3. MIG(Mach接口生成器) 3.1 MIG基础 自动生成Mach IPC的桩代码 基于 .defs 规范文件生成: *User.c :客户端代理代码 *Server.c :服务端桩代码 *.h :函数原型 3.2 示例:task.defs 4. 任务端口与内核任务 4.1 任务端口 任务的Mach抽象 相关API: task_for_pid() :获取任务端口(需特权) pid_for_task() :获取任务对应的PID host_get_special_port() :获取特殊端口 4.2 内核任务(tfp0) PID 0对应的任务 拥有内核任务端口意味着完全控制内核内存 传统获取方法: task_for_pid(0) (已被patch) processor_set_tasks() (macOS) 4.3 内存操作API 5. 漏洞利用技术 5.1 hsp4 patch 绕过内核任务指针检查的技术: 重新映射内核任务 写入未使用的特殊端口空间(realhost.special[ 4 ]) 调用 host_get_special_port(4) 获取可用内核任务 5.2 伪造任务端口 技术要点: 构造伪造的 ipc_port 结构体 设置 io_bits (包含 IO_BITS_ACTIVE ) 设置 io_references (非零) 设置 receiver 为内核 ipc_space 设置 kobject 为伪造的 task 结构体 5.3 pid_ for_ task()任意读 利用方法: 伪造任务端口指向目标内存-0x10(假设 p_pid 偏移为0x10) 调用 pid_for_task() 读取4字节 重复读取64位值 5.4 堆喷射技术 常用方法: 使用 MACH_MSG_OOL_PORTS_DESCRIPTOR 发送大量端口指针 触发 ipc_kmsg_copyin_ool_ports_descriptor 分配内存 利用zone垃圾回收特性 6. 安全机制 6.1 PAC(指针验证检查) ARM 8.3+特性 对指针进行加密签名 使用前验证签名有效性 防止伪造指针攻击 6.2 CoreTrust 内核扩展(com.apple.kext.CoreTrust) 加强代码签名验证 仅允许Apple签名二进制运行 与AMFI协同工作 7. 实用工具与资源 7.1 分析工具 jtool2 :Mach-O分析工具 IDA Pro/Hopper:反汇编工具 Binary Ninja:逆向工程平台 7.2 重要资源 XNU源码:opensource.apple.com Project Zero:https://bugs.chromium.org/p/project-zero theiphonewiki:设备与固件信息 8. 漏洞分析流程 获取目标版本kernelcache 使用工具恢复符号 逆向分析关键函数 查找潜在漏洞点 构建PoC验证漏洞 开发完整利用链 9. 后续研究方向 voucher_ swap漏洞 :MIG生成的代码中的引用计数漏洞 越狱开发 :逃逸沙盒、绕过CoreTrust、重挂载rootfs 新版本iOS安全机制 :研究最新防护措施及绕过方法 本教学文档涵盖了iOS内核安全与漏洞利用的基础知识,为后续深入分析特定漏洞和开发利用提供了必要理论基础。