吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 11673|回复: 15
收起左侧

[漏洞分析] 【OSG】macOS 10.12.2本地提权和XNU port堆风水

  [复制链接]
看雪iOS小组 发表于 2017-5-25 12:17
本帖最后由 看雪iOS小组 于 2017-5-25 12:21 编辑

原文作者:Vitaly Nikolenko译者:依然范特西 校对:布兜儿
原文链接:Local Privilege Escalation for macOS 10.12.2 and XNU port Feng Shui

首发看雪论坛:【OSG】macOS 10.12.2本地提权和XNU port堆风水


0x00 简介


从yalu 10.2 中,我们可以学到很多新的漏洞利用技术,特别是XNU堆风水和绕过内核保护。 在本文中,我们将讨论XNU堆风水的一些技术细节,并使用该技术在macOS中获得root权限。最后但同样重要的是,漏洞源码可以从以下网址下载:zhengmin1989/macOS-10.12.2-Exp-via-mach_voucher


0x01 内核堆溢出


为了使用XNU堆风水在macOS 10.12中获得root权限,我们需要一个内核漏洞。在本文中,我们选择mach_voucher堆溢出为例,Mach_voucher_extract_attr_recipe_trap() 是可以在沙箱内被调用的Mach陷阱。这是在iOS 10macOS 10.12中新添加的功能,但是它含有一个严重的缓冲区溢出漏洞。



在这个函数中,args->recipe_size是一个指向整数的用户态指针,所以mach_voucher_extract_attr_recipe_trap() 通过copyin() 从用户态拷贝size的值。



然后该函数使用sz值在内核堆上分配一个内存块。但是,开发人员忘记了args-> recipe_size是一个用户态指针,然后将其用做copyin() 中的 size 值。 我们知道用户态指针可能大于sz值,这将导致内核堆中的缓冲区溢出。请注意,如果我们要在该地址上分配一个内存块,我们可能无法控制用户态指针的地址。不过这不是问题。如果遇到未映射的内存,copyin() 函数会自动停止。 所以,我们可以在高地址上分配一个内存块,然后通过取消映射其余的内存块来控制溢出数据。




0x02 port进行堆风水

在iOS 10和macOS 10.12中,苹果添加了一个新的防护机制,用以检查在错误区域释放的攻击,因此我们无法使用经典的vm_map_copy(修改vm_map_size)技术来执行堆风水。另外,苹果在iOS 9.2和macOS 10.11中添加了一个空闲列表(freelist)随机化的机制,所以我们不能较容易地预测再分配的内存块的位置。 为了解决这些问题,我们需要一个新的堆风水技术。在Yalu 10.2中,qwertyoruiop使用OOL_PORTS来获取可用于执行任意内核内存读写的内核任务端口。 这种技术绕过了XNU堆中的所有防护机制。接下来,我们将讨论这种技术的细节。Mach msg是XNU中最常用的IPC机制,大量消息通过 “complicated message” 发送。通过MACH_MSG_OOL_PORTS_DESCRIPTOR msg_type的 ”complicated message”,我们可以向内核发送out-of-line端口。例如,我们发送了32个MACH_PORT_DEAD ool端口(32 * 8字节=0x100字节)到内核的kalloc.256区域。




保存在mach msg中的ool端口都是ipc_object类型的指针,这类指针可以指向用户态地址。 因此,我们可以使用mach_voucher漏洞来溢出这些指针,并在用户态下修改一个ipc_object指针,使它指向一个伪造的ipc_object。 另外,我们也可以在用户态下为假的端口创建假的任务




为了保证溢出正确的ipc_object指针,我们需要做一些堆风水操作。 首先,为了确保新分配的内存块是连续的,我们向内核发送大量的ool端口消息。 然后使用在中间收到的一些消息戳一些slots。 然后我们再次发送一些消息,使得溢出点在slots的中间部位。 最后,我们使用mach_voucher在溢出点触发堆溢出。




溢出之后,我们可以接收到剩余得 mach 消息,来找到被破坏的端口(不是MACH_PORT_DEAD 端口)。



0x03 内核内存任意读写


首先,我们将伪造的ipc_object的io_bits设置为IKOT_CLOCK。所以我们可以使用clock_sleep_trap() 通过遍历内核来获取内核中计时任务的地址。 这个地址将帮助我们稍后找到内核数据。




然后我们将伪造的ipc_object的io_bits设置为IKOT_TASK,为假的端口制造一个假的任务。 通过将值设置为faketask + 0x380(在arm64中为0x360),我们可以通过pid_for_task() 读取任意32位内核内存。这是因为该函数不检查任务的有效性,只返回(faketask + 0x380)+ 0x10)的值。 所以我们可以在没使用任何工具和ROP的情况下获得可造性内核读取。





通过计时任务泄露内核地址,我们可以在内存中搜索内核镜像的魔数,然后找到kslide。




获取内核基地址后,我们可以遍历所有进程来查找内核ipc_object和内核任务。然后我们可以dump出这些信息,给我们的伪造的ipc_object和任务。通过对假的ipc_object和任务使用task_get_special_port() ,我们可以获得内核任务端口。请注意,内核任务端口是非常强大的。它可以通过mach_vm_read()和mach_vm_write()进行任意内核内存读写。



0x04 root提权


每个进程的凭据信息,posix_cred结构,存储在内核内存中。首先我们需要找到我们的进程信息(通过内核基址+ allproc),然后找到我们的利用程序的posix_cred结构数据。 之后,我们通过kernel_task_port使用mach_vm_write() ,将cr_ruid(实际用户ID)值设置为0(也就是root)。最后,而且非常重要的是,我们可以使用system(“/ bin / bash”)获取root shell!



0x05 总结


在本文中,我们介绍了如何使用mach_voucher堆溢出和port堆风水来实现macOS 10.12.2上的本地提权。漏洞源码可以从下面的网址下载:https://github.com/zhengmin1989/macOS-10.12.2-Exp-via-mach_voucher

0x06 参考
  • Yalu 102: https://github.com/kpwn/yalu102
  • https://bugs.chromium.org/p/project-zero/issues/detail?id=1004

点评

图片盗链了,尽快修改一下。  发表于 2017-5-27 16:58

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
yyyz + 1 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

HIM411 发表于 2017-5-25 12:59
楼主,图片全挂了...
w2010d 发表于 2017-5-25 14:03
Hatsune_miku 发表于 2017-5-25 15:53
345718234 发表于 2017-5-25 20:15
图片全部挂了啊
小2b 发表于 2017-5-25 20:25
我从本篇学到加速乐,恩,很实用
kanxue2018 发表于 2017-6-3 16:37
可惜图全挂了!
bysysnet 发表于 2017-6-9 21:12
厉害了,楼主佩服。
头像被屏蔽
爱蜂玩爱疯玩 发表于 2017-11-8 15:02
提示: 作者被禁止或删除 内容自动屏蔽
ludog 发表于 2017-11-11 18:13
我也能看到图
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-18 22:09

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表