1 00:00:00,099 --> 00:00:15,129 *34c3 preroll music* 2 00:00:15,129 --> 00:00:19,695 Herald Angel: And now I want to introduce our first speaker and the topic he's 3 00:00:19,695 --> 00:00:27,844 talking about. iOS kernel exploitation archaeology. A kernel exploit from late 4 00:00:27,844 --> 00:00:35,231 2013 early 2014 will be digged out and analyzed proper archaeology all the 5 00:00:35,231 --> 00:00:43,165 digging... digging and analysis is done by argp here to my left on the stage and give 6 00:00:43,165 --> 00:00:46,586 him a big round of applause. And the stage is yours, thanks. 7 00:00:46,586 --> 00:00:47,882 *Applause* 8 00:00:47,882 --> 00:00:58,883 argp: Thanks for the introduction. First of all, thank you all for being here. As 9 00:00:58,883 --> 00:01:03,899 the person that did the introduction told you this is going to be an archeology talk 10 00:01:03,899 --> 00:01:09,939 so I apologize in advance if it's not that interesting for you. So we'll talk about a 11 00:01:09,939 --> 00:01:16,310 bit older stuff rather than new things. Okay so a bit a few things about myself. 12 00:01:16,851 --> 00:01:20,923 Actually, I think from all these things, the most important are the the Phrack 13 00:01:20,923 --> 00:01:26,830 papers, right? So, yeah. Let's ignore all the other stuff okay? So, what I'm going 14 00:01:26,830 --> 00:01:35,059 to talk about. I'm going to talk about the evasi0n7 kernel exploit. Now evasi0n7 was 15 00:01:35,059 --> 00:01:42,060 a jailbreak it was released by the evad3rs on the 22nd of December 2013. It supported 16 00:01:42,060 --> 00:01:50,210 iOS7 to iOS7.1 beta 3. That's not the 7.1 stable release, right? So that's a 17 00:01:50,210 --> 00:01:55,759 beta. And this supported all devices at that time including the iPhone 5s which 18 00:01:55,759 --> 00:02:03,999 was the first 64-bit device except the Apple TV. So, I decided to reverse 19 00:02:03,999 --> 00:02:08,900 engineer the kernel exploit of the jailbreak focused just on that. Because I 20 00:02:08,900 --> 00:02:14,170 was really interested, not so much in the bug itself, which was as we will see not 21 00:02:14,170 --> 00:02:18,805 very complicated. But I was really interested to understand the exploitation 22 00:02:18,805 --> 00:02:25,970 techniques that the evad3rs used. So, I started reversing it, and I understanding 23 00:02:25,970 --> 00:02:32,329 it, and at some point I just said I'm just gonna do a reimplementation of the kernel 24 00:02:32,329 --> 00:02:37,030 exploit. So, this talk is basically my notes on this whole process. And, of 25 00:02:37,030 --> 00:02:42,390 course, it's not a jailbreak walkthrough, right? And I'm going to specifically focus 26 00:02:42,390 --> 00:02:50,042 on the various problems I encountered during this task and how I overcame them. 27 00:02:50,042 --> 00:02:58,250 And hopefully it's going to give you some helpful takeways for if you do iOS kernel 28 00:02:58,250 --> 00:03:05,459 research nowadays. Okay, so, the general outline is I'm going to say a few things 29 00:03:05,459 --> 00:03:11,730 about the version 7 to setup the stage. And then I'm going to explain the kernel 30 00:03:11,730 --> 00:03:18,971 bug itself. And, then I'm going to talk in length about my debugging setup. And, I 31 00:03:18,971 --> 00:03:26,136 think that's a very important step that usually phone or embedded talks 32 00:03:26,136 --> 00:03:29,860 exploitation talks don't analyze that much, and I think it's a really important 33 00:03:29,860 --> 00:03:36,220 part. Because usually having a working the debugging set up is, basically, maybe half 34 00:03:36,220 --> 00:03:41,080 the job of doing a reliable exploit. Then I'm going to do to talk about my 35 00:03:41,080 --> 00:03:46,520 reimplementation of the exploit, and hopefully, at the end, we're gonna have 36 00:03:46,520 --> 00:03:53,870 some things to take away or maybe not. We will see. Okay so it was the evasi0n7 37 00:03:53,870 --> 00:03:59,300 jailbreak was released about 4 years ago. And that's the archaeology in the title. 38 00:03:59,300 --> 00:04:04,830 That's ancient history right? And if you were following the jailbreak community, 39 00:04:04,830 --> 00:04:12,120 you might remember this huge drama around this jailbreak, initially, with geohot and 40 00:04:12,120 --> 00:04:17,160 if he was planning or not to release it before the evad3rs. And who he was 41 00:04:17,160 --> 00:04:22,860 planning to sell it to, and some leaked discussion that he had with some of that 42 00:04:22,860 --> 00:04:31,070 he was offering money to buy. And geohot, his jailbreak supposedly using 43 00:04:31,070 --> 00:04:37,773 some of the bugs the evad3rs were using so this is a huge drama. And then after the 44 00:04:37,773 --> 00:04:43,320 evasi0n7 jailbreak released, like maybe a few hours ago, people realize that if your 45 00:04:43,320 --> 00:04:54,220 phone had a Chinese locale then the jailbreak was installing a piracy app. So, 46 00:04:54,220 --> 00:04:57,440 that was basically a third-party app that 47 00:04:57,440 --> 00:05:00,660 was taking you to an app store not operated 48 00:05:00,660 --> 00:05:05,210 by Apple but by TaiG that had some pirated versions of the real applications on the 49 00:05:05,210 --> 00:05:12,700 App Store. And, of course, that also create like a huge drama, this practice. 50 00:05:13,695 --> 00:05:17,660 Okay, so a lot of things were said about the jailbreak at that time and about the 51 00:05:17,660 --> 00:05:23,820 TaiG pirate App Store. But what I really set apart was this tweet. And the really 52 00:05:23,820 --> 00:05:28,030 important thing that I like about this tweet is, that it doesn't really make 53 00:05:28,030 --> 00:05:31,430 sense. So he says that we have to decide to remotely disable the default 54 00:05:31,430 --> 00:05:35,285 installation of TaiG in China for further investigations of the piracy. So that 55 00:05:35,285 --> 00:05:40,740 whole thing doesn't make sense. So you mean, you didn't know what was happening? 56 00:05:40,740 --> 00:05:45,490 You didn't bundle it with a jailbreak? Are you going to disable it for new 57 00:05:45,490 --> 00:05:50,040 installations? And then, what does remotely then mean exactly? So what about 58 00:05:50,040 --> 00:05:56,290 the people that already had the apps, the piracy app. How are you going to disable 59 00:05:56,290 --> 00:06:04,520 that? Is that what remotely refers to? So that's an excellent tweet I think. Okay, 60 00:06:04,520 --> 00:06:11,370 so some point after the evasi0n7 jailbreak was released geohot did a writeup on the 61 00:06:11,370 --> 00:06:19,151 userland part of it. So, he analyzed how the userland part worked and he stopped at 62 00:06:19,151 --> 00:06:27,690 the point of gaining root and basically, he mentioned in his writeup that the 63 00:06:27,690 --> 00:06:33,185 evasi0n7 untethered binary, which basically what was good doing the kernel 64 00:06:33,185 --> 00:06:40,260 exploit, was obfuscated. And as we will see this was indeed the case and as far as 65 00:06:40,260 --> 00:06:46,038 I know that's the first jailbreak that used the deliberate obfuscation. I don't 66 00:06:46,038 --> 00:06:51,330 know the reason, I assume it's partly to hide the the piracy 67 00:06:51,330 --> 00:06:57,243 app store that was bundled with it and maybe partly to hide the bug, the kernel 68 00:06:57,243 --> 00:07:07,370 bug, but I'm not sure about the reason. Now p0sixninja who found as far as I know 69 00:07:07,370 --> 00:07:12,120 the bug, the kernel bug did a writeup on the kernel bug, it's on the iPhone wiki, 70 00:07:12,120 --> 00:07:17,630 and he basically describes the bug and he stops at the point where he gets a crash 71 00:07:17,630 --> 00:07:25,530 log from gdb. So he doesn't say anything about how to exploit it. Okay, so after 72 00:07:25,530 --> 00:07:31,250 all these things happened then I decided to reverse engineer the untethered binary 73 00:07:31,250 --> 00:07:37,180 and understand the exploitation techniques and I was really interested to reverse 74 00:07:37,180 --> 00:07:41,289 engineer the obfuscation that the evad3rs were using, it seemed like an interesting 75 00:07:41,289 --> 00:07:46,250 challenge, and... but as I also mentioned earlier I was really interested to 76 00:07:46,250 --> 00:07:49,795 understand the exploitation techniques that they were using that was more 77 00:07:49,795 --> 00:07:58,510 important for me at that time. And, okay, so the jailbreak was released 78 00:07:58,510 --> 00:08:06,337 December 2013 and I started doing that around February 2014, and I did that while 79 00:08:06,337 --> 00:08:10,310 having an actual day job, right, so I was spending at most two days per week on 80 00:08:10,310 --> 00:08:20,360 that. So what was my setup? I had an iPhone 4, and if you know about iPhone 4s 81 00:08:20,360 --> 00:08:25,570 they have a boot ROM bug called limera1n which basically allows you to load 82 00:08:25,570 --> 00:08:31,520 arbitrary kernels, unsigned kernels, on the device and run them and that basically 83 00:08:31,520 --> 00:08:38,049 means that you can very easily set up kernel debugging. So initially I 84 00:08:38,049 --> 00:08:46,026 had an iPhone 4 device with iOS 7.0.6. I want to remind you that iPhone 4 is ARM32, 85 00:08:46,026 --> 00:08:52,990 right. I also had an iPhone 5s with the same version of iOS and I had that in 86 00:08:52,990 --> 00:09:00,269 order to verify all my findings and all my tests on - to redo my tests on an ARM64 87 00:09:00,269 --> 00:09:06,279 device and as I told you - the iPhone 5s at that time was the only ARM64 device. 88 00:09:06,279 --> 00:09:10,480 Actually, I think on the market, I don't think there was another consumer device 89 00:09:10,480 --> 00:09:19,240 with ARM64 at that time. So that's the exact version of version 7 I was analyzing 90 00:09:19,240 --> 00:09:26,269 and of course IDA, gdb, lldb. Now the lols in this slide they don't actually refer to 91 00:09:26,269 --> 00:09:30,639 something funny they actually mean something very painful and that caused a 92 00:09:30,639 --> 00:09:37,090 lot of like sleepless nights, but I'll get onto that. Okay, a few things about the 93 00:09:37,090 --> 00:09:44,310 obfuscation. So, not all the functions of the entire binary were obfuscated, but 94 00:09:44,310 --> 00:09:51,980 some of the important ones were, and those were the ones that were triggering the bug 95 00:09:51,980 --> 00:09:56,930 and they were actually doing heap manipulation and all the other important 96 00:09:56,930 --> 00:10:01,180 things. Now I have been told, I haven't checked that, but I have been told that 97 00:10:01,180 --> 00:10:05,256 later versions remove the obfuscation but I'm not sure about that, I haven't 98 00:10:05,256 --> 00:10:09,769 verified it and I already had my implementation done at that point so I 99 00:10:09,769 --> 00:10:20,170 wasn't that interested to look at that. So as I mentioned the kernel bug that the 100 00:10:20,170 --> 00:10:26,733 evasi0n7 untethered binary was based on was found by p0sixninja, and basically as 101 00:10:26,733 --> 00:10:34,040 far as he says on that iPhone wiki page he used that six line bash script fuzzer to 102 00:10:34,040 --> 00:10:41,840 find it. So as you can see he basically creates device nodes and, with 103 00:10:41,840 --> 00:10:50,439 controlled arguments here like minor and major numbers. Now in order to get to the 104 00:10:50,439 --> 00:10:57,100 point to create device nodes you basically need to be outside of the application 105 00:10:57,100 --> 00:11:04,329 sandbox that exists on iOS and you also need root privileges and that's what I 106 00:11:04,329 --> 00:11:08,224 refer to as the userland part of the evasi0n7 binary and I'm not going to cover 107 00:11:08,224 --> 00:11:14,810 that at all. So I'm gonna start my analysis from the point on that we have 108 00:11:14,810 --> 00:11:19,321 escaped the sandbox, we have obtained root and now we go to exploit the kernel 109 00:11:19,321 --> 00:11:29,268 bug. Now that's code from that version of the XNU kernel that had the bug. Now this 110 00:11:29,268 --> 00:11:39,533 ptsd_open function is called everytime userland code opens a /dev/ptmx device and 111 00:11:39,533 --> 00:11:43,936 then this ptmx_get_ioctl function is called. Now the important thing here 112 00:11:43,936 --> 00:11:46,779 is that dev here is completely user controlled and then 113 00:11:46,779 --> 00:11:49,023 it's passed to this ptmx_get_ioctl 114 00:11:49,023 --> 00:11:54,759 function with no checks at all, right, and then this ptmx_get_ioctl function uses 115 00:11:54,759 --> 00:11:59,949 this to index an array without any checks. So basically the bug's an invalid indexing 116 00:11:59,949 --> 00:12:05,618 bug, right, so since we can control that you can put here whatever. I have here the 117 00:12:05,618 --> 00:12:14,365 ptmx_ioctl struct that, okay, this array here is, so this state struct here is 118 00:12:14,365 --> 00:12:21,790 global to the kernel and this pis_ioctl_list array here is on the kernel 119 00:12:21,790 --> 00:12:30,418 heap and it is an array of ptmx_ioctl structs and that's the PTMX ioctl struct 120 00:12:30,418 --> 00:12:35,610 and the important thing here is, that I'm going to refer to again and again 121 00:12:35,610 --> 00:12:41,289 during the talk, is that it has a pointer to a tty struct as the first element of 122 00:12:41,289 --> 00:12:50,680 the structure. Okay, so we control the index to the array, so what can we do with 123 00:12:50,680 --> 00:12:57,349 that? So here as you can see it return the ptmx_get_ioctl function returns 124 00:12:57,349 --> 00:13:04,961 whatever it indexes, right. So, as you can see here is it assigns this pti variable 125 00:13:04,961 --> 00:13:10,682 and then does all kinds of interesting things, so pti is controllable, tp is 126 00:13:10,682 --> 00:13:14,163 controllable here as well after this dereference here to some controllable 127 00:13:14,163 --> 00:13:21,449 value and, I mean in other code parts of the kernel this is called again and so 128 00:13:21,449 --> 00:13:26,980 there are there are a lot of things to consider when you know the bug and 129 00:13:26,980 --> 00:13:33,788 then you try to think how to exploit it. Okay, one important thing here that I 130 00:13:33,788 --> 00:13:44,380 wanted to mention is that this ptmx, this function here ptmx_get_ioctl also 131 00:13:44,380 --> 00:13:51,850 does the allocation of this struct here, of this tty struct here and that's 132 00:13:51,850 --> 00:14:00,282 important because I'm going to use further on. Okay, another important thing is that 133 00:14:00,282 --> 00:14:05,934 you basically, this bug what allows you to do is you can control the size of this 134 00:14:05,934 --> 00:14:14,602 array here, so by, can you see that? Okay, so by repeatedly open the ptmx 135 00:14:14,602 --> 00:14:21,824 device you can grow this array and you can grow it as you see here by this grow 136 00:14:21,824 --> 00:14:29,830 vector that's 16, but it doesn't matter. What matters is that the size of this 137 00:14:29,830 --> 00:14:38,299 array in bytes is controllable by you, the person who are trying to exploit this bug. 138 00:14:38,299 --> 00:14:44,679 Now, for example these are notes from my exploit so if I did one allocation, if I 139 00:14:44,679 --> 00:14:51,239 did one open of this ptmx device then this array was going into kalloc_64. If I was 140 00:14:51,239 --> 00:14:59,089 doing 17 it was going to kalloc_128, if I was doing 33 opens here it was going to 141 00:14:59,089 --> 00:15:06,709 kalloc_192 and so on and so forth. So I could decide in which kalloc zone I could 142 00:15:06,709 --> 00:15:14,009 place the array. If you don't know kalloc zones, they are basically, you can think 143 00:15:14,009 --> 00:15:20,829 them as container, you can think kalloc zones as containers for heap objects on 144 00:15:20,829 --> 00:15:26,579 the kernel heap. All of them can be of different type but they're, all of them 145 00:15:26,579 --> 00:15:33,265 are of the same size, right, so kalloc_64 can have different structures of size 64 146 00:15:33,265 --> 00:15:43,258 bytes, but all of them are our size 64 bytes. Okay so I started debugging the 147 00:15:43,260 --> 00:15:49,936 untethered binary in userland, that's how I started. So initially I was using gdb 148 00:15:49,936 --> 00:15:57,889 and I found out that nothing worked with gdb. It was at that point Apple was 149 00:15:57,889 --> 00:16:01,641 starting to move from gdb to lldb, so I don't, maybe that was the reason gdb 150 00:16:01,641 --> 00:16:05,960 wasn't tested at all. So when I say nothing worked I mean that I was 151 00:16:05,960 --> 00:16:11,799 placing break points and they weren't hitting and I was trying like stepping and 152 00:16:11,799 --> 00:16:16,269 it was continuing execution and stuff like that. Sometimes I couldn't even attach the 153 00:16:16,269 --> 00:16:23,534 binary. So then I moved to lldb, on lldb set up with debugserver and things were 154 00:16:23,534 --> 00:16:29,489 much better. Now, while I was experimenting stealing from, just with 155 00:16:29,489 --> 00:16:35,436 userland debugging my iPhone 4 device went to into a recovery loop and I wasn't able 156 00:16:35,436 --> 00:16:46,339 to get out of it, so I was forced to do a clean restore of the device. The problem 157 00:16:46,339 --> 00:16:51,749 was that at that time only iOS 7.1 was signed by Apple, so I couldn't install a 158 00:16:51,749 --> 00:16:55,889 version of files that hit the kernel that hit the bug that I was interested to look 159 00:16:55,889 --> 00:16:59,610 at, but on the other hand I couldn't not restore my device because that was the 160 00:16:59,610 --> 00:17:05,240 only device I had at the point I could do kernel debugging with. So I updated my 161 00:17:05,240 --> 00:17:11,805 device to 7.1. As I said just told you 7.1 didn't have a vulnerable kernel 162 00:17:11,805 --> 00:17:22,208 to this bug, so what I wanted to do was basically to boot an iOS 7.1 device with a 163 00:17:22,208 --> 00:17:27,990 7.0.6 kernel, and in order to do that I could use the limera1n bug that allowed me 164 00:17:27,990 --> 00:17:32,854 to boot arbitrary kernels and the utility to do that was redsn0w, right. The problem 165 00:17:32,854 --> 00:17:40,400 was that redsn0w only supported up to iOS 6 and it wasn't, it didn't have support 166 00:17:40,400 --> 00:17:46,100 for iOS 7 so I left all the other things I was doing and I started reversing redsn0w 167 00:17:46,100 --> 00:17:51,530 to understand how it worked. Redsn0w, if you don't know it's, it was back then 168 00:17:51,530 --> 00:17:55,740 and still is closed source, right, so I started reversing that to understand how 169 00:17:55,740 --> 00:18:00,875 it worked in order to support, for me to hot patch it, to binary 170 00:18:00,875 --> 00:18:06,646 patch it to add support for iOS 7 and I spent like I don't know maybe a month on 171 00:18:06,646 --> 00:18:11,699 that and then I realized that it was, it wasn't leading me anywhere, I couldn't 172 00:18:11,699 --> 00:18:17,029 understand a lot of things about how redsn0w was implemented, so I I stopped 173 00:18:17,029 --> 00:18:25,700 doing that, and at that point I found opensn0w which was an effort by winocm to 174 00:18:25,700 --> 00:18:32,160 implement redsn0w as open source. So, it seemed to have support for iOS 7 and that 175 00:18:32,160 --> 00:18:40,120 was good, I tested that and it was working. Now my problem was that I 176 00:18:40,120 --> 00:18:44,460 couldn't have an arbitrary length of boot-args. Boot-args are the 177 00:18:44,460 --> 00:18:48,590 arguments that you pass to the kernel when it boots and they are really important in 178 00:18:48,590 --> 00:18:57,630 iOS because by passing certain boot-args to the kernel you can disable sign checks, 179 00:18:57,630 --> 00:19:02,320 you can enable kernel debugging, so it's really important to be able to pass 180 00:19:02,320 --> 00:19:09,470 arbitrary length boot-args. And iOS 7.1 was using absurd 9 character so that was 181 00:19:09,470 --> 00:19:15,726 the reason opensn0w couldn't support more So what I ended up doing was I patched 182 00:19:15,726 --> 00:19:22,556 iBEC, which is basically the loader of the kernel, right, that passes boot- 183 00:19:22,556 --> 00:19:29,935 args to the kernel when it boots and, basically I changed the pointer to the 184 00:19:29,935 --> 00:19:35,571 boot-args to some other place that had much more space. So at that point I was 185 00:19:35,571 --> 00:19:41,619 able to pass arbitrary-length boot-args to my kernel. So where we are at last? So I 186 00:19:41,619 --> 00:19:50,358 had an iPhone 4 device with iOS 7.1 and I was using opensn0w to boot the 7.0.6 187 00:19:50,358 --> 00:19:56,795 kernel that had the bug that I was interested to exploit. Now, one side note 188 00:19:56,795 --> 00:20:04,161 here is that as I was doing that and I was trying to add to open snow all the patches 189 00:20:04,161 --> 00:20:09,762 to the kernel to enable kernel debugging, I was reversing the evasi0n7 binary as 190 00:20:09,762 --> 00:20:15,217 well. Now, the evasi0n7 binary was trying also to, after it exploited the kernel 191 00:20:15,217 --> 00:20:19,799 it was patching it to enable kernel debugging, but, so I was just copying 192 00:20:19,799 --> 00:20:23,740 their patches, right, and adding them to opensn0w, but I realized at some point 193 00:20:23,740 --> 00:20:29,919 that they missed some check for the debug- enabled variable and KDP wasn't really 194 00:20:29,919 --> 00:20:35,919 working, so the session was established and it seemed like it was working, but if 195 00:20:35,919 --> 00:20:40,934 you tried to actually use the kernel, the KDP, the kernel debugging setup for 196 00:20:40,934 --> 00:20:45,470 to do actual, like to attach debugger to the kernel and do whatever, like place a 197 00:20:45,470 --> 00:20:54,241 breakpoint or step then KDP just froze. So I added another part that was required on 198 00:20:54,241 --> 00:21:02,730 that. Ok, so kernel debugging at last, but that's not really what happened, because 199 00:21:02,730 --> 00:21:07,981 you know breakpoints didn't always work so you were placing a breakpoint and it 200 00:21:07,981 --> 00:21:12,708 wasn't hitting when execution was reaching there and you were trying to step 201 00:21:12,708 --> 00:21:17,340 instructions and the execution just continues, so you were stepping one 202 00:21:17,340 --> 00:21:21,210 instruction it was just like you would type in continue and if you were taking 203 00:21:21,210 --> 00:21:26,755 too long to type an lldb command then KDP froze and then you had to restart your 204 00:21:26,755 --> 00:21:33,261 device, re-establish the kernel debugging session and start from zero. And if you 205 00:21:33,261 --> 00:21:37,951 issue commands too fast then KDB froze again, so you have to reboot again. It was 206 00:21:37,951 --> 00:21:47,320 amazing, it was great time. And now I did similar stuff with iOS 6 and I distinctly 207 00:21:47,320 --> 00:21:53,110 remember that was much easier and kernel debugging worked much better. And... I 208 00:21:53,110 --> 00:21:58,669 mean the issue that comes to everyone's mind that does that is: do Apple engineers 209 00:21:58,669 --> 00:22:05,580 really use KDP for debugging the iOS kernel or do they use something else? 210 00:22:06,240 --> 00:22:15,330 Okay, so now I could debug the evasi0n7 untethered binary both from the userland 211 00:22:15,330 --> 00:22:23,130 side and from the kernel side, and that was good because I was analyzing at run 212 00:22:23,130 --> 00:22:31,730 time and at the same time I was reversing it in IDA, so the obfuscation who... I 213 00:22:31,730 --> 00:22:38,480 could do it much faster since I was taking hints from runtime. So I... at that point 214 00:22:38,480 --> 00:22:42,860 things started moving fast and I quickly found that it was abusing the data by 215 00:22:42,860 --> 00:22:49,179 structure to obtain read/write access to physical memory. I mean that was 216 00:22:49,179 --> 00:22:52,940 interesting to me, but I was expecting something else. I was expecting something 217 00:22:52,940 --> 00:22:58,389 like what they did in iOS in the evasi0n6 jailbreak, that they did like a lot of 218 00:22:58,389 --> 00:23:04,387 heap manipulation and that's my interest actually, heap exploitation. So at that 219 00:23:04,387 --> 00:23:10,370 point I decided to stop reversing it and reimplement the exploit the way that I 220 00:23:10,370 --> 00:23:16,190 wanted to do it. So obviously that wasn't work from scratch, it was from everything 221 00:23:16,190 --> 00:23:20,330 that I understood up to that point, and what I really wanted to use was the 222 00:23:20,330 --> 00:23:25,410 vm_map_copy structures technique by Dowd and Mandt and I'm going to explain that in 223 00:23:25,410 --> 00:23:31,669 the following slides, how it works. Okay, so at that point I had the clear 224 00:23:31,669 --> 00:23:37,090 understanding of the bug, what it was and I had the general idea like about how to 225 00:23:37,090 --> 00:23:41,779 exploit it and I mean if you've done that you know then it takes a lot of pen 226 00:23:41,779 --> 00:23:47,980 and paper like ideas you develop on paper, then you go test them and they don't work 227 00:23:47,980 --> 00:23:53,409 and then you design them again and then again and you fail and you despair and 228 00:23:53,409 --> 00:23:58,289 then you suddenly have an idea and you spend like I don't know like two nights 229 00:23:58,289 --> 00:24:04,029 stay up until 5:00 in the morning testing things and they don't work and then you 230 00:24:04,029 --> 00:24:10,700 despair again and ad nauseam. But eventually you get somewhere so let's talk 231 00:24:10,700 --> 00:24:18,630 about exploitation now. Now, a few things to refresh your memory about the bug. So 232 00:24:18,630 --> 00:24:26,200 as I said it was an invalid indexing bug. This pis_ioctl_list array was on the heap 233 00:24:26,200 --> 00:24:32,760 and I could control in which kalloc zone it can go. I can grow it, but once I grow 234 00:24:32,760 --> 00:24:42,700 it I cannot shrink it back. Now, that's code from that ptmx_get_ioctl function, so 235 00:24:42,700 --> 00:24:46,760 what... basically what it does it allocates a new ptmx_ioctl structure and 236 00:24:46,760 --> 00:24:53,294 then it uses the index that you provide... that you control to store the address on 237 00:24:53,294 --> 00:25:01,090 the array. Now, this allocation here... this struct here goes into kalloc.88 and 238 00:25:01,090 --> 00:25:07,895 that's useful for the next parts. Okay, a few things about the technique I wanted to 239 00:25:07,895 --> 00:25:13,000 use... about the exploitation technique I wanted to use. So it's the vm_map_copy 240 00:25:13,000 --> 00:25:19,160 technique, it was proposed by Dowd and Mandt and basically they were spraying the 241 00:25:19,160 --> 00:25:24,779 heap with these structs here, the vm_map_copy structs, and assuming you have 242 00:25:24,779 --> 00:25:31,250 like some way to corrupt this struct that you've sprayed on the heap if you can 243 00:25:31,250 --> 00:25:39,299 overwrite this kdata element here, then basically what you have is a leak of 244 00:25:39,299 --> 00:25:44,669 kernel memory other adjacent like next to the kdata, whatever is below or above the 245 00:25:44,669 --> 00:25:49,941 kdata pointer or arbitrary if you put whatever address you want in there. By 246 00:25:49,941 --> 00:25:58,019 overwriting the kalloc_size element here and then freeing the struct on the heap, 247 00:25:58,019 --> 00:26:03,909 you put it on a wrong zone and basically when you allocate it back, since you put 248 00:26:03,909 --> 00:26:10,157 it on on a different size zone, you can have a heap overflow. So that's a general 249 00:26:10,157 --> 00:26:14,021 overview of this technique. So but you corrupt this struct and you get primitive 250 00:26:14,021 --> 00:26:21,840 exploitation primitives. Okay, so what was the idea I had at that point? The idea 251 00:26:21,840 --> 00:26:28,659 was to use the... this pis_ioctl_list index bug to corrupt this kdata pointer 252 00:26:28,659 --> 00:26:38,370 here and to have arbitrarily... Sorry, we have a relative leak of kernel heap 253 00:26:38,370 --> 00:26:44,760 memory, and that would be my first step towards exploiting the bug. Of course the 254 00:26:44,760 --> 00:26:52,480 end goal is to have arbitrary read/write, right, and of course it was just a fuzzy 255 00:26:52,480 --> 00:26:56,269 idea at that point and you know that's always the goal, but when you study the 256 00:26:56,269 --> 00:27:03,620 bug and you see the different code paths and how the things you affect are used, 257 00:27:03,620 --> 00:27:08,330 then you have some maybe not completely concrete things in your mind, but you know 258 00:27:08,330 --> 00:27:14,234 that interesting things can happen, so that's what I had at that point. 259 00:27:14,234 --> 00:27:23,871 Okay, so let's talk about the exploitation strategies now. So at stage one I sprayed 260 00:27:23,871 --> 00:27:31,399 the kernel heap with vm_map_copy structs and I decided to work on the kalloc.256 261 00:27:31,399 --> 00:27:36,279 zone, and the reason for that was completely arbitrary... was because of all 262 00:27:36,279 --> 00:27:40,590 the kernel debugging I have done up to this point of this entire binary I saw 263 00:27:40,590 --> 00:27:45,860 that this kalloc zone was not really used that much, either by the kernel or by 264 00:27:45,860 --> 00:27:51,970 whatever the exploit was doing. So... that's good because it means that you 265 00:27:51,970 --> 00:27:55,950 can... you as an exploiter can have much better control over the kernel heap if 266 00:27:55,950 --> 00:28:04,701 there aren't other things placing allocations on the zone you work. So I 267 00:28:04,701 --> 00:28:12,610 decided to use the kalloc.256 zone and I avoided of course kalloc.384 because the 268 00:28:12,610 --> 00:28:20,559 tty structs were going there and that would really mess up my heap arrangements. 269 00:28:20,559 --> 00:28:30,286 So the first... let me actually... ok. So what I wanted to do was to do this. 270 00:28:30,286 --> 00:28:37,249 So initially you spray the heap with vm_map_copy structs and you control both 271 00:28:37,249 --> 00:28:41,820 their size and their contents, the content don't matter at this point. So it... just 272 00:28:41,820 --> 00:28:48,419 the size matters. So I spray with 256 bytes vm_map_copy structs and then I free 273 00:28:48,419 --> 00:28:53,131 every other second one and I create this kind of pattern like a vm_map_copy and a 274 00:28:53,131 --> 00:28:59,210 free slot and a vm_map_copy and a free slot and then I grow the pis_ioctl_list 275 00:28:59,210 --> 00:29:08,620 array to 256 bytes and then it goes into one of these free slots here. Now, the 276 00:29:08,620 --> 00:29:14,990 code for doing that looks something like that, so what this basically does it 277 00:29:14,990 --> 00:29:24,509 sends... it creates this... so if you see here the out of line mach messages as 278 00:29:24,509 --> 00:29:31,570 basically these vm_map_copy structs and... Their size is 256, their buffer doesn't 279 00:29:31,570 --> 00:29:37,950 matter at this point and you just send them like machs and methods. And then 280 00:29:37,950 --> 00:29:42,990 after you've sprayed with them then you free every second one here... with this 281 00:29:42,990 --> 00:29:51,779 loop here. So in order to make this free slot you just receive this mach out of 282 00:29:51,779 --> 00:29:58,027 line messages that correspond to the vm_map_copy structs. And after you've 283 00:29:58,027 --> 00:30:04,519 created the holes you basically grow the array to 256 bytes. How do you do that? As 284 00:30:04,519 --> 00:30:12,010 I mentioned earlier you open the dev ptmx device a number of times. How many times 285 00:30:12,010 --> 00:30:18,429 doesn't matter, like a specific number of times that I mentioned earlier, that I 286 00:30:18,429 --> 00:30:26,370 have noticed grows it 256 bytes. So that's the arrangement you have at that first 287 00:30:26,370 --> 00:30:35,520 stage. Okay, so the second stage is done on the kalloc.88 zone. So I spray again 288 00:30:35,520 --> 00:30:41,640 with vm_map_copy structs and this time I make them 88 bytes to go to 289 00:30:41,640 --> 00:30:50,570 the kalloc.88 zone and then I create again holes. And then I trigger the bug with an 290 00:30:50,570 --> 00:30:56,250 invalid index value and remember that when you trigger the bug a ptmx_ioctl struct is 291 00:30:56,250 --> 00:31:01,610 allocated and this goes to kalloc.88. But because on kalloc.88 I have created this 292 00:31:01,610 --> 00:31:06,840 pattern of used free used free it goes into one of the free slots. So now I have 293 00:31:06,840 --> 00:31:13,620 a ptmx_ioctl struct in one of my free slots. I don't know where that is but I 294 00:31:13,620 --> 00:31:23,089 know that it falls into the pattern, right, so I trigger the bug and remember 295 00:31:23,089 --> 00:31:29,200 that basically you control this index, right, so since I control the index I 296 00:31:29,200 --> 00:31:35,270 point it to the vm_map... to the kdata element of the vm_map_copy struct that I 297 00:31:35,270 --> 00:31:39,809 know is below the free slot that the array went into. I don't know the address, 298 00:31:39,809 --> 00:31:46,950 right, I can't put like an address there, but I can... I know the relatives... the 299 00:31:46,950 --> 00:31:52,330 relative distance in bytes because I created the pattern... the heap pattern. 300 00:31:52,330 --> 00:31:58,289 So let's go to... okay. So it looks like that. So that's my first stage, right, 301 00:31:58,289 --> 00:32:02,594 free, vm_map_copy, ... and this is the same pattern on the kalloc.88 zone. 302 00:32:02,594 --> 00:32:08,000 When you trigger the bug, this ptmx_ioctl structure is allocated. It goes into one 303 00:32:08,000 --> 00:32:16,590 of the free slots, right, and then the bug itself, which is what we see here is... 304 00:32:16,590 --> 00:32:21,340 remember you control the index, so this is the new allocation that went here, and 305 00:32:21,340 --> 00:32:27,210 then it goes and stores the address where the index tells it to store it. But 306 00:32:27,210 --> 00:32:31,499 remember that this is controlled, we control that, so what I do I point this 307 00:32:31,499 --> 00:32:36,809 here relatively to the neighboring vm_map_copy struct at the kdata field, 308 00:32:36,809 --> 00:32:42,465 right. So in this kdata field here of the vm_map_copy struct I have now this 309 00:32:42,465 --> 00:32:52,740 address, right. So that's how the heap looks like. I have here the code, it's 310 00:32:52,740 --> 00:33:00,660 very similar to the first stage that you spray with vm_map_copy structs of size 88, 311 00:33:00,660 --> 00:33:05,919 machs and methods, right, and then you receive every second one, you create the 312 00:33:05,919 --> 00:33:15,909 holes on the 88 zone and then you trigger the bug here, right. This invalid pis 313 00:33:15,909 --> 00:33:29,610 index number here is basically what points relatively here, right. So I have now the 314 00:33:29,610 --> 00:33:37,179 address of this ptmx_ioctl struct which is an address on the kalloc.88 zone. I have 315 00:33:37,179 --> 00:33:42,669 it on the kdata field of this vm_map_copy struct here. So what I do... I can simply 316 00:33:42,669 --> 00:33:51,350 receive these methods and in its content I can see the address of that slot on the 317 00:33:51,350 --> 00:34:00,539 kalloc.88 zone. So that's the code to do that, I simply receive all the messages 318 00:34:00,539 --> 00:34:12,080 and that's my address. Okay, so at this point I only... what I only have is this 319 00:34:12,080 --> 00:34:21,500 address here, right? I have the address of this heap slot. So, at that point I 320 00:34:21,500 --> 00:34:28,699 started looking at other code paths that this invalid index... what other 321 00:34:28,699 --> 00:34:34,595 variables this invalid index was influencing and I found the code path that 322 00:34:34,595 --> 00:34:40,270 was actually giving... was giving me a write and... But in order to reach that I 323 00:34:40,270 --> 00:34:45,570 needed to survive several dereferences, and what I only knew was just the 324 00:34:45,570 --> 00:34:50,790 kalloc.88 address, right? Nothing else. So I will now walk you through everything 325 00:34:50,790 --> 00:35:00,710 that gave me this write. So I clean up the kalloc.256 zone and I spray it again with 326 00:35:00,710 --> 00:35:06,384 vm_map_copy structs and create holes exactly like the previous step... 327 00:35:06,384 --> 00:35:15,073 the first stage. Again, next to the pis_ioctl_list array I have a vm_map_copy 328 00:35:15,073 --> 00:35:23,110 struct, but at this time I... in all the the vm_map_copy structs I put a payload of 329 00:35:23,110 --> 00:35:29,890 the... of this fake ptmx_ioctl address I have. And remember that the first element 330 00:35:29,890 --> 00:35:40,250 of the ptmx_ioctl struct is a pointer to tty struct and I can use the leaked 331 00:35:40,250 --> 00:35:44,860 address I have for this pointer that I don't know... I didn't know where to point 332 00:35:44,860 --> 00:35:52,880 it to. So, the next step was to clean up the kalloc.88 zone and spray it again, and 333 00:35:52,880 --> 00:35:58,650 again I sprayed with vm_map_copy structs, but at this time at their payload I can 334 00:35:58,650 --> 00:36:07,231 put now the fake tty struct that the ptmx_ioctl struct is pointing to. The 335 00:36:07,231 --> 00:36:15,780 problem at that point was that the tty struct with 256 bytes and kalloc.88 has... 336 00:36:15,780 --> 00:36:22,480 the slots are only 88 bytes, so I couldn't just with the elements of the... just with 337 00:36:22,480 --> 00:36:29,311 the first 88 byte elements, I couldn't get to the path that was giving the write, so 338 00:36:29,311 --> 00:36:44,730 I needed to find some other way to host my fake tty struct. So remember that I 339 00:36:44,730 --> 00:36:50,730 couldn't work on any other kalloc zone or anywhere else because what I only knew was 340 00:36:50,730 --> 00:36:59,207 the address of that kalloc.88 zone, I had nothing else to build on. So at that point 341 00:36:59,207 --> 00:37:07,070 I started doing a much more complicated heap arrangement. So instead of spraying 342 00:37:07,070 --> 00:37:15,830 just one thing I was spraying... I was trying to create a pattern of two 343 00:37:15,830 --> 00:37:20,480 controlled things. Now, I couldn't use vm_map_copy structs for both these slots 344 00:37:20,480 --> 00:37:24,930 because the vm_map_copy structs has a header, right? So it would mess up my 345 00:37:24,930 --> 00:37:34,390 fake tty struct. So by reading i0n1c's kernel heap exploitation slides, I 346 00:37:34,390 --> 00:37:40,828 realized that I could spray the heap with XML properties of length 88 from that 347 00:37:40,828 --> 00:37:48,411 AppleJPEGDriver and I could place as a second controlled object after the 348 00:37:48,411 --> 00:37:53,130 vm_map_copy struct these XML properties which are completely controlled in 349 00:37:53,130 --> 00:37:58,190 content, and I could host the second part of the tty struct there. I mean, it's 350 00:37:58,190 --> 00:38:06,190 still not 256 bytes, but what it gives me is the ability to survive all dereferences 351 00:38:06,190 --> 00:38:14,430 to reach the write that I was interested in. Okay. So, a few things about the 352 00:38:14,430 --> 00:38:20,080 tty struct. So that's what I got... I wanted to create on the kalloc.88 zone, 353 00:38:20,080 --> 00:38:28,051 right, so that's the tty struct that the ptmx_ioctl struct is pointing to. Now, 354 00:38:28,051 --> 00:38:38,230 what basically I wanted to do here is I wanted to point... the final thing was 355 00:38:38,230 --> 00:38:45,610 to use this clist struct to control this element here, c_cs, as a start of the ring 356 00:38:45,610 --> 00:38:50,609 buffer for the tty, to give me an arbitrary write... Sorry, to give me a 357 00:38:50,609 --> 00:38:56,500 controlled write. I started playing a bit with to use it to do arbitrary write, but 358 00:38:56,500 --> 00:39:04,340 I found that I wasn't able to do it because at later stage some other parts of 359 00:39:04,340 --> 00:39:09,957 the tty struct were needed that I wasn't able to control, so I only had two 360 00:39:09,957 --> 00:39:17,500 88-slots to host my fake tty struct. So that wasn't stable. So I was only 361 00:39:17,500 --> 00:39:25,660 using that to do a relative write. So we'll see the code later on, let's go to 362 00:39:25,660 --> 00:39:32,430 the heap layout. So that's the third stage. Again, remember I sprayed the 363 00:39:32,430 --> 00:39:38,940 kalloc.256 zone with vm_map_copy structs/ frees, just place my pis_ioctl_list array 364 00:39:38,940 --> 00:39:43,150 next to vm_map_copy struct. Remember that I control the contents of vm_map_copy, 365 00:39:43,150 --> 00:39:52,270 right, so I placed in the buffer of vm_map_copy this ptmx_ioctl address that I 366 00:39:52,270 --> 00:39:59,650 know and I point the invalid index that I control to this ptmx_ioctl... this address 367 00:39:59,650 --> 00:40:03,830 that I put here. And what is this address? It's that leaked address that I got in the 368 00:40:03,830 --> 00:40:11,550 previous stage which points to the kalloc.88 zone. And what's the arrangement 369 00:40:11,550 --> 00:40:16,780 of that kalloc.88 zone? It's as I told you a vm_map_copy followed by an XML properties. 370 00:40:16,780 --> 00:40:21,170 vm_map_copy, XML properties... And all this hosts this fake tty struct, right? 371 00:40:21,170 --> 00:40:28,160 All these are the same, I just explained here how it looks like. So this points to 372 00:40:28,160 --> 00:40:35,090 the kdata element here and the rest of it holds the rest of the... all this is 373 00:40:35,090 --> 00:40:39,660 basically the fake tty struct, like the buffer of the vm_map_copy and then 374 00:40:39,660 --> 00:40:47,370 following the XML contents of this heap allocation. And where do I... this c_cs 375 00:40:47,370 --> 00:40:53,045 pointer that I told you that I wanted to control, where do I point it? I point it 376 00:40:53,045 --> 00:40:56,572 relatively again, I don't know any addresses but I can put it relatively 377 00:40:56,572 --> 00:41:02,420 since I know the... since I created this heap arrangement, I can put it relatively 378 00:41:02,420 --> 00:41:07,380 to the size of the kalloc size of the neighboring vm_map_copy struct. And why do 379 00:41:07,380 --> 00:41:13,720 I need this? Because I want to use the vm_map_copy technique by Mandt and Dowd 380 00:41:13,720 --> 00:41:20,060 that I mentioned earlier, so that's the end goal. So what's the code looks like? 381 00:41:20,060 --> 00:41:25,910 Okay, that's the spray of 256, we've seen that a lot of times, then we have the 382 00:41:25,910 --> 00:41:34,004 freeze... wait, no, that's not the freeze. So that's the allocations of the 256... 383 00:41:34,004 --> 00:41:37,864 that's... yeah, I don't have the freeze here because they don't matter, because we 384 00:41:37,864 --> 00:41:42,880 have seen them before. So what I have here is the spray of the kalloc.88 zone and the 385 00:41:42,880 --> 00:41:46,720 important thing here is that... what I wanted to show you that is that at every 386 00:41:46,720 --> 00:41:53,510 step I took two allocations. One is the vm_map_copy struct here with the machs and 387 00:41:53,510 --> 00:42:00,840 methods, and the second part is the XML properties, which are sprayed on the heap 388 00:42:00,840 --> 00:42:09,920 when you open the device driver, the AppleJPEGDriver. And what are the contents 389 00:42:09,920 --> 00:42:15,590 of that XML properties? They're basically that fake... the second part of the fake 390 00:42:15,590 --> 00:42:20,282 tty struct that you have the controlled c_cs pointer that will give me the 391 00:42:20,282 --> 00:42:27,438 relative write. So if you see here, I have this function setup_fake_tty that 392 00:42:27,438 --> 00:42:33,230 basically creates the structs so I don't have to type all the time, and we are at 393 00:42:33,230 --> 00:42:37,740 second stage here, and basically what you can see here is the creation of the 394 00:42:37,740 --> 00:42:41,770 fake tty struct, right? So that's the different elements of the fake tty as we 395 00:42:41,770 --> 00:42:47,690 saw it from the code. And that's the write offset I wanted to... that I pointed to 396 00:42:47,690 --> 00:42:54,050 the kdata field of the neighboring vm_map_copy struct. So, again, that's how 397 00:42:54,050 --> 00:43:02,360 it looks like in the heap. Okay, so after that, after we have arranged the... we 398 00:43:02,360 --> 00:43:08,780 have arranged it this way, we trigger again the invalid index array bug, but at 399 00:43:08,780 --> 00:43:13,920 this time on the slave ptmx device. I was only doing that on a master ptmx device, 400 00:43:13,920 --> 00:43:18,070 but in order to reach that write code path that I mentioned, you need to get on a 401 00:43:18,070 --> 00:43:24,080 slave ptmx device. So that's what happens here. And then you simply write to the 402 00:43:24,080 --> 00:43:29,830 corresponding descriptor and it just dereferences this c_cs that you controlled 403 00:43:29,830 --> 00:43:33,860 and your end... and it writes with whatever you want to write. And what do I 404 00:43:33,860 --> 00:43:39,010 want to write? I want to write a new size for the vm_map_copy struct... for the 405 00:43:39,010 --> 00:43:42,841 kalloc size field of the vm... of the neighboring vm_map_copy struct, so I can 406 00:43:42,841 --> 00:43:52,730 use the Dowd and Mandt technique. So, putting everything together. So at that 407 00:43:52,730 --> 00:43:57,410 point I have a controlled corruption of a vm_map_copy struct and I can use the 408 00:43:57,410 --> 00:44:04,000 primitives to get arbitrary... an arbitrary leak, so I can leak for example 409 00:44:04,000 --> 00:44:10,230 the KSLR-slide and I can do a heap overflow. Again these are how you can use 410 00:44:10,230 --> 00:44:18,580 the primitives that Mandt and Dowd gave us. Now I also know my location on the 411 00:44:18,580 --> 00:44:24,610 kernel heap, and remember that... that's basically... we found that on the stage... 412 00:44:24,610 --> 00:44:29,380 on the first... on the first of stages and we only... we use only that, like where 413 00:44:29,380 --> 00:44:36,580 that ptmx_ioctl struct was stored on the kernel heap, that's the only thing we 414 00:44:36,580 --> 00:44:41,770 knew, that address, in order to successively build on it, in order to 415 00:44:41,770 --> 00:44:47,200 reach like a much more useful primitive. And the important... the interesting thing 416 00:44:47,200 --> 00:44:50,690 here is that everything up to this point is data only, right? So you haven't 417 00:44:50,690 --> 00:44:55,090 injected any code, you haven't done anything at all that you could be caught 418 00:44:55,090 --> 00:45:00,850 somehow by a kernel self-protection mechanism or these kind of things, 419 00:45:00,850 --> 00:45:10,310 everything's data only. So once you reach that point, how do you get PC control? So 420 00:45:10,310 --> 00:45:18,400 since you can use Dowd's and and Mandt's technique, you can basically do a heap 421 00:45:18,400 --> 00:45:23,480 overflow, so you can again do a heap arrangement, you can place IOKit objects 422 00:45:23,480 --> 00:45:31,000 next to vm_map_copy structs where you can overflow from, and you can corrupt IOKit 423 00:45:31,000 --> 00:45:36,840 objects and from there you can have... also you can do an arbitrary write... 424 00:45:36,840 --> 00:45:43,470 read/write, so you can... by the arbitrary read you can read the vtables of the IOKit 425 00:45:43,470 --> 00:45:48,650 objects so you know the KSLR-slide and you can corrupt it in order to get PC 426 00:45:48,650 --> 00:45:55,500 control. Of course getting to a whole jailbreak from that point is out of the 427 00:45:55,500 --> 00:46:01,030 scope of this talk, and... but is not that hard actually from that point on. And 428 00:46:01,030 --> 00:46:09,551 okay, so after doing all that how close was that exploit to the evasi0n... to the 429 00:46:09,551 --> 00:46:15,660 real evasi0n7 kernel exploiter? I'd say it was pretty far off, but I mean it wasn't 430 00:46:15,660 --> 00:46:22,040 my point to recreate it like completely, but it was my point to play with the heap 431 00:46:22,040 --> 00:46:29,260 and to try to do complex heap arrangements and to see how much I understand the iOS 432 00:46:29,260 --> 00:46:36,730 kernel heap, that was the point of this whole exercise for me. Okay, so some 433 00:46:36,730 --> 00:46:44,290 lessons learned. So the real surprising thing for me at that point was that I 434 00:46:44,290 --> 00:46:52,760 couldn't believe that Apple does kernel debugging by KDB. It was very flaky, it 435 00:46:52,760 --> 00:46:57,630 was very unstable as I told you. If you type commands too fast it froze, if you 436 00:46:57,630 --> 00:47:03,430 type commands very slowly it had like a go-stop timer and froze, I think. 437 00:47:03,430 --> 00:47:08,280 there was a claim of something like that and it's unbeliev... I couldn't believe 438 00:47:08,280 --> 00:47:14,670 that the Apple engineers were using this interface to do kernel debugging. So it 439 00:47:14,670 --> 00:47:23,730 was really hard to do anything on the kernel side of idevices. But of course I 440 00:47:23,730 --> 00:47:27,280 don't really mean that you shouldn't mess with these things, right? I mean, these 441 00:47:27,280 --> 00:47:31,941 devices are really interesting and it's really becoming harder to hack them, but I 442 00:47:31,941 --> 00:47:37,070 think it's much more fun and I think the only takeaway may be that you shouldn't 443 00:47:37,070 --> 00:47:41,310 report bugs to Apple at all and if you need street cred you should just report 444 00:47:41,310 --> 00:47:48,060 white elephant bugs now. I mean that's always good. And I mean this very... this 445 00:47:48,060 --> 00:47:52,220 is getting very esoteric, right, there are not a lot of information and Apple keeps 446 00:47:52,220 --> 00:47:55,690 changing stuff and everything is closed source, I mean, all the important parts 447 00:47:55,690 --> 00:48:01,110 are closed source... and I mean, I really think people that work on that things 448 00:48:01,110 --> 00:48:08,240 should share notes as much as possible. Okay, so these are some of the people I 449 00:48:08,240 --> 00:48:15,190 was talking to while doing all this and I want to mention them, and basically that's 450 00:48:15,190 --> 00:48:21,570 all of the material I have and I'm open to any questions you might have. 451 00:48:21,570 --> 00:48:32,850 *applause* Herald: Thank you, argp, for the talk. So 452 00:48:32,850 --> 00:48:42,831 we have prepared microphones 1, 2, 3 and 4 in the room and we have a Signal Angel, I 453 00:48:42,831 --> 00:48:50,870 think. You... when you have questions, you can give me a hand sign, but I 454 00:48:50,870 --> 00:48:58,050 think we start with microphone 2 here in the front. And please ask questions and no 455 00:48:58,050 --> 00:49:01,510 comments, there's time after the talk. Okay, go ahead. 456 00:49:01,510 --> 00:49:03,830 Q: Thanks for the awesome talk. argp: Thanks. 457 00:49:03,830 --> 00:49:11,960 Q: I have a question about heap spraying. Was your heap spraying really stable? If 458 00:49:11,960 --> 00:49:17,080 it is not successful, did it crash the device? 459 00:49:17,080 --> 00:49:21,850 argp: Yeah. So I haven't mentioned it here, but it was pretty stable I think. 460 00:49:21,850 --> 00:49:25,130 It was something like... because I did a lot of tests for that because it was 461 00:49:25,130 --> 00:49:31,480 really interesting for me to know. It was maybe something like 90%, so 9 out of 10 462 00:49:31,480 --> 00:49:35,141 times it worked, but if it didn't work - yeah, then... yes it crashed the kernel 463 00:49:35,141 --> 00:49:40,250 and crashed the device, yeah. Q: And did you try to return heap into 464 00:49:40,250 --> 00:49:44,990 some kind of initial state to start your exploit from scratch? 465 00:49:44,990 --> 00:49:50,230 argp: Yeah, that's true I haven't included that, but you're right. So the initial 466 00:49:50,230 --> 00:49:56,860 step on every spray that I mentioned here was to spray a lot of objects of the 467 00:49:56,860 --> 00:50:01,740 specific size you were targeting in order to get basically a new page of the kalloc 468 00:50:01,740 --> 00:50:07,120 zone, right? So you... so even if as I told you the kalloc 256 zone wasn't 469 00:50:07,120 --> 00:50:11,220 that busy, it's still... there were still allocations going on it, right? So if you 470 00:50:11,220 --> 00:50:16,390 did a lot of initial spraying, you were making sure that when you're... the 471 00:50:16,390 --> 00:50:21,690 allocations that mattered to you we're made, were on a new page that weren't... 472 00:50:21,690 --> 00:50:24,110 wasn't too much noise from other allocations from the kernel. So yeah, 473 00:50:24,110 --> 00:50:26,930 you're right I haven't included that, but yeah, that happened. 474 00:50:26,930 --> 00:50:29,900 Q: Thanks, great. argp: Thanks. 475 00:50:29,900 --> 00:50:36,200 Herald: Then microphone 1, please. Q: Also thank you for your awesome talk 476 00:50:36,200 --> 00:50:37,710 again. argp: Thanks. 477 00:50:37,710 --> 00:50:43,609 Q: My question was nowadays it's way harder to use vm_copy I think Apple truly 478 00:50:43,609 --> 00:50:49,480 deprecated it, it's not possible anymore that due to security. Do you see hope in 479 00:50:49,480 --> 00:50:54,560 reconstructing some function that does the same or is it totally dead now? 480 00:50:54,560 --> 00:50:57,780 argp: Oh, you mean the vm_map_copy technique? 481 00:50:57,780 --> 00:51:00,740 Q: Yes. argp: No, I think it's completely dead 482 00:51:00,740 --> 00:51:03,940 now. Q: All right. And I recently saw on the 483 00:51:03,940 --> 00:51:10,310 iOS logs vulnerabilities that again a vulnerability in AppleJPEGDriver was 484 00:51:10,310 --> 00:51:15,060 found. Do you think... have you looked into it or... 485 00:51:15,060 --> 00:51:20,050 argp: Well, Apple... the AppleJPEGDriver is one of the 4, I think, IOkit drivers 486 00:51:20,050 --> 00:51:25,820 that you can reach from the container sandbox, right? So that means it's very 487 00:51:25,820 --> 00:51:31,260 fast by everyone, Apple included, and very audited. So I'm not saying that there 488 00:51:31,260 --> 00:51:36,170 aren't many... there aren't things there, like interesting findings, but if there 489 00:51:36,170 --> 00:51:38,640 are they're not going to live much longer, I think. 490 00:51:38,640 --> 00:51:41,680 Q: Okay, thank you. Herald: Thanks for your question and now 491 00:51:41,680 --> 00:51:45,000 from the Signal Angel a question from the Internet. 492 00:51:45,000 --> 00:51:48,650 Signal Angel: Yes, I have a question from the internet. How long did this research 493 00:51:48,650 --> 00:51:52,800 take you? You said two weeks in the beginning, but from begin to end, how many 494 00:51:52,800 --> 00:51:55,430 hours about? Because you also said it was during work? 495 00:51:55,430 --> 00:51:59,750 argp: No, it didn't it didn't take two weeks, no. It took like maybe close to 496 00:51:59,750 --> 00:52:05,030 three months or two months and something like that. So I spent... as I mentioned I 497 00:52:05,030 --> 00:52:09,190 spent like a complete month, I think, like - maybe three weeks, maybe not a complete 498 00:52:09,190 --> 00:52:16,560 month just on reversing redsn0w and trying to get redsn0w to play with iOS7. So I 499 00:52:16,560 --> 00:52:21,790 wouldn't count this month in the exploit part of it, right? So if you're interested 500 00:52:21,790 --> 00:52:29,000 just in the kernel exploit part I would say something like maybe seven weeks, 501 00:52:29,000 --> 00:52:36,170 something like that. But just with 2 maybe 3 days per week right, not complete weeks. 502 00:52:36,170 --> 00:52:40,240 Herald: Okay, then microphone 1, please. 503 00:52:40,240 --> 00:52:45,740 Q: Congratulations on your talk which was really interesting, I liked it a lot and 504 00:52:45,740 --> 00:52:51,090 my question is if the technique you used to exploit the bug was in FreeBSD or any 505 00:52:51,090 --> 00:52:56,320 other BSD as well? argp: Oh no, no. I mean, the vm_map_copy 506 00:52:56,320 --> 00:53:02,900 struct doesn't exist anywhere else except the XNU kernel. But I think the 507 00:53:02,900 --> 00:53:06,921 interesting takeaway is that you can do complex heap arrangements if you 508 00:53:06,921 --> 00:53:13,960 understand the kernel heep allocator, right? So this process I described by 509 00:53:13,960 --> 00:53:18,740 creating holes and maybe controlling 2 allocations in order to host fake 510 00:53:18,740 --> 00:53:24,630 structures that you are able then to use to get exploitation primitives then that's 511 00:53:24,630 --> 00:53:30,740 applicable everywhere, right? Herald: Okay, then we go to microphone 2 512 00:53:30,740 --> 00:53:35,810 again, please. Q: So I saw one sentence, just not report 513 00:53:35,810 --> 00:53:42,830 or... just don't report the bugs. I would like to understand your thinking behind, 514 00:53:42,830 --> 00:53:48,980 because I think this is really important for companies to know the bugs that they 515 00:53:48,980 --> 00:53:54,800 made and yeah, make the products better and this is really beneficial for 516 00:53:54,800 --> 00:54:00,950 researcher because for example Apple they pay a lot of money for the bugs. What... 517 00:54:00,950 --> 00:54:07,050 argp: Okay, yeah, I don't have much to say on that. I mean, apart from: if all the 518 00:54:07,050 --> 00:54:11,030 bugs are fixed then you won't be able to do this kind of work and it's no fun. 519 00:54:11,030 --> 00:54:17,760 Sorry, I don't have anything else to say on that. Sorry, I don't have anything 520 00:54:17,760 --> 00:54:23,140 else, no comment. Herald: Okay. Signal Angel, do we have 521 00:54:23,140 --> 00:54:31,310 another question from the internet? Okay, then please a big round of applause for 522 00:54:31,310 --> 00:54:33,539 our speaker! argp: Thanks. 523 00:54:33,539 --> 00:54:35,233 *applause* 524 00:54:35,233 --> 00:54:39,864 *postroll music* 525 00:54:39,864 --> 00:54:57,000 subtitles created by c3subtitles.de in the year 2020. Join, and help us!