thirdkit是什么软件?

这个漏洞利用链适用于iOS 12 – 12.1版本,当我们在野外发现漏洞利用链时,这两个漏洞均没有官方补丁发布。于是我们向Apple报告了这两个漏洞情况,在7天之后,iOS发布了12.1.4的更新版本。

这里的沙箱逃逸漏洞再次涉及到XPC,但这次是一个特定的守护进程错误地管理了XPC对象的生命周期。

遗憾的是,这里用到的内核漏洞非常容易被发现和被利用。带有外部方法的IOKit设备驱动程序,在第一个语句中执行包含由攻击者直接控制的长度参数的无边界memmove:

其中,struct_in缓冲区的内容完全由攻击者控制。

与iOS漏洞利用链#3类似,我们的测试和验证过程似乎已经能够确定这个漏洞利用链。

在本系列最后的详细介绍中,我们将了解攻击者如何利用这些漏洞来安装他们的植入工具并监视用户,以及这些恶意工具所包含的实时监控功能。

与iOS漏洞利用链#3一样,这个权限提升的二进制文件不依赖于系统Mach-O加载程序来解析依赖关系,而是在执行开始时解析符号。

在这里,会终止在此任务中运行的所有其他线程,然后检查其先前的漏洞利用标记。以前我们已经发现攻击者在bootargs sysctl中添加了一个字符串。而这次,他们使用了新的技术:

如果kern.maxfilesperproc的值为0x27ff,则认为此设备已被攻陷,该漏洞利用过程将停止。##再次涉及到XPC

与iOS漏洞利用链#3一样,这一条漏洞利用链具有单独的沙箱逃逸和内核漏洞利用。沙箱逃逸再次涉及到XPC,但这次不是核心XPC代码,而是守护进程错误地使用了XPC API。

XPC中的对象生存周期管理

XPC有非常详细的使用手册,涵盖了XPC对象的生命周期语义。下面是关于$ man xpc_objects的使用方法节选:

1、由XPC框架中的创建函数返回的对象可以分别使用函数xpc_retain()和xpc_release()统一保留和释放。

2、XPC框架不保证任何指定的客户端具有对指定对象的最终或唯一引用。对象可以由系统内部保留。

3、返回对象的函数遵循传统的create、copy和get命名规则:

(1)create返回一个带有单个引用的新对象。该引用应由调用方释放。

(2)copy返回复制或保留的对象引用。该引用应由调用方释放。

(3)get返回对现有对象的未保留引用。调用方不应释放该引用,并且如有必要,应负责保留该对象以备后续使用。

XPC对象是由引用计数。xpc_retain可以被调用以手动获取引用,并且可以使用xpc_release来删除引用。名称中带有copy的所有XPC函数都会返回一个对象,该对象具有对调用方的额外引用,而名称中带有get的XPC函数不返回额外的引用。使用手册告诉我们,如果我们调用名称中带有get的XPC函数,那么会返回对现有对象的未保留引用,且调用方无法释放该引用。接下来,我们看一个完全符合上述情况的代码案例。

com.apple.cfprefsd.daemon是由cfprefsd守护程序托管的XPC服务。该守护程序未处在沙箱之中,并且是以root身份运行,可以从应用程序沙箱和WebContent沙箱直接访问。

该块为每个连接创建一个新的串行调度队列,并为连接上每个传入消息提供一个块。

multiMessage处理程序期望输入消息是xpcdictionary对象的xpc_array,它将是要处理的子消息。它使用xpc_array_get_value,将内容从xpc_array中pull出,并将其传递给handleMessage方法,使用的是另一个replyHandler块。在这里,并没有立即将回复消息发送回客户端,而是覆盖sub_messages中的输入子消息指针数组与回复。在处理完所有的子消息后,会从所有回复中创建一个xpc_array,并调用传递给此函数的replyHandler,并传递包含子消息回复的xpc_array的回复消息。

这里的漏洞有点微妙。如果我们想象没有multiMessage,那么传递给每个消息处理程序地replyHandler块的语义是:“调用我,可以发送回复”,因此名称为“replyHandler”。例如,消息类型3由handleFlushManagedMessage处理,它调用replyHandler块以返回回复。

但是,并非所有的消息类型都希望发送回复。可以把它们想象成C中的void函数,它们不会返回值。正因如此,它们也同样不会发送回复消息。这意味着它们不会调用replyHandler块。那么,如果没有回复要发送,为什么还要调用名为replyHandler的块呢?

但是正如我们所看到的,无法保证将会调用replyHandler块。事实上,一些消息处理程序只是NOP,并且什么都不做。

这成为了一个问题,因为multiMessage replyHandler块更改了存储在sub_messages数组中的指针的生命周期语义。初始化sub_messages数组时,它存储由xpcget方法返回的原始未保留指针:

