iOS冰与火之歌(番外篇) - 基于PEGASUS(Trident三叉戟)的OS X 10.11.6本地提权
iOS冰与火之歌(番外篇)
基于PEGASUS(Trident三叉戟)的OS X 10.11.6本地提权
蒸米@阿里移动安全
0x00 序
这段时间最火的漏洞当属阿联酋的人权活动人士被apt攻击所使用的iOS PEGASUS(又称Trident三叉戟)0day漏洞了。为了修复该漏洞,苹果专门发布了一个iOS 9.3.5版本。这个漏洞的厉害之处在于可以直接从沙盒内对内核进行攻击(无需沙盒逃逸),并且同时影响iOS(9.3.4)和OS X (10.11.6)。因此,本篇文章将会从PEGASUS漏洞形成的原因开始分析,然后一步一步教大家写出OS X上利用PEGASUS提权的攻击代码。
《iOS冰与火之歌》这一系列文章的目录如下:
1. Objective-C Pwn and iOS arm64 ROP
2. 在非越狱的iOS上进行App Hook(番外篇)
3. App Hook答疑以及iOS 9砸壳(番外篇)
4. 利用XPC过App沙盒
5. UAF and Kernel PWN
6. 基于PEGASUS(三叉戟)的OS X 10.11.6本地提权 (番外篇)
另外文中涉及代码可在我的github下载: https://github.com/zhengmin1989/iOS_ICE_AND_FIRE
0x01 漏洞分析
PEGASUS(三叉戟)实际上是由三个漏洞组成,分别是:
CVE-2016-4657:Safari的Webkit内核上的内存破坏漏洞。
CVE-2016-4655:内核信息泄露漏洞,可用于绕过KASLR。
CVE-2016-4656:内核UAF漏洞,可用于控制内核并执行任意代码。
关于CVE-2016-4657目前还没有公开的资料,但Stefan Esser和Pangu分别爆出了另外两个漏洞CVE-2016-4655和CVE-2016-4656的细节。利用已经曝光的这两个漏洞,其实已经可以做到iOS非完美越狱和OS X本地提权了。下面我们就来讲解一下这两个漏洞形成的原因以及如何利用。
0x02 CVE-2016-4655 内核信息泄露
CVE-2016-4655这个漏洞形成的原因是内核在序列化和反序列化OSNumber的时候没有验证长度的正确性。因此,如果我们将number的长度设置的非常长,并用io_registry_entry_get_property()去获取number数据的话,就会造成内核的信息泄露。

我们知道内核栈中会保存函数的返回地址,因此我们可以利用这个返回地址去计算出内核的kslide,从而攻破kaslr的保护。
那么如何编写利用代码呢?我们先创建一个序列化后的dictionary。对内核来说,这个dictionary应该是这样的:
<dict> <key>min</key> <number>0x4141414141414141</number> </dict>
但是我们对OSNumber的长度进行了修改,变成了0x200:
uint32_t data[] = {
0x000000d3,
0x81000001,
0x08000004, 0x006e696d,
0x84000200, //change the length of OSNumber
0x41414141, 0x41414141
};
发送这个给内核后,内核在反序列化的时候就会出现错误。随后我们使用io_registry_entry_get_property_bytes()这个用户态函数就可以获取到内核返回的数据了。

因为我们修改了OS number的长度,所以返回的数据不光有我们发送给内核的number,还有栈上数据,比如函数ret时候的返回地址-0xFFFFFF80003934BF。

通过这个地址我们就可以计算出来kslide了。
0x03 CVE-2016-4656 内核代码执行
CVE-2016-4656这个漏洞其实有两种触发UAF的方法,我们这里先讲比较简单的那一种(两种方法在Stefan Esser的文章中都有介绍)。简单UAF漏洞形成的原因是OSUnserializeBinary支持用OSString和OSSymbol来作为key,并且支持用OSObject去引用之前的key。但是OSString和OSSymbol不一样的地方在于,OSString key转换为OSSymbol的过程中OSString已经被free掉了,但这个OSString却被加入了对象列表里。

因此当我们OSObject类型去引用一个已经被释放了的OSString的时候,就会产生UAF崩溃:

通过汇编崩溃的位置我们可以找到源码对应的位置是在341行创建OSObject对象的时候:

因此,如果我们能够在OSString被free的时候,立刻申请一段和OSString一样大小的内存并且构造好对应的vtable数据,当程序执行到OSObject创建的时候,内核就能成功的被我们控制。
那么如何编写利用代码呢?我们还是先创建一个序列化后的dictionary。对内核来说,这个dictionary应该是这样的:
<dict> <string>A</string> <bool>true</bool> <key>B</key> <data>vtable data...</data> <object>1</object> </dict>
内核随后会解析这个dictionary,正如我们之前分析的,OSString-”A”在创建完后就被free掉了,这时候,我们立刻创建OSSymbol-”B”以及和OSString-”A”大小相同的OSData,就可以在OSString-”A” free后重新控制这块内存,随后当内核使用OSObject引用OSString-”A”,并调用retain()函数的时候,其实就是在调用我们已经控制的vtable了。
0x04 利用ROP提权
首先我们先申请一块内存来放vtable和ROP chain,在OS X上有一种取巧的方法,如果我们是32位的程序的话,可以使用NULL page。因此,我们先用vm_allocate()申请到NULL Page,然后将vtable和ROP chain都保存在NULL page里:

随后在OS X上用rop提权的代码我们可以直接使用tpwn的:首先获得当前进程的ucred,然后将cr_svuid设置为0,最后用thread_exception_return退出进程。

0x05 测试EXP
编写完代码后,我们来尝试执行一下我们的exp。
首先说一下测试环境:Mac OS X EI Capitan 10.11.6 (15G31),在没有安装2016-01的security update的情况下(这时候内核相当于iOS 9.3.4,如果安装完2016-01 update就相当于iOS 9.3.5)。

接下来我们编译一下我们的exp:
clang -framework IOKit -framework Foundation -framework CoreFoundation -m32 -Wl,-pagezero_size,0 -O3 exp.m lsym.m -o exp
然后运行:

可以看到我们已经成功的获取了root权限。
0x06 总结
这篇文章介绍了如何利用PEGASUS(Trident三叉戟)做到内核信息泄露以及内核代码执行,然后利用rop获取root权限。另外,因为PEGASUS(Trident三叉戟)同时存在于iOS和OS X,有兴趣的同学可以在我们发布的攻击代码的基础上,尝试一下iOS攻击代码的编写。
基于PEGASUS(Trident三叉戟)的OS X 10.11.6本地提权exp的下载地址:https://github.com/zhengmin1989/OS-X-10.11.6-Exp-via-PEGASUS
0x07 参考资料
1. http://blog.pangu.io/cve-2016-4655/
2. https://sektioneins.de/en/blog/16-09-02-pegasus-ios-kernel-vulnerability-explained.html
3. https://bazad.github.io/2016/05/mac-os-x-use-after-free/
4. https://github.com/kpwn/tpwn
作者:蒸米@阿里移动安全,更多安全类技术文章,请访问阿里聚安全博客
iOS冰与火之歌(番外篇) - 基于PEGASUS(Trident三叉戟)的OS X 10.11.6本地提权的更多相关文章
- 《手把手教你》系列技巧篇(三十一)-java+ selenium自动化测试- Actions的相关操作-番外篇(详解教程)
1.简介 上一篇中,宏哥说的宏哥在最后提到网站的反爬虫机制,那么宏哥在自己本地做一个网页,没有那个反爬虫的机制,谷歌浏览器是不是就可以验证成功了,宏哥就想验证一下自己想法,于是写了这一篇文章,另外也是 ...
- 《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)
1.简介 前边几篇文章是宏哥自己在本地弄了一个单选和多选的demo,然后又找了网上相关联的例子给小伙伴或童鞋们演示了一下如何自动化测试,这一篇宏哥在网上找了一个问卷调查,给小伙伴或童鞋们来演示一下.上 ...
- 给深度学习入门者的Python快速教程 - 番外篇之Python-OpenCV
这次博客园的排版彻底残了..高清版请移步: https://zhuanlan.zhihu.com/p/24425116 本篇是前面两篇教程: 给深度学习入门者的Python快速教程 - 基础篇 给深度 ...
- [置顶] think in java interview番外篇-谈程序员如何修练英语
一.程序员对英语能力的重视度和能力要求应该是在各行各业中排在比较靠前的 这样说吧,英语程度的好坏直接影响着一个程序员的编程.开发.创新能力. 道理很简单: 1. 计算机和软件是用英语创造出来的 2. ...
- 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
- 可视化(番外篇)——在Eclipse RCP中玩转OpenGL
最近在看有关Eclipse RCP方面的东西,鉴于Gephi是使用opengl作为绘图引擎,所以,萌生了在Eclipse RCP下添加画布,使用opengl绘图的想法,网上有博文详细介绍这方面的内容, ...
- 可视化(番外篇)——SWT总结
本篇主要介绍如何在SWT下构建一个应用,如何安装SWT Designer并破解已进行SWT的可视化编程,Display以及Shell为何物.有何用,SWT中的常用组件.面板容器以及事件模型等. 1.可 ...
- 【重走Android之路】【番外篇】关于==和equals
[重走Android之路][番外篇]关于==和equals 在实际的编程当中,经常会使用==和equals来判断变量是否相同.但是这两种比较方式也常常让人搞得云里雾里摸不着头脑.下面是我个人做的总 ...
- 【重走Android之路】【番外篇】有关于null的一些知识点
[重走Android之路][番外篇]有关于null的一些知识点 1.首先,到底什么是null? null是Java中的一个关键字,用于表示一个空对象引用,但其本身并不是任何类型也不是属于任何对象. ...
随机推荐
- SQL必备知识点
经典SQL语句大全 基础 1.说明:创建数据库.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份数据的 device.说明:创建新表crea ...
- Android Ormlite 学习笔记2 -- 主外键关系
以上一篇为例子,进行主外键的查询 定义Users.java 和 Role.java Users -- Role 关系为:1对1 即父表关系 Role -- Users 关系为:1对多 即子表关系 下面 ...
- 关于Layer弹出框初探
layer至今仍作为layui的代表作,她的受众广泛并非偶然,而是这五年多的坚持,不断完善和维护.不断建设和提升社区服务,使得猿们纷纷自发传播,乃至于成为今天的Layui最强劲的源动力.目前,laye ...
- 如何避免git每次提交都输入密码
在ubuntu系统中,如何避免git每次提交都输入用户名和密码?操作步聚如下:1: cd 回车: 进入当前用户目录下:2: vim .git-credentials (如果没有安装vim 用其它编辑器 ...
- OpenCV人脸识别Eigen算法源码分析
1 理论基础 学习Eigen人脸识别算法需要了解一下它用到的几个理论基础,现总结如下: 1.1 协方差矩阵 首先需要了解一下公式: 共公式可以看出:均值描述的是样本集合的平均值,而标准差描述的则是样本 ...
- 【Machine Learning】Python开发工具:Anaconda+Sublime
Python开发工具:Anaconda+Sublime 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现 ...
- 菜鸟Python学习笔记第二天:关于Python黑客。
2016年1月5日 星期四 天气:还好 一直不知道自己为什么要去学Python,其实Python能做到的Java都可以做到,Python有的有点Java也有,而且Java还是必修课,可是就是不愿意去学 ...
- 快速了解微信小程序的使用,一个根据小程序的框架开发的todos app
微信官方已经开放微信小程序的官方文档和开发者工具.前两天都是在看相关的新闻来了解小程序该如何开发,这两天官方的文档出来之后,赶紧翻看了几眼,重点了解了一下文档中框架与组件这两个部分,然后根据简易教程, ...
- WebApi返回Json格式字符串
WebApi返回json格式字符串, 在网上能找到好几种方法, 其中有三种普遍的方法, 但是感觉都不怎么好. 先贴一下, 网上给的常用方法吧. 方法一:(改配置法) 找到Global.asax文件,在 ...
- LINQ to SQL Where条件
1. 适用场景 实现条件的过滤和查询等功能. 2. 说明 跟SQL语句中的where作用相似,都起到了范围的限定即过滤的作用,而判断条件是紧跟后面的条件子句.where主要分为三种形式:简单形式.条件 ...