0x00 序
Ian Beer@google发布了CVE-2017-7047Triple_Fetch的exp和writeup[1],chenliang@keenlab也发表了关于Triple_Fetch的分析[2],但因为这个漏洞和exp有很是多的亮点,因此还剩不少能够深刻挖掘的细节。所以,咱们简单分析一下漏洞造成的缘由,并具体介绍一下漏洞利用的细节,以及如何利用这个漏洞作到iOS 10.3.2上的沙盒逃逸。html
0x01 CVE-2017-7047 Triple_Fetch漏洞造成的缘由spring
由于chenliang对漏洞成因的分析很是详细,这里我就简单描述一下,由于使用XPC服务传输大块内存的话很影响效率,苹果为了减小传输时间,对大于0x4000的OS_xpc_data数据会经过mach_vm_map的方式映射这块内存,而后将这块数据的send right以port的方式发送到另外一方。但这段内存的共享是基于共享物理页的方式,也就是说发送方和接收方会共享同一块内存,所以咱们将数据发送之后再在发送端对数据进行修改,接收方的数据也会发生变化。安全
所以经过race condition,可让接收端获得不一样的数据(接收端认为是相同的数据),若是接收端没有考虑到这一点的话就可能会出现漏洞。好比咱们刚开始让接收端获取的字符串是@”ABCD”(包括@和”),那么接收端会为这个字符串分配7个字节的空间。随后在进行字符串拷贝的时候,咱们将字符串变为@"ABCDOVERFLOW_OVERFLOW_OVERFLOW",接收端会一直拷贝到遇到”符号为止,这样就形成了溢出。服务器
Triple_Fetch攻击所选择的函数是CoreFoundation里的___NSMS1()函数,这个函数会对咱们构造的恶意字符串进行屡次读取操做,若是在读取的间隙快速对字符串进行三次修改,就会让函数读取到不一样的字符串,让函数产生判断失误,从而形成溢出并让咱们控制pc,这也是为何把这个漏洞称为Triple_Fetch的缘由。下图就是攻击所使用的三组不一样的字符串:并发
攻击所选择的NSXPC服务是“com.apple.CoreAuthentication.daemon”。对应的二进制文件是/System/Library/Frameworks/LocalAuthentication.framework/Support/coreauthd。缘由是这个进程是root权限而且能够调用processor_set_tasks() API从而获取系统其余进程的send right[3]。下图是控制了pc后的crash report:app
0x02 Triple_FetchJOP &ROP&任意代码执行
利用漏洞Triple_Fetch虽然能够控制pc,可是还不能控制栈,因此须要先作stack_pivot,好消息是x0寄存器指向的xpc_uuid对象是咱们能够控制的:函数
所以咱们能够利用JOP跳转到_longjmp函数做为来进行stack pivot,从而控制stack:post
最终发送的用来作JOP的格式伪造的xpc_uuid对象以下:ui
控制了stack就能够很容易的写rop了。可是beer目标不只仅是执行rop,它还但愿获取目标进程的task port而且执行任意二进制文件,所以除了exp,攻击端还用mach msg发送了0x1000个带有send right的port到目标进程中:google
这些port的mach msg在内存中的位置和内容以下(msgh_id都为0x12344321):
随后,exp采用rop的方法对这些port进行遍历而且发送回发送端:
随后,攻击端会接收mach msg,若是获取到的msgh_id为0x12344321的消息,说明咱们成果获得了目标进程的task port:
获得了task_port后,sploit()函数就结束了,开始进入do_post_exploit()。do_post_exploit()也作了很是多的事情,首先是利用coreauthd的task port以及processor_set_tasks()获取全部进程的task port。这是怎么作到的呢?
利用coreauthd的task port咱们能够利用mach_vm_* API任意的修改coreauthd的内存以及寄存器,因此咱们须要先开辟一段内存做为stack,而后将sp指向这段内存,再将pc指向咱们想要执行的函数地址就可让目标进程执行任意的函数了,具体实如今call_remote()中:
随后咱们控制coreauthd依次执行task_get_special_port(), processor_set_default(), host_processor_set_priv(),processor_set_tasks()等函数,来得到全部进程的task port并返回给攻击端(具体实如今get_task_ports())中。接着,攻击端会遍历这个列表并筛选出amfid,launchd,installd,springboard这四个进程的task port。而后利用以前patch amfid的技巧,对amfid打补丁。最后再启动debugserver。
其实这个exp不但能够执行debugserver,还能够用来在沙盒外执行任意的二进制文件。只要把pocs文件夹下的hello_world二进制文件替换成你本身的想要执行的二进制文件,编译安装后,点击ui中的exec bundle binary便可:
具体怎么作到的呢?秘密在spawn_bundle_binary()函数中,先在目标进程中调用chmod将bin改成0777,而后经过一系列的posix_spawn API(相似fork())在目标进程中执行该bin文件。
沙盒外的代码执行提供了更多能够攻击内核的接口。而且能够读取甚至修改其余应用或者系统上的文件。好比,漏洞能够读取一些我的隐私数据(好比,短信,聊天记录和照片等)并发送到黑客的服务器上:
因此建议你们早日更新iOS系统到最新版本。
0x03 总结
本文介绍了beer发现的通用NSXPC漏洞。另外,还分析了iOS用户态上,用JOP作stack pivot以及利用ROP作到任意代码执行的攻击技术。固然,这些漏洞只是作到了沙盒外的代码执行,想要控制内核还须要一个或两个XNU或者IOKit的漏洞才行,而且苹果已经修复了yalu102越狱用的kpp绕过方法,所以,即便有了Triple_Fetch漏洞,离完成所有越狱还有很大一段距离。
0x04 参考文献
一、https://bugs.chromium.org/p/p...
二、http://keenlab.tencent.com/zh...
三、http://newosxbook.com/article...
* 做者:蒸米,更多安全知识分享和热点信息,请关注阿里聚安全的官方博客