欢迎来到 无奈人生 安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

深入XPC:逆向分析XPC对象

来源:未知 作者:wnhack 时间:2019-01-08 14:26 点击: 我要投稿
广告位API接口通信错误,查看德得广告获取帮助
一、前言
最近我在FortiGuard实验室一直在深入研究macOS系统安全,主要关注的是发现和分析IPC漏洞方面内容。在本文中,我将与大家分享XPC内部数据类型,可以帮助研究人员(包括我自己)快速分析XPC漏洞根源,也能深入分析针对这些漏洞的利用技术。
XPC是macOS/iOS系统上使用的增强型IPC框架,自10.7/5.0版引入以来,XPC的使用范围已经呈爆炸式增长。XPC依然包含没有官方说明文档的大量功能,具体实现也没有公开(例如,libxpc这个主工程为闭源项目)。XPC在两个层面上开放API:底层以及Foundation封装层。在本文中我们只关注底层API,这些API为libxpc.dylib直接导出的xpc_*函数。
这些API可以分为object API以及transport API。XPC通过libxpc.dylib提供自己的数据类型,具体数据类型如下所示:

图1. XPC提供的数据类型
从C API角度来看,所有的对象实际上都是xpc_object_t。实际类型可以通过xpc_get_type(xpc_object_t)函数动态确定。所有数据类型可以使用对应的xpc_objectType_create函数创建,并且所有这些函数都会调用_xpc_base_create(Class, Size)函数,其中Size参数指定了对象的大小,而Class参数为某个_OS_xpc_type_*元类(metaclass)。
我们可以通过Hopper Disassembler v4看到 _xpc_base_create函数被多次引用。

图2. 对_xpc_base_create函数的引用代码
我开发了Hopper的一个python脚本,可以自动找出调用_xpc_base_create函数时所使用的具体参数。如下python脚本可以显示Hopper Disassembler中XPC对象的大小。
def get_last2instructions_addr(seg, x):
                  last1ins_addr = seg.getInstructionStart(x - 1)
                  last2ins_addr = seg.getInstructionStart(last1ins_addr - 1)
                  last2ins = seg.getInstructionAtAddress(last2ins_addr)
                  last1ins = seg.getInstructionAtAddress(last1ins_addr)
                  print hex(last2ins_addr), last2ins.getInstructionString(), last2ins.getRawArgument(0), last2ins.getRawArgument(1)
                  print hex(last1ins_addr), last1ins.getInstructionString(), last1ins.getRawArgument(0), last1ins.getRawArgument(1)
                  return last2ins,last1ins
def run():
                  print '[*] Demonstrating XPC ojbect sizes using a hopper diassembler's python script'
                  xpc_object_sizes_dict = dict()
                  doc = Document.getCurrentDocument()
                  _xpc_base_create_addr = doc.getAddressForName('__xpc_base_create')
                  for i in range(doc.getSegmentCount()):
                                    seg = doc.getSegment(i)
                                    #print '[*]'+ seg.getName()
                                    if('__TEXT' == seg.getName()):
                                                      eachxrefs = seg.getReferencesOfAddress(_xpc_base_create_addr)
                                                      for x in eachxrefs: 一、前言
最近我在FortiGuard实验室一直在深入研究macOS系统安全,主要关注的是发现和分析IPC漏洞方面内容。在本文中,我将与大家分享XPC内部数据类型,可以帮助研究人员(包括我自己)快速分析XPC漏洞根源,也能深入分析针对这些漏洞的利用技术。
XPC是macOS/iOS系统上使用的增强型IPC框架,自10.7/5.0版引入以来,XPC的使用范围已经呈爆炸式增长。XPC依然包含没有官方说明文档的大量功能,具体实现也没有公开(例如,libxpc这个主工程为闭源项目)。XPC在两个层面上开放API:底层以及Foundation封装层。在本文中我们只关注底层API,这些API为libxpc.dylib直接导出的xpc_*函数。 copyright 无奈人生
这些API可以分为object API以及transport API。XPC通过libxpc.dylib提供自己的数据类型,具体数据类型如下所示:

图1. XPC提供的数据类型
从C API角度来看,所有的对象实际上都是xpc_object_t。实际类型可以通过xpc_get_type(xpc_object_t)函数动态确定。所有数据类型可以使用对应的xpc_objectType_create函数创建,并且所有这些函数都会调用_xpc_base_create(Class, Size)函数,其中Size参数指定了对象的大小,而Class参数为某个_OS_xpc_type_*元类(metaclass)。 本文来自无奈人生安全网
我们可以通过Hopper Disassembler v4看到 _xpc_base_create函数被多次引用。

图2. 对_xpc_base_create函数的引用代码
我开发了Hopper的一个python脚本,可以自动找出调用_xpc_base_create函数时所使用的具体参数。如下python脚本可以显示Hopper Disassembler中XPC对象的大小。 copyright 无奈人生
def get_last2instructions_addr(seg, x):
                  last1ins_addr = seg.getInstructionStart(x - 1)
                  last2ins_addr = seg.getInstructionStart(last1ins_addr - 1)
                  last2ins = seg.getInstructionAtAddress(last2ins_addr)
www.wnhack.com

                  last1ins = seg.getInstructionAtAddress(last1ins_addr)
                  print hex(last2ins_addr), last2ins.getInstructionString(), last2ins.getRawArgument(0), last2ins.getRawArgument(1)
                  print hex(last1ins_addr), last1ins.getInstructionString(), last1ins.getRawArgument(0), last1ins.getRawArgument(1) 本文来自无奈人生安全网
                  return last2ins,last1ins
def run():
                  print '[*] Demonstrating XPC ojbect sizes using a hopper diassembler's python script'
                  xpc_object_sizes_dict = dict() 内容来自无奈安全网
                  doc = Document.getCurrentDocument()
                  _xpc_base_create_addr = doc.getAddressForName('__xpc_base_create')
                  for i in range(doc.getSegmentCount()):
内容来自无奈安全网

                                    seg = doc.getSegment(i)
                                    #print '[*]'+ seg.getName()
                                    if('__TEXT' == seg.getName()):

copyright 无奈人生


                                                      eachxrefs = seg.getReferencesOfAddress(_xpc_base_create_addr)
                                                      for x in eachxrefs:。 (责任编辑:wnhack)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。