xpc_array_get_value返回xpc_array中指定偏移量处的原始指针。它不会返回包含新引用的指针。因此,在消息xpc_array的生命周期之外使用该指针是无效的。然后,replyHandler块重用sub_messages数组来存储对每个子消息的回复,但这次它需要对它存储在其中的回复对象进行引用:

在处理完所有sub_messages后,会尝试释放所有回复:

与iOS漏洞利用链#3一样,攻击者在这里也选择了堆喷射和端口喷射技术。但是,他们没有使用资源泄露的原语,而是在XPC触发器消息本身中发送所有内容。

攻击者通过使用并行运行的四个线程来完成此操作。线程A、B和C启动并等待全局变量设置为1。当发生这种情况时,它们各自尝试100次将以下XPC消息发送到服务:

其中xpc_data_spray是一个448字节的xpc_data缓冲区,填充qword值0x。这是他们尝试堆喷射的目标地址。他们希望其中一个xpc_data的448字节后备缓冲区的内容与释放后的xpc_dictionary重叠,用堆喷射地址完全填充内存。

该漏洞将由子消息触发,其中操作键被映射到不会调用其回复块的处理程序。攻击者选择了操作4,由handleFlushSourceForDomainMessage处理。触发器消息如下所示:

其中,子消息字典如下:

在4k设备上,堆喷射的xpc_data对象大约为25MB,在具有更多RAM空间的16k设备上大约为30MB。攻击者将其中的16个放入消息中,在4k以及500MB的16k设备上,将导致400MB喷射虚拟地址空间。

xpc_release实际上做了什么呢?Objective-C对象的第一个qword是它的isa指针。这是一个指向类对象的指针,它定义了对象的类型。在xpc_release中,他们检查libxpc的__objc_data部分中是否有isa点。如果存在,则调用os_object_release。由于攻击者提供了一个虚假的isa指针(值为0x),因此将会调用另一个分支,也就是调用objc_release。如果类对象的位字段中的FAST_ALLOC位被清零(移量为0x20的字节中的第2位),就会导致释放选择器被发送到对象,将会发生下面的情况。

构建一个虚假的Objective-C对象,以便在选择器被发送到它时获得PC控制,这是一种已知的技术。obj_msgSend是负责处理选择器调用的本机函数。它将首先跟随指向类对象的isa指针,然后跟随+ 0x10处的指针到选择器缓存结构,该结构是(function_pointer, selector)对的一个数组。如果目标选择器与缓存中的条目匹配,就会调用缓存的函数指针。

在攻击者获得PC控制时,X0指向释放后的xpc_dictionary对象。在上一个也具有沙箱逃逸的利用链中,攻击者通过JOP到longjmp,可以很容易地获取栈。在iOS 12中,Apple在使用PAC的A12设备、A11设备和没有使用PAC的早期设备上加固了longjmp。攻击者的漏洞利用不支持这些设备。

我们在iOS 11中查看了用于iOS漏洞利用链#3沙箱逃逸的longjmp。iOS 12中A11及以下版本的添加是从线程本地存储区读取键值,并用于对LR、SP和FP寄存器进行异或。

这是从TPIDRRO_EL0系统寄存器(只读软件线程ID寄存器)读取,XNU指向用户控件线程本地存储区域。键值通过main的特定apple[]参数传递给exec上的新进程,在exec期间生成:

从根本上来说,在iOS漏洞利用链#3中使用的longjmp只是一种技术,对于漏洞利用链来说并不是什么基础。longjmp只是一种非常方便的方式来转动栈,并获得完整的寄存器控制。我们来看看攻击者是如何在没有使用longjmp的情况下转动栈的:

gadget_3将X8和X1存储到实际堆栈中,创建一个虚假栈帧,其中包含已保存帧指针(0x)和受控返回地址(gadget_4_addr)的受控值。然后跳转到gadget_4+4:

该过程将从实际栈中加载帧指针和链接寄存器,具体是从刚刚写入受控值的地址实现加载。这就使得攻击者可以任意控制帧指针和链接寄存器。RET会跳转到链接寄存器中的值,即gadget_4:

这会将其受控帧指针移动到栈指针寄存器中,从那里加载帧指针和链接寄存器的新值,并将RET转换为gadget_5,然后成功转动到受控栈指针中。此处的ROP栈与PE3的沙箱逃逸栈非常相似,他们使用相同的LOAD_ARGS小工具,在想要调用的每个目标函数之前加载X0-X7:

除此之外,还使用相同的memory_write小工具:

mach端口发送权限。攻击者使用内存写入小工具将该端口名称写入他们连续发送的四个exfil消息。在WebContent进程中,在端口集上侦听消息。如果收到该消息,则会在其中发送一个ProvInfoIOKitUserClient。

IOKit外部方法类似于系统调用。这个参数在这个边界是不可信的。该外部方法中的第一个语句是一个memmove操作,具有一个简单的、由用户控制的长度参数。

内核漏洞利用的开始通常都是相同的:获取设备正确的内核偏移量,并创建一个IOSurfaceRootUserClient以附加任意OSObject。攻击者分配了0x800管道(首先增加打开文件限制)和1024个早期端口。

然后,分配了768个端口,分成四组,如下所示:

然后是另外五个独立的端口:

在这里,分配了10240个before_ports、target_port和5120个after_ports。这也是我们在之前的链中看到的副本。初看上去,似乎正在设置一个指向target_port的悬空指针,将区域转移到kalloc.4096并构建一个虚假的内核任务端口。

随后,他们发送了一个更加复杂的kalloc_groomer,它将进行1024次kalloc.4096分配,然后进行1024次kalloc.6144分配。这填补了这两个区域的空白。

在该过程中,希望可以交替使用一个空的kalloc.4096。这样一来,就得到了一个看起来类似于下面的kalloc.4096:

其中,P是具有上述布局的外联端口描述符,K是来自外联内存描述符的空kalloc.4096。

然后它们交替另外96次,首先针对4104字节OSData对象,反序列化填充了ASCII “1”,同时还对一个4104字节的kalloc groomer进行反序列化。上述两个都将导致kalloc.6144的分配,因为这是kalloc.4096之后的下一个规格:

这样一来,布局空间就有所改变,其中OSData后备缓冲区与kalloc.6144中空的外联内存描述符大致交替。

目前,已经破坏了kalloc.4096的中间部分,希望在一些外部端口描述符之间留出空白:

同样,攻击者会破坏kalloc.6144外联内存描述符的一半:

他们通过一个复杂的kallocer重新分配了他们刚刚释放的一半数量的24个分配,然后触发溢出:

要了解这里发生了什么,我们需要更加仔细地查看外部方法调用的工作原理:

IOConnectCallMethod是一个更复杂的包装器,它根据传递的参数选择正确的内核MIG函数进行调用。具体而言,这里是io_connect_method:

在device.defs上运行MIG工具将生成序列化和反序列化C代码,用户空间和内核用于实现RPC的客户端和服务器部分。这是作为XNU构建过程的一部分发生的。

MIG方法的第一个参数是一个mach端口,这是序列化消息将会被发送到的端口。

在ipc_kmsg.c中的mach消息发送路径中,进行了以下检查:

如果将mach消息发送到ip_receiver字段设置为ipc_space_kernel的端口,则不会排进接收端口的消息队列。相反,发送路径被“短路”,并且消息被假设为内核的MIG序列化RPC请求,由ipc_kobject_server同步处理:

该函数在包含所有内核MIG子系统的表中查找消息的msgh_id字段,不仅是来自devices.defs的子系统,还包括任务端口、线程端口、主机端口等方法。

从该表中读取最大回复消息大小(在MIG中是静态的)并分配适当大小的回复ipc_kmsg结构。有关ipc_kmsg结构的更多详细信息,请参阅几年前发表的一篇关于如何借助它实现漏洞利用的文章。

由于请求和回复消息都将使用带内结构缓冲区,因此传递给外部方法的输入和输出结构缓冲区将直接指向请求并回复ipc_kmsg结构。 回想一下之前的Heap Grooming过程,最终会得到以下布局:

这是触发漏洞时的设置,这里的目标是公开目标端口的地址。如果Groom过程成功,那么外部方法中的坏memmove将从位于请求消息之后的外部端口描述符复制到回复ipc_kmsg结构之后的OSData对象后备缓冲区中。

在触发漏洞之后,依次读取每个喷射的OSData对象,检查它们现在是否包含看起来像内核指针的内容:

如果成功,那么证明已经暴露了target_port ipc_port结构的内核地址。正如我们在之前的利用链中所看到的,这是他们伪造内核端口技术的先决条件之一。

接下来,开始第二次触发漏洞。这一次,使用了另外一个复杂的kalloc groomer来填充kalloc.4096和kalloc.6144中的小孔,然后在这两个区域中再执行两次Heap Groom。

在将在kalloc.4096外联内存描述符中发送的缓冲区中,写入两个值:

邻近的端口内核地址将在后面出现,除非后面的端口开启了一个4k的页面,在这种情况下会出现在前面。

这里的C和A都包含具有所暴露的端口地址的外联内存描述符缓冲器。

攻击者在kalloc.6144中创建了一个类似的Groom,在一个带有0x201条目的外联端口描述符之间交替,所有这些都是MACH_PORT_NULL,以及一个外联内存描述符缓冲区:

外联端口描述符从ports_b数组发送到端口,外联存储器描述符从ports_d发送到端口。

随后,将销毁那些中间端口的中间一半(中间的C和D),并回收一半被释放的部分,希望能实现下面的堆布局:

接下来,第二次触发堆溢出:

这里的思路是,读取包含两个端口指针的kalloc.4096外联内存描述符缓冲区的边界,然后在回复消息的末尾写入超出范围的这些值,其中一个位于B外联端口描述符。这样一来,其中一个外联端口描述符被破坏,能具有从未获取引用的引用悬空指针。

与前面的攻击链不同,这里不会继续销毁损坏的外部端口描述符。相反,他们将发送权限销毁为target_port(已将额外端口指针写入外部端口描述符的端口)。这意味着,外部端口描述符现在具有悬空端口指针,而不是任务的端口命名空间表。然后破坏before_ports和after_ports,并强制GC。请注意,这意味着攻击者不再拥有对任务端口命名空间中悬空ipc_port的发送权限。但他们仍然保留对发送损坏的外联端口描述符的端口接收权限,因此通过接收在该端口上排队的消息,就可以重新获得到悬空端口的发送权限。

这次,他们继续使用熟悉的虚假端口结构,直接尝试使用管道缓冲区重新分配支持目标端口的内存。

攻击者使用以下上下文值,填充所有管道缓冲区和虚假端口:

然后,他们接收包含外部端口描述符的所有消息,查看其中是否有任何一个包含端口权限。如果在这里找到任何端口,就证明它是指向目标的悬空指针。

这里,在接收端口上调用mach_port_get_context,并确保上下文值的较高32位与它们设置的魔术值(0x2333)匹配。根据较低的32位,可以确定哪个管道fd拥有替换缓冲区,以及虚假端口在该页面上的偏移量。

这里的一切都和之前的利用链一样,攻击者在管道缓冲区中创建一个虚假的clock端口,并使用clock_sleep_trap技巧来确定KASLR Slide。攻击者构建一个虚假的内核任务端口,实现沙箱逃逸,并修补平台策略,将植入工具的CDHash添加到信任缓存中,并以root身份生成植入工具。

Supervisor: Associate Research Fellow Liu Jun Lecturer Ren Kun March, 2015 杭州电子科技大学 学位论文原创性声明和使用授权说明 原创性声明 本人郑重声明: 所呈交的学位论文,是本人在导师的指导下,独立进行研究工作所取得 的成果。除文中已经注明引用的内容外,本论文不含任何其他个人或集体已经发表或撰写过 的作品或成果。对本文的研究做出重要贡献的个人和集体,均已在文中以明确方式标明。申 请学位论文与资料若有不实之处,本人承担一切相关责任。 论文作者签名: 日期: 年 月 日 学位论文使用授权说明 本人完全了解杭州电子科技大学关于保留和使用学位论文的规定,即:研究生在校攻读 学位期间论文工作的知识产权单位属杭州电子科技大学。本人保证毕业离校后,发表论文或 使用论文工作成果时署名单位仍然为杭州电子科技大学。学校有权保留送交论文的复印件, 允许查阅和借阅论文;学校可以公布论文的全部或部分内容,可以允许采用影印、缩印或其 它复制手段保存论文。(保密论文在解密后遵守此规定) 论文作者签名: 日期: 年 月 日 指导教师签名: 日期: 年 月 日 摘 要 随着计算机科学技术的飞速发展,在电路设计领域电子设计自动化( Electronic Design Automation )技术对电路设计人员来说也变得越来越重要。EDA技术的发展使得整个集成电 路产业的各个阶段的工作在速度、质量、和精度上得以保证。无疑,在众多的EDA工具软件 中电路模拟部分是它们的核心。Spice仿真程序应用简单、精度高,受到了众多电路设计人员 的欢迎。 本文在对用于集成电路模型和模型库参数提取的基本流程和方法进行充分分析的基础 上,开展了适用于 CMOS 集成电路工艺射频模型参数提取工具的开发工作。该工具可驱 动 Spice、Hspice 等仿真工具,加载集成电路基础元器件模型参数提取用测试数据,并支持用户 在软件环境下采用 python 语言进行模型参数提取流程的开发。为支持模型参数最优化,集成 了遗传算法,并开发为优化器。该工具通过了实际器件建模验证。为支持无源器件精确模型 的开发,本文对基于 vector fitting 的模型参数提取方法进行了研究,并提出了一种新的建立 毫米波器件模型的方法。 第一章本文介绍了IC器件模型和器件建模软件概况。然后介绍了本文的目的和本文得到 的结论。第二章本文详细介绍了目前市面上流行的几款器件建模软件,并分别分析了它们的 优缺点。第三章本文介绍了我们自己实现的软件,其中包括软件功能定义、软件架构等模块。

我要回帖

更多关于 支持callkit的软件 的文章