在ZecOps 团队宣布在iOS的默认邮件应用程序中发现RCE漏洞之后,已经有很多用户联系了他们,他们怀疑自己成为了这个漏洞的攻击目标。
在这篇文章中,我们将介绍一种简单的方法来喷洒堆,通过这种方法,我们可以证明远程利用这个漏洞是可能的。除此之外,我们还将提供两个在野外观察到的触发器示例。
目前,我们已经发现了该漏洞具有以下攻击性能:
1.邮件应用程序中的远程堆溢出;
2.能够通过传入邮件由攻击者控制的输入内容来远程触发漏洞;
3.改变代码执行的能力;
4.事实提升访问内核的权限;
不过,我们并没有发现该漏洞可以泄漏消息,但让人感到惊讶是,信息泄漏并不是存在于邮件中,而是存在于其他过程中。因为dyld_shared_cache是通过大多数进程共享的,因此信息泄漏漏洞不一定必须存在于MobileMail中,例如iMessage的CVE-2019-8646也可以远程实现这个功能,这就打开了额外的攻击面(Facetime、其他应用、iMessage等)。本文,我们会远程利用这个漏洞所具有的所有特性。尽管如此,我们还是要做以下说明:
1.我们无意公开LPE,它允许我们在需要时对A12及更高版本的设备执行文件系统提取或内存检查。你可以在FreeTheSandbox.org 上了解更多关于移动设备的漏洞信息。
2.我们还没有在野外看到对本地特权升级(LPE)漏洞的利用;
我们还将分享我们在野外看到的两个触发器示例,并让你做出自己的推断和结论。
MailDemon赏金
最后,对于那些能够证明他们遭到攻击的示例,我们将提供赏金。
利用MailDemon
如前所述,MailDemon是一个很好的利用对象,因为它覆盖了MALLOC_NANO内存区域的模块,而MALLOC_NANO内存区域存储了大量的Objective-C对象。因此,它允许攻击者操纵已被攻击对象的ISA指针(允许他们引起类型混淆)或重写函数指针来控制进程的代码流,这是接管受影响过程的可行方法。
堆喷和堆整理技术
为了控制代码流,需要进行堆喷射以将制作的数据放入内存中。使用包含“dealloc”方法的伪方法缓存的伪造类,我们可以使用此方法触发漏洞后控制程序计数器(PC)寄存器。
下面是测试POC时生成的部分崩溃日志:
Exception Type: EXC_BAD_ACCESS (SIGBUS) Exception Subtype: EXC_ARM_DA_ALIGN at 0xdeadbeefdeadbeef VM Region Info: 0xdeadbeefdeadbeef is not in any region. Bytes after previous region: 16045690973559045872 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL MALLOC_NANO 0000000280000000-00000002a0000000 [512.0M] rw-/rwx SM=PRV ---> UNUSED SPACE AT END Thread 18 name: Dispatch queue: com.apple.CFNetwork.Connection Thread 18 Crashed: 0 ??? 0xdeadbeefdeadbeef 0 + -2401053088876216593 1 libdispatch.dylib 0x00000001b7732338 _dispatch_lane_serial_drain$VARIANT$mp + 612 2 libdispatch.dylib 0x00000001b7732e74 _dispatch_lane_invoke$VARIANT$mp + 480 3 libdispatch.dylib 0x00000001b773410c _dispatch_workloop_invoke$VARIANT$mp + 1960 4 libdispatch.dylib 0x00000001b773b4ac _dispatch_workloop_worker_thread + 596 5 libsystem_pthread.dylib 0x00000001b796a114 _pthread_wqthread + 304 6 libsystem_pthread.dylib 0x00000001b796ccd4 start_wqthread + 4 Thread 18 crashed with ARM Thread State (64-bit): x0: 0x0000000281606300 x1: 0x00000001e4b97b04 x2: 0x0000000000000004 x3: 0x00000001b791df30 x4: 0x00000002827e81c0 x5: 0x0000000000000000 x6: 0x0000000106e5af60 x7: 0x0000000000000940 x8: 0x00000001f14a6f68 x9: 0x00000001e4b97b04 x10: 0x0000000110000ae0 x11: 0x000000130000001f x12: 0x0000000110000b10 x13: 0x000001a1f14b0141 x14: 0x00000000ef02b800 x15: 0x0000000000000057 x16: 0x00000001f14b0140 x17: 0xdeadbeefdeadbeef x18: 0x0000000000000000 x19: 0x0000000108e68038 x20: 0x0000000108e68000 x21: 0x0000000108e68000 x22: 0x000000016ff3f0e0 x23: 0xa3a3a3a3a3a3a3a3 x24: 0x0000000282721140 x25: 0x0000000108e68038 x26: 0x000000016ff3eac0 x27: 0x00000002827e8e80 x28: 0x000000016ff3f0e0 fp: 0x000000016ff3e870 lr: 0x00000001b6f3db9c sp: 0x000000016ff3e400 pc: 0xdeadbeefdeadbeef cpsr: 0x60000000
在这种示例下,堆喷射的理想原语是可以从远程触发的内存泄漏漏洞,因为我们希望所喷洒的内存在触发内存破坏之前保持不变。另一种方法是使用MFMutableData本身,当MFMutableData的大小小于0x20000字节时,它从堆中分配内存,而不是创建一个文件来存储内容。我们可以通过将电子邮件的内容分割成小于0x20000字节的行来控制MFMutableData的大小,因为IMAP库是按行读取电子邮件内容的。使用这个原语,我们有更好的机会将有效载荷放置到我们想要的地址中。
触发过程
一个过大的电子邮件能够复制漏洞作为一个PoC ,但是要获得稳定的利用,我们需要仔细研究“-[MFMutableData appendBytes:length:]“。
-[MFMutableData appendBytes:length:] { int old_len = [self length]; //... char* bytes = self->bytes; if(!bytes){ bytes = [self _mapMutableData]; //Might be a data pointer of a size 8 heap } copy_dst = bytes + old_len; //... memmove(copy_dst, append_bytes, append_length); // It used append_length to copy the memory, causing an OOB writing in a small heap }
memove的目标地址是 ”bytes + old_len”,而不是“bytes”。那么,如果在触发漏洞之前我们积累了太多数据该怎么办?考虑到MALLOC_NANO区域的大小为512MB, “old_len”将以一个非常大的值结束,因此目标地址将以超出该区域边界的无效地址结束并立即崩溃。
为了减少“填充”的大小,我们需要在触发漏洞之前消耗尽可能多的数据。此时,内存泄漏就会必然发生。
值得注意的是,“填充”并不意味着溢出地址是完全随机的,由于硬件大小相同,因此硬件模型可以预测“填充”,因为在我们的测试中,相同大小的mmap通常会失败。
崩溃分析
这篇文章讨论了在以前的文章中介绍的在野外检测到的MobileMail漏洞的几种触发因素和可利用性。
示例1显示,该漏洞在被披露之前就在野外被触发。
示例2是由于MALLOC_NANO区域中的内存损坏,损坏的内存的值是已发送电子邮件的一部分,并完全由发件人控制。
示例1
当发生溢出时,易受攻击的函数内部立即触发了以下崩溃。
Coalition: com.apple.mobilemail [521] Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x000000004a35630e //[a] VM Region Info: 0x4a35630e is not in any region. Bytes before following region: 3091946738 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL UNUSED SPACE AT START ---> __TEXT 000000010280c000-0000000102aec000 [ 2944K] r-x/r-x SM=COW ...p/MobileMail] Thread 4 Crashed: 0 libsystem_platform.dylib 0x00000001834a5a80 _platform_memmove + 208 0x1834a5a74 ldnp x10, x11, [x1, #16] 0x1834a5a78 add x1, x1, 0x20 0x1834a5a7c sub x2, x2, x5 0x1834a5a80 stp x12, x13, [x0] //[b] 0x1834a5a84 stp x14, x15, [x0, #16] 0x1834a5a88 subs x2, x2, 0x40 0x1834a5a8c b.ls 0x00002ab0 1 MIME 0x00000001947ae104 -[MFMutableData appendBytes:length:] + 356 2 Message 0x0000000194f6ce6c -[MFDAMessageContentConsumer consumeData:length:format:mailMessage:] + 804 3 DAEAS 0x000000019ac5ca8c -[ASAccount folderItemsSyncTask:handleStreamOperation:forCodePage:tag:withParentItem:withData:dataLength:] + 736 4 DAEAS 0x000000019aca3fd0 -[ASFolderItemsSyncTask handleStreamOperation:forCodePage:tag:withParentItem:withData:dataLength:] + 524 5 DAEAS 0x000000019acae338 -[ASItem _streamYourLittleHeartOutWithContext:] + 440 6 DAEAS 0x000000019acaf4d4 -[ASItem _streamIfNecessaryFromContext:] + 96 7 DAEAS 0x000000019acaf758 -[ASItem _parseNextValueWithDataclass:context:root:parent:callbackDict:streamCallbackDict:parseRules:account:] + 164 8 DAEAS 0x000000019acb001c -[ASItem parseASParseContext:root:parent:callbackDict:streamCallbackDict:account:] + 776 9 DAEAS 0x000000019acaf7d8 -[ASItem _parseNextValueWithDataclass:context:root:parent:callbackDict:streamCallbackDict:parseRules:account:] + 292 10 DAEAS 0x000000019acb001c -[ASItem parseASParseContext:root:parent:callbackDict:streamCallbackDict:account:] + 776 ... Thread 4 crashed with ARM Thread State (64-bit): x0: 0x000000004a35630e x1: 0x00000001149af432 x2: 0x0000000000001519 x3: 0x000000004a356320 x4: 0x0000000100000028 x5: 0x0000000000000012 x6: 0x0000000c04000100 x7: 0x0000000114951a00 x8: 0x44423d30443d3644 x9: 0x443d30443d38463d x10: 0x3d31413d31443d30 x11: 0x31413d31463d3444 x12: 0x33423d30453d3043 x13: 0x433d30443d35423d x14: 0x3d30443d36443d44 x15: 0x30443d38463d4442 x16: 0x00000001834a59b0 x17: 0x0200080110000100 x18: 0xfffffff00a0dd260 x19: 0x000000000000152b x20: 0x00000001149af400 x21: 0x000000004a35630e x22: 0x000000004a35630f x23: 0x0000000000000008 x24: 0x000000000000152b x25: 0x0000000000000000 x26: 0x0000000000000000 x27: 0x00000001149af400 x28: 0x000000018dbd34bc fp: 0x000000016da4c720 lr: 0x00000001947ae104 sp: 0x000000016da4c720 pc: 0x00000001834a5a80 cpsr: 0x80000000
对于[a]和[b],我们知道进程在“memmove”中崩溃,这个进程被“-[MFMutableData appendBytes:length:]”调用,这意味着“copy_dst”的值首先是一个无效地址,即0x4a35630e。
那么寄存器x0 (0x4a35630e)的值是从哪里来的呢?因为,它比最低有效地址小得多。
结果是,当在mmap文件失败后,同时分配8字节内存失败时,进程就会崩溃。
无效地址0x4a35630e实际上是触发漏洞之前MFMutableData的长度偏移量(即“old_len”)。当calloc分配内存失败时,它返回NULL,因此copy_dst将是“0 + old_len(0x4a35630e)”。
在本例中,“old_len”约为1.2GB,这与POC的平均长度相匹配,这可能会导致mmap失败并触发漏洞。
请注意,x8-x15和x0完全由发送者控制。
这次崩溃为我们的上述问题(如果我们在触发漏洞之前积累了太多的数据,会怎么样?)提供了另一个答案,8字节内存的分配可能会失败并崩溃,而将有效载荷复制到一个无效的地址。这可能使可靠的利用变得更加困难,因为我们可能在接管程序计数器之前崩溃。
回顾2010年iOS 3.1.3中的神秘触发!
值得注意的是,我们在modmy.com论坛上找到了一个匿名用户完全类似的触发事件的公开示例:
漏洞版本:iPhone 2G上的iOS 3.1.3;
发生时间:2010年10月22日;
用户“shyamsandeep”于2008年6月12日注册,最后一次登录是在2011年10月16日,在论坛中只有一篇帖子,其中就包含了这个触发事件。
这个崩溃的r0等于0x037ea000,这可能是我们在之前的文章中披露的第一个漏洞,这是由于ftruncate()失败造成的。有趣的是,正如我们在第一种示例中所解释的,它也可能是分配8字节内存失败的结果,但是由于日志缺少内存区域信息,因此无法确定确切原因。但是,可以肯定的是,自2010年以来,这个可利用漏洞的触发因素很多。
Identifier: MobileMail Version: ??? (???) Code Type: ARM (Native) Parent Process: launchd [1] Date/Time: 2010-10-22 08:14:31.640 +0530 OS Version: iPhone OS 3.1.3 (7E18) Report Version: 104 Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x037ea000 Crashed Thread: 4 Thread 4 Crashed: 0 libSystem.B.dylib 0x33aaef3c 0x33aad000 + 7996 //memcpy + 0x294 1 MIME 0x30a822a4 0x30a7f000 + 12964 //_FastMemoryMove + 0x44 2 MIME 0x30a8231a 0x30a7f000 + 13082 // -[MFMutableData appendBytes:length:] + 0x6a 3 MIME 0x30a806d6 0x30a7f000 + 5846 // -[MFMutableData appendData:] + 0x32 4 Message 0x342e2938 0x34251000 + 596280 // -[DAMessageContentConsumer consumeData:length:format:mailMessage:] + 0x25c 5 Message 0x342e1ff8 0x34251000 + 593912 // -[DAMailAccountSyncConsumer consumeData:length:format:mailMessage:] +0x24 6 DataAccess 0x34146b22 0x3413e000 + 35618 // -[ASAccount folderItemsSyncTask:handleStreamOperation:forCodePage:tag:withParentItem:withData:dataLength:] + 0x162 7 DataAccess 0x3416657c 0x3413e000 + 165244 //[ASFolderItemsSyncTaskhandleStreamOperation:forCodePage:tag:withParentIt em:withData:dataLength:] + 0x108 ... Thread 4 crashed with ARM Thread State: r0: 0x037ea000 r1: 0x008729e0 r2: 0x00002205 r3: 0x4e414153 r4: 0x41415367 r5: 0x037e9825 r6: 0x00872200 r7: 0x007b8b78 r8: 0x0001f825 r9: 0x001fc098 r10: 0x00872200 r11: 0x0087c200 ip: 0x0000068a sp: 0x007b8b6c lr: 0x30a822ab pc: 0x33aaef3c cpsr: 0x20000010
示例2
以下是在收到并处理电子邮件之后发生的另一次崩溃:
Coalition: com.apple.mobilemail [308] Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x0041004100410041 // [a] VM Region Info: 0x41004100410041 is not in any region. Bytes after previous region: 18296140473139266 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL mapped file 00000002d31f0000-00000002d6978000 [ 55.5M] r--/rw- SM=COW ...t_id=9bfc1855 ---> UNUSED SPACE AT END Thread 13 name: Dispatch queue: Internal _UICache queue Thread 13 Crashed: 0 libobjc.A.dylib 0x00000001b040fca0 objc_release + 16 0x1b040fc94 mov x29, sp 0x1b040fc98 cbz x0, 0x0093fce4 0x1b040fc9c tbnz x0, #63, 0x0093fce4 0x1b040fca0 ldr x8, [x0] // [b] 0x1b040fca4 and x8, x8, 0xffffffff8 0x1b040fca8 ldrb w8, [x8, #32] 0x1b040fcac tbz w8, #2, 0x0093fd14 1 CoreFoundation 0x00000001b1119408 -[__NSDictionaryM removeAllObjects] + 600 2 libdispatch.dylib 0x00000001b0c5d7d4 _dispatch_client_callout + 16 3 libdispatch.dylib 0x00000001b0c0bc1c _dispatch_lane_barrier_sync_invoke_and_complete + 56 4 UIFoundation 0x00000001bb9136b0 __16-[_UICache init]_block_invoke + 76 5 libdispatch.dylib 0x00000001b0c5d7d4 _dispatch_client_callout + 16 6 libdispatch.dylib 0x00000001b0c0201c _dispatch_continuation_pop$VARIANT$mp + 412 7 libdispatch.dylib 0x00000001b0c11fa8 _dispatch_source_invoke$VARIANT$mp + 1308 8 libdispatch.dylib 0x00000001b0c0ee00 _dispatch_kevent_worker_thread + 1224 9 libsystem_pthread.dylib 0x00000001b0e3e124 _pthread_wqthread + 320 10 libsystem_pthread.dylib 0x00000001b0e40cd4 start_wqthread + 4 Thread 13 crashed with ARM Thread State (64-bit): x0: 0x0041004100410041 x1: 0x00000001de1ac18a x2: 0x0000000000000000 x3: 0x0000000000000010 x4: 0x00000001b0c60388 x5: 0x0000000000000010 x6: 0x0000000000000000 x7: 0x0000000000000000 x8: 0x0000000281f94090 x9: 0x00000001b143f670 x10: 0x0000000142846800 x11: 0x0000004b0000007f x12: 0x00000001428468a0 x13: 0x000041a1eb487861 x14: 0x0000000283ed9d10 x15: 0x0000000000000004 x16: 0x00000001eb487860 x17: 0x00000001b11191b0 x18: 0x0000000000000000 x19: 0x0000000281dce4c0 x20: 0x0000000282693398 x21: 0x0000000282693330 x22: 0x0000000000000000 x23: 0x0000000000000000 x24: 0x0000000281dce4c8 x25: 0x000000000c000000 x26: 0x000000000000000d x27: 0x00000001eb48e000 x28: 0x0000000282693330 fp: 0x000000016b8fe820 lr: 0x00000001b1119408 sp: 0x000000016b8fe820 pc: 0x00000001b040fca0 cpsr: 0x20000000
[a]:对象的指针被“0x00410041004100410041”覆盖,它在unicode中是AAAA。
[b]是我们为更好地理解而添加的关于崩溃地址的指令之一,当-[nsdictionarym removeAllObjects]试图释放一个对象时,进程在指令“ldr x8, [x0]”上崩溃。
通过逆向工程-[nsdictionarym removeAllObjects],我们可以理解寄存器x0是从x28(0x0000000282693330)加载的,因为在崩溃之前,寄存器x28从未被更改过。
让我们看一下x28: 0x0000000282693330的虚拟内存区域信息,覆盖的对象存储在MALLOC_NANO区域,该区域存储小堆块。堆溢出漏洞会破坏同一个区域,因为它会溢出一个8字节的堆块,这个堆块也存储在MALLOC_NANO中。
MALLOC_NANO 0x0000000280000000-0x00000002a0000000 rw-/rwx
这个崩溃实际上非常接近于控制PC,因为它控制了Objective-C对象的指针。通过将寄存器x0的值指向一个带有伪对象和伪方法缓存的类的内存,攻击者可以控制PC指针。
总结
1.很少看到用户提供的输入触发和控制远程漏洞;
2.如上所述,利用这个漏洞是可能的;
3.如上所述,现实中的触发器具有较大的分配值;
4.如上所述,现实中的触发器的值是由发送方控制的;
5.我们寻找的电子邮件丢失/删除了;
6.这个漏洞在2010年的iPhone 2G设备上就有了;
苹果如何改进日志?
iOS日志中缺少详细信息,而且缺少为个人和组织选择数据粒度的选项,因此需要进行更改,以使iOS能够与MacOS、Linux和Windows功能相媲美。总的来说,为了分析手机是如何被入侵的而侵入手机的做法是完全错误的,但却是迫不得已。
为此,我们建议苹果改进其漏洞诊断流程,以帮助个人、组织和软件开发者调查他们的设备。我们的建议如下:
1.改进崩溃:启用查看每个指针/寄存器旁边的内存的功能
2.改善崩溃:显示堆栈/堆内存/寄存器附近的内存;
3.将PID / PPID / UID / EUID添加到所有适用的事件;
4.无需物理连接即可将这些日志发送到远程服务器,在多个示例中,日志被神秘地删除;
5.能够对可疑的iOS设备进行完整的数字取证分析,而不需要先侵入设备;
本文翻译自:https://blog.zecops.com/vulnerabilities/seeing-maildemons-technique-triggers-and-a-bounty/ 如若转载,请注明原文地址