0:00:00.099,0:00:15.129 34c3 preroll music 0:00:15.129,0:00:19.695 Herald Angel: And now I want to introduce[br]our first speaker and the topic he's 0:00:19.695,0:00:27.844 talking about. iOS kernel exploitation[br]archaeology. A kernel exploit from late[br] 0:00:27.844,0:00:35.231 2013 early 2014 will be digged out and[br]analyzed proper archaeology all the 0:00:35.231,0:00:43.165 digging... digging and analysis is done by[br]argp here to my left on the stage and give 0:00:43.165,0:00:46.586 him a big round of applause. And the stage[br]is yours, thanks. 0:00:46.586,0:00:47.882 Applause 0:00:47.882,0:00:58.883 argp: Thanks for the introduction. First[br]of all, thank you all for being here. As 0:00:58.883,0:01:03.899 the person that did the introduction told[br]you this is going to be an archeology talk 0:01:03.899,0:01:09.939 so I apologize in advance if it's not that[br]interesting for you. So we'll talk about a 0:01:09.939,0:01:16.310 bit older stuff rather than new things.[br]Okay so a bit a few things about myself. 0:01:16.851,0:01:20.923 Actually, I think from all these things,[br]the most important are the the Phrack 0:01:20.923,0:01:26.830 papers, right? So, yeah. Let's ignore all[br]the other stuff okay? So, what I'm going 0:01:26.830,0:01:35.059 to talk about. I'm going to talk about the[br]evasi0n7 kernel exploit. Now evasi0n7 was 0:01:35.059,0:01:42.060 a jailbreak it was released by the evad3rs[br]on the 22nd of December 2013. It supported 0:01:42.060,0:01:50.210 iOS7 to iOS7.1 beta 3. That's not the[br]7.1 stable release, right? So that's a 0:01:50.210,0:01:55.759 beta. And this supported all devices at[br]that time including the iPhone 5s which 0:01:55.759,0:02:03.999 was the first 64-bit device except the[br]Apple TV. So, I decided to reverse 0:02:03.999,0:02:08.900 engineer the kernel exploit of the[br]jailbreak focused just on that. Because I 0:02:08.900,0:02:14.170 was really interested, not so much in the[br]bug itself, which was as we will see not 0:02:14.170,0:02:18.805 very complicated. But I was really[br]interested to understand the exploitation 0:02:18.805,0:02:25.970 techniques that the evad3rs used. So, I[br]started reversing it, and I understanding 0:02:25.970,0:02:32.329 it, and at some point I just said I'm just[br]gonna do a reimplementation of the kernel 0:02:32.329,0:02:37.030 exploit. So, this talk is basically my[br]notes on this whole process. And, of 0:02:37.030,0:02:42.390 course, it's not a jailbreak walkthrough,[br]right? And I'm going to specifically focus 0:02:42.390,0:02:50.042 on the various problems I encountered[br]during this task and how I overcame them. 0:02:50.042,0:02:58.250 And hopefully it's going to give you some[br]helpful takeways for if you do iOS kernel 0:02:58.250,0:03:05.459 research nowadays. Okay, so, the general[br]outline is I'm going to say a few things 0:03:05.459,0:03:11.730 about the version 7 to setup the stage.[br]And then I'm going to explain the kernel 0:03:11.730,0:03:18.971 bug itself. And, then I'm going to talk in[br]length about my debugging setup. And, I 0:03:18.971,0:03:26.136 think that's a very important step that[br]usually phone or embedded talks 0:03:26.136,0:03:29.860 exploitation talks don't analyze that[br]much, and I think it's a really important 0:03:29.860,0:03:36.220 part. Because usually having a working the[br]debugging set up is, basically, maybe half 0:03:36.220,0:03:41.080 the job of doing a reliable exploit. Then[br]I'm going to do to talk about my 0:03:41.080,0:03:46.520 reimplementation of the exploit, and[br]hopefully, at the end, we're gonna have 0:03:46.520,0:03:53.870 some things to take away or maybe not. We[br]will see. Okay so it was the evasi0n7 0:03:53.870,0:03:59.300 jailbreak was released about 4 years ago.[br]And that's the archaeology in the title. 0:03:59.300,0:04:04.830 That's ancient history right? And if you[br]were following the jailbreak community, 0:04:04.830,0:04:12.120 you might remember this huge drama around[br]this jailbreak, initially, with geohot and 0:04:12.120,0:04:17.160 if he was planning or not to release it[br]before the evad3rs. And who he was 0:04:17.160,0:04:22.860 planning to sell it to, and some leaked[br]discussion that he had with some of that 0:04:22.860,0:04:31.070 he was offering money to buy. And geohot,[br]his jailbreak supposedly using 0:04:31.070,0:04:37.773 some of the bugs the evad3rs were using so[br]this is a huge drama. And then after the 0:04:37.773,0:04:43.320 evasi0n7 jailbreak released, like maybe a[br]few hours ago, people realize that if your 0:04:43.320,0:04:54.220 phone had a Chinese locale then the[br]jailbreak was installing a piracy app. So, 0:04:54.220,0:04:57.440 that was basically a third-party app that 0:04:57.440,0:05:00.660 was taking you to an[br]app store not operated 0:05:00.660,0:05:05.210 by Apple but by TaiG that had some pirated[br]versions of the real applications on the 0:05:05.210,0:05:12.700 App Store. And, of course, that also[br]create like a huge drama, this practice. 0:05:13.695,0:05:17.660 Okay, so a lot of things were said about[br]the jailbreak at that time and about the 0:05:17.660,0:05:23.820 TaiG pirate App Store. But what I really[br]set apart was this tweet. And the really 0:05:23.820,0:05:28.030 important thing that I like about this[br]tweet is, that it doesn't really make 0:05:28.030,0:05:31.430 sense. So he says that we have to decide[br]to remotely disable the default 0:05:31.430,0:05:35.285 installation of TaiG in China for further[br]investigations of the piracy. So that 0:05:35.285,0:05:40.740 whole thing doesn't make sense. So you[br]mean, you didn't know what was happening? 0:05:40.740,0:05:45.490 You didn't bundle it with a jailbreak? Are[br]you going to disable it for new 0:05:45.490,0:05:50.040 installations? And then, what does[br]remotely then mean exactly? So what about 0:05:50.040,0:05:56.290 the people that already had the apps, the[br]piracy app. How are you going to disable 0:05:56.290,0:06:04.520 that? Is that what remotely refers to? So[br]that's an excellent tweet I think. Okay, 0:06:04.520,0:06:11.370 so some point after the evasi0n7 jailbreak[br]was released geohot did a writeup on the 0:06:11.370,0:06:19.151 userland part of it. So, he analyzed how[br]the userland part worked and he stopped at 0:06:19.151,0:06:27.690 the point of gaining root and basically,[br]he mentioned in his writeup that the 0:06:27.690,0:06:33.185 evasi0n7 untethered binary, which[br]basically what was good doing the kernel 0:06:33.185,0:06:40.260 exploit, was obfuscated. And as we will[br]see this was indeed the case and as far as 0:06:40.260,0:06:46.038 I know that's the first jailbreak that[br]used the deliberate obfuscation. I don't 0:06:46.038,0:06:51.330 know the reason, I assume it's[br]partly to hide the the piracy 0:06:51.330,0:06:57.243 app store that was bundled with it and[br]maybe partly to hide the bug, the kernel 0:06:57.243,0:07:07.370 bug, but I'm not sure about the reason.[br]Now p0sixninja who found as far as I know 0:07:07.370,0:07:12.120 the bug, the kernel bug did a writeup on[br]the kernel bug, it's on the iPhone wiki, 0:07:12.120,0:07:17.630 and he basically describes the bug and he[br]stops at the point where he gets a crash 0:07:17.630,0:07:25.530 log from gdb. So he doesn't say anything[br]about how to exploit it. Okay, so after 0:07:25.530,0:07:31.250 all these things happened then I decided[br]to reverse engineer the untethered binary 0:07:31.250,0:07:37.180 and understand the exploitation techniques[br]and I was really interested to reverse 0:07:37.180,0:07:41.289 engineer the obfuscation that the evad3rs[br]were using, it seemed like an interesting 0:07:41.289,0:07:46.250 challenge, and... but as I also mentioned[br]earlier I was really interested to 0:07:46.250,0:07:49.795 understand the exploitation techniques[br]that they were using that was more 0:07:49.795,0:07:58.510 important for me at that time. And,[br]okay, so the jailbreak was released 0:07:58.510,0:08:06.337 December 2013 and I started doing that[br]around February 2014, and I did that while 0:08:06.337,0:08:10.310 having an actual day job, right, so I was[br]spending at most two days per week on 0:08:10.310,0:08:20.360 that. So what was my setup? I had an[br]iPhone 4, and if you know about iPhone 4s 0:08:20.360,0:08:25.570 they have a boot ROM bug called limera1n[br]which basically allows you to load 0:08:25.570,0:08:31.520 arbitrary kernels, unsigned kernels, on[br]the device and run them and that basically 0:08:31.520,0:08:38.049 means that you can very easily[br]set up kernel debugging. So initially I 0:08:38.049,0:08:46.026 had an iPhone 4 device with iOS 7.0.6. I[br]want to remind you that iPhone 4 is ARM32, 0:08:46.026,0:08:52.990 right. I also had an iPhone 5s with the[br]same version of iOS and I had that in 0:08:52.990,0:09:00.269 order to verify all my findings and all my[br]tests on - to redo my tests on an ARM64 0:09:00.269,0:09:06.279 device and as I told you - the iPhone 5s[br]at that time was the only ARM64 device. 0:09:06.279,0:09:10.480 Actually, I think on the market, I don't[br]think there was another consumer device 0:09:10.480,0:09:19.240 with ARM64 at that time. So that's the[br]exact version of version 7 I was analyzing 0:09:19.240,0:09:26.269 and of course IDA, gdb, lldb. Now the lols[br]in this slide they don't actually refer to 0:09:26.269,0:09:30.639 something funny they actually mean[br]something very painful and that caused a 0:09:30.639,0:09:37.090 lot of like sleepless nights, but I'll get[br]onto that. Okay, a few things about the 0:09:37.090,0:09:44.310 obfuscation. So, not all the functions of[br]the entire binary were obfuscated, but 0:09:44.310,0:09:51.980 some of the important ones were, and those[br]were the ones that were triggering the bug 0:09:51.980,0:09:56.930 and they were actually doing heap[br]manipulation and all the other important 0:09:56.930,0:10:01.180 things. Now I have been told, I haven't[br]checked that, but I have been told that 0:10:01.180,0:10:05.256 later versions remove the obfuscation but[br]I'm not sure about that, I haven't 0:10:05.256,0:10:09.769 verified it and I already had my[br]implementation done at that point so I 0:10:09.769,0:10:20.170 wasn't that interested to look at that. So[br]as I mentioned the kernel bug that the 0:10:20.170,0:10:26.733 evasi0n7 untethered binary was based on[br]was found by p0sixninja, and basically as 0:10:26.733,0:10:34.040 far as he says on that iPhone wiki page he[br]used that six line bash script fuzzer to 0:10:34.040,0:10:41.840 find it. So as you can see he basically[br]creates device nodes and, with 0:10:41.840,0:10:50.439 controlled arguments here like minor and[br]major numbers. Now in order to get to the 0:10:50.439,0:10:57.100 point to create device nodes you basically[br]need to be outside of the application 0:10:57.100,0:11:04.329 sandbox that exists on iOS and you also[br]need root privileges and that's what I 0:11:04.329,0:11:08.224 refer to as the userland part of the[br]evasi0n7 binary and I'm not going to cover 0:11:08.224,0:11:14.810 that at all. So I'm gonna start my[br]analysis from the point on that we have 0:11:14.810,0:11:19.321 escaped the sandbox, we have obtained[br]root and now we go to exploit the kernel 0:11:19.321,0:11:29.268 bug. Now that's code from that version of[br]the XNU kernel that had the bug. Now this 0:11:29.268,0:11:39.533 ptsd_open function is called everytime[br]userland code opens a /dev/ptmx device and 0:11:39.533,0:11:43.936 then this ptmx_get_ioctl function is[br]called. Now the important thing here 0:11:43.936,0:11:46.779 is that dev here is completely[br]user controlled and then 0:11:46.779,0:11:49.023 it's passed to this ptmx_get_ioctl 0:11:49.023,0:11:54.759 function with no checks at all, right, and[br]then this ptmx_get_ioctl function uses 0:11:54.759,0:11:59.949 this to index an array without any checks.[br]So basically the bug's an invalid indexing 0:11:59.949,0:12:05.618 bug, right, so since we can control that[br]you can put here whatever. I have here the 0:12:05.618,0:12:14.365 ptmx_ioctl struct that, okay, this array[br]here is, so this state struct here is 0:12:14.365,0:12:21.790 global to the kernel and this[br]pis_ioctl_list array here is on the kernel 0:12:21.790,0:12:30.418 heap and it is an array of ptmx_ioctl[br]structs and that's the PTMX ioctl struct 0:12:30.418,0:12:35.610 and the important thing here is, that[br]I'm going to refer to again and again 0:12:35.610,0:12:41.289 during the talk, is that it has a pointer[br]to a tty struct as the first element of 0:12:41.289,0:12:50.680 the structure. Okay, so we control the[br]index to the array, so what can we do with 0:12:50.680,0:12:57.349 that? So here as you can see it return[br]the ptmx_get_ioctl function returns 0:12:57.349,0:13:04.961 whatever it indexes, right. So, as you can[br]see here is it assigns this pti variable 0:13:04.961,0:13:10.682 and then does all kinds of interesting[br]things, so pti is controllable, tp is 0:13:10.682,0:13:14.163 controllable here as well after this[br]dereference here to some controllable 0:13:14.163,0:13:21.449 value and, I mean in other code parts of[br]the kernel this is called again and so 0:13:21.449,0:13:26.980 there are there are a lot of things to[br]consider when you know the bug and 0:13:26.980,0:13:33.788 then you try to think how to exploit it.[br]Okay, one important thing here that I 0:13:33.788,0:13:44.380 wanted to mention is that this ptmx,[br]this function here ptmx_get_ioctl also 0:13:44.380,0:13:51.850 does the allocation of this struct here,[br]of this tty struct here and that's 0:13:51.850,0:14:00.282 important because I'm going to use further[br]on. Okay, another important thing is that 0:14:00.282,0:14:05.934 you basically, this bug what allows you[br]to do is you can control the size of this 0:14:05.934,0:14:14.602 array here, so by, can you see that?[br]Okay, so by repeatedly open the ptmx 0:14:14.602,0:14:21.824 device you can grow this array and you can[br]grow it as you see here by this grow 0:14:21.824,0:14:29.830 vector that's 16, but it doesn't matter.[br]What matters is that the size of this 0:14:29.830,0:14:38.299 array in bytes is controllable by you, the[br]person who are trying to exploit this bug. 0:14:38.299,0:14:44.679 Now, for example these are notes from my[br]exploit so if I did one allocation, if I 0:14:44.679,0:14:51.239 did one open of this ptmx device then this[br]array was going into kalloc_64. If I was 0:14:51.239,0:14:59.089 doing 17 it was going to kalloc_128, if I[br]was doing 33 opens here it was going to 0:14:59.089,0:15:06.709 kalloc_192 and so on and so forth. So I[br]could decide in which kalloc zone I could 0:15:06.709,0:15:14.009 place the array. If you don't know kalloc[br]zones, they are basically, you can think 0:15:14.009,0:15:20.829 them as container, you can think kalloc[br]zones as containers for heap objects on 0:15:20.829,0:15:26.579 the kernel heap. All of them can be of[br]different type but they're, all of them 0:15:26.579,0:15:33.265 are of the same size, right, so kalloc_64[br]can have different structures of size 64 0:15:33.265,0:15:43.258 bytes, but all of them are our size 64[br]bytes. Okay so I started debugging the 0:15:43.260,0:15:49.936 untethered binary in userland, that's how[br]I started. So initially I was using gdb 0:15:49.936,0:15:57.889 and I found out that nothing worked with[br]gdb. It was at that point Apple was 0:15:57.889,0:16:01.641 starting to move from gdb to lldb, so I[br]don't, maybe that was the reason gdb 0:16:01.641,0:16:05.960 wasn't tested at all. So when I[br]say nothing worked I mean that I was 0:16:05.960,0:16:11.799 placing break points and they weren't[br]hitting and I was trying like stepping and 0:16:11.799,0:16:16.269 it was continuing execution and stuff like[br]that. Sometimes I couldn't even attach the 0:16:16.269,0:16:23.534 binary. So then I moved to lldb, on lldb[br]set up with debugserver and things were 0:16:23.534,0:16:29.489 much better. Now, while I was[br]experimenting stealing from, just with 0:16:29.489,0:16:35.436 userland debugging my iPhone 4 device went[br]to into a recovery loop and I wasn't able 0:16:35.436,0:16:46.339 to get out of it, so I was forced to do a[br]clean restore of the device. The problem 0:16:46.339,0:16:51.749 was that at that time only iOS 7.1 was[br]signed by Apple, so I couldn't install a 0:16:51.749,0:16:55.889 version of files that hit the kernel that[br]hit the bug that I was interested to look 0:16:55.889,0:16:59.610 at, but on the other hand I couldn't not[br]restore my device because that was the 0:16:59.610,0:17:05.240 only device I had at the point I could do[br]kernel debugging with. So I updated my 0:17:05.240,0:17:11.805 device to 7.1. As I said just told you 7.1[br]didn't have a vulnerable kernel 0:17:11.805,0:17:22.208 to this bug, so what I wanted to do was[br]basically to boot an iOS 7.1 device with a 0:17:22.208,0:17:27.990 7.0.6 kernel, and in order to do that I[br]could use the limera1n bug that allowed me 0:17:27.990,0:17:32.854 to boot arbitrary kernels and the utility[br]to do that was redsn0w, right. The problem 0:17:32.854,0:17:40.400 was that redsn0w only supported up to iOS[br]6 and it wasn't, it didn't have support 0:17:40.400,0:17:46.100 for iOS 7 so I left all the other things I[br]was doing and I started reversing redsn0w 0:17:46.100,0:17:51.530 to understand how it worked. Redsn0w, if[br]you don't know it's, it was back then 0:17:51.530,0:17:55.740 and still is closed source, right, so I[br]started reversing that to understand how 0:17:55.740,0:18:00.875 it worked in order to support, for me to[br]hot patch it, to binary 0:18:00.875,0:18:06.646 patch it to add support for iOS 7 and I[br]spent like I don't know maybe a month on 0:18:06.646,0:18:11.699 that and then I realized that it was, it[br]wasn't leading me anywhere, I couldn't 0:18:11.699,0:18:17.029 understand a lot of things about how[br]redsn0w was implemented, so I I stopped 0:18:17.029,0:18:25.700 doing that, and at that point I found[br]opensn0w which was an effort by winocm to 0:18:25.700,0:18:32.160 implement redsn0w as open source. So, it[br]seemed to have support for iOS 7 and that 0:18:32.160,0:18:40.120 was good, I tested that and it was[br]working. Now my problem was that I 0:18:40.120,0:18:44.460 couldn't have an arbitrary[br]length of boot-args. Boot-args are the 0:18:44.460,0:18:48.590 arguments that you pass to the kernel when[br]it boots and they are really important in 0:18:48.590,0:18:57.630 iOS because by passing certain boot-args[br]to the kernel you can disable sign checks, 0:18:57.630,0:19:02.320 you can enable kernel debugging, so it's[br]really important to be able to pass 0:19:02.320,0:19:09.470 arbitrary length boot-args. And iOS 7.1[br]was using absurd 9 character so that was 0:19:09.470,0:19:15.726 the reason opensn0w couldn't support more[br]So what I ended up doing was I patched 0:19:15.726,0:19:22.556 iBEC, which is basically the loader[br]of the kernel, right, that passes boot- 0:19:22.556,0:19:29.935 args to the kernel when it boots and,[br]basically I changed the pointer to the 0:19:29.935,0:19:35.571 boot-args to some other place that had[br]much more space. So at that point I was 0:19:35.571,0:19:41.619 able to pass arbitrary-length boot-args to[br]my kernel. So where we are at last? So I 0:19:41.619,0:19:50.358 had an iPhone 4 device with iOS 7.1 and I[br]was using opensn0w to boot the 7.0.6 0:19:50.358,0:19:56.795 kernel that had the bug that I was[br]interested to exploit. Now, one side note 0:19:56.795,0:20:04.161 here is that as I was doing that and I was[br]trying to add to open snow all the patches 0:20:04.161,0:20:09.762 to the kernel to enable kernel debugging,[br]I was reversing the evasi0n7 binary as 0:20:09.762,0:20:15.217 well. Now, the evasi0n7 binary was trying[br]also to, after it exploited the kernel 0:20:15.217,0:20:19.799 it was patching it to enable kernel[br]debugging, but, so I was just copying 0:20:19.799,0:20:23.740 their patches, right, and adding them to[br]opensn0w, but I realized at some point 0:20:23.740,0:20:29.919 that they missed some check for the debug-[br]enabled variable and KDP wasn't really 0:20:29.919,0:20:35.919 working, so the session was established[br]and it seemed like it was working, but if 0:20:35.919,0:20:40.934 you tried to actually use the kernel,[br]the KDP, the kernel debugging setup for 0:20:40.934,0:20:45.470 to do actual, like to attach debugger to[br]the kernel and do whatever, like place a 0:20:45.470,0:20:54.241 breakpoint or step then KDP just froze. So[br]I added another part that was required on 0:20:54.241,0:21:02.730 that. Ok, so kernel debugging at last, but[br]that's not really what happened, because 0:21:02.730,0:21:07.981 you know breakpoints didn't always work so[br]you were placing a breakpoint and it 0:21:07.981,0:21:12.708 wasn't hitting when execution was reaching[br]there and you were trying to step 0:21:12.708,0:21:17.340 instructions and the execution just[br]continues, so you were stepping one 0:21:17.340,0:21:21.210 instruction it was just like you would[br]type in continue and if you were taking 0:21:21.210,0:21:26.755 too long to type an lldb command then KDP[br]froze and then you had to restart your 0:21:26.755,0:21:33.261 device, re-establish the kernel debugging[br]session and start from zero. And if you 0:21:33.261,0:21:37.951 issue commands too fast then KDB froze[br]again, so you have to reboot again. It was 0:21:37.951,0:21:47.320 amazing, it was great time. And now I did[br]similar stuff with iOS 6 and I distinctly 0:21:47.320,0:21:53.110 remember that was much easier and kernel[br]debugging worked much better. And... I 0:21:53.110,0:21:58.669 mean the issue that comes to everyone's[br]mind that does that is: do Apple engineers 0:21:58.669,0:22:05.580 really use KDP for debugging the iOS[br]kernel or do they use something else? 0:22:06.240,0:22:15.330 Okay, so now I could debug the evasi0n7[br]untethered binary both from the userland 0:22:15.330,0:22:23.130 side and from the kernel side, and that[br]was good because I was analyzing at run 0:22:23.130,0:22:31.730 time and at the same time I was reversing[br]it in IDA, so the obfuscation who... I 0:22:31.730,0:22:38.480 could do it much faster since I was taking[br]hints from runtime. So I... at that point 0:22:38.480,0:22:42.860 things started moving fast and I quickly[br]found that it was abusing the data by 0:22:42.860,0:22:49.179 structure to obtain read/write access to[br]physical memory. I mean that was 0:22:49.179,0:22:52.940 interesting to me, but I was expecting[br]something else. I was expecting something 0:22:52.940,0:22:58.389 like what they did in iOS in the evasi0n6[br]jailbreak, that they did like a lot of 0:22:58.389,0:23:04.387 heap manipulation and that's my interest[br]actually, heap exploitation. So at that 0:23:04.387,0:23:10.370 point I decided to stop reversing it and[br]reimplement the exploit the way that I 0:23:10.370,0:23:16.190 wanted to do it. So obviously that wasn't[br]work from scratch, it was from everything 0:23:16.190,0:23:20.330 that I understood up to that point, and[br]what I really wanted to use was the 0:23:20.330,0:23:25.410 vm_map_copy structures technique by Dowd[br]and Mandt and I'm going to explain that in 0:23:25.410,0:23:31.669 the following slides, how it works.[br]Okay, so at that point I had the clear 0:23:31.669,0:23:37.090 understanding of the bug, what it was and[br]I had the general idea like about how to 0:23:37.090,0:23:41.779 exploit it and I mean if you've done[br]that you know then it takes a lot of pen 0:23:41.779,0:23:47.980 and paper like ideas you develop on paper,[br]then you go test them and they don't work 0:23:47.980,0:23:53.409 and then you design them again and then[br]again and you fail and you despair and 0:23:53.409,0:23:58.289 then you suddenly have an idea and you[br]spend like I don't know like two nights 0:23:58.289,0:24:04.029 stay up until 5:00 in the morning testing[br]things and they don't work and then you 0:24:04.029,0:24:10.700 despair again and ad nauseam. But[br]eventually you get somewhere so let's talk 0:24:10.700,0:24:18.630 about exploitation now. Now, a few things[br]to refresh your memory about the bug. So 0:24:18.630,0:24:26.200 as I said it was an invalid indexing bug.[br]This pis_ioctl_list array was on the heap 0:24:26.200,0:24:32.760 and I could control in which kalloc zone[br]it can go. I can grow it, but once I grow 0:24:32.760,0:24:42.700 it I cannot shrink it back. Now, that's[br]code from that ptmx_get_ioctl function, so 0:24:42.700,0:24:46.760 what... basically what it does it[br]allocates a new ptmx_ioctl structure and 0:24:46.760,0:24:53.294 then it uses the index that you provide...[br]that you control to store the address on 0:24:53.294,0:25:01.090 the array. Now, this allocation here...[br]this struct here goes into kalloc.88 and 0:25:01.090,0:25:07.895 that's useful for the next parts. Okay, a[br]few things about the technique I wanted to 0:25:07.895,0:25:13.000 use... about the exploitation technique I[br]wanted to use. So it's the vm_map_copy 0:25:13.000,0:25:19.160 technique, it was proposed by Dowd and[br]Mandt and basically they were spraying the 0:25:19.160,0:25:24.779 heap with these structs here, the[br]vm_map_copy structs, and assuming you have 0:25:24.779,0:25:31.250 like some way to corrupt this struct that[br]you've sprayed on the heap if you can 0:25:31.250,0:25:39.299 overwrite this kdata element here, then[br]basically what you have is a leak of 0:25:39.299,0:25:44.669 kernel memory other adjacent like next to[br]the kdata, whatever is below or above the 0:25:44.669,0:25:49.941 kdata pointer or arbitrary if you put[br]whatever address you want in there. By 0:25:49.941,0:25:58.019 overwriting the kalloc_size element here[br]and then freeing the struct on the heap, 0:25:58.019,0:26:03.909 you put it on a wrong zone and basically[br]when you allocate it back, since you put 0:26:03.909,0:26:10.157 it on on a different size zone, you can[br]have a heap overflow. So that's a general 0:26:10.157,0:26:14.021 overview of this technique. So but you[br]corrupt this struct and you get primitive 0:26:14.021,0:26:21.840 exploitation primitives. Okay, so what was[br]the idea I had at that point? The idea 0:26:21.840,0:26:28.659 was to use the... this pis_ioctl_list[br]index bug to corrupt this kdata pointer 0:26:28.659,0:26:38.370 here and to have arbitrarily... Sorry, we[br]have a relative leak of kernel heap 0:26:38.370,0:26:44.760 memory, and that would be my first step[br]towards exploiting the bug. Of course the 0:26:44.760,0:26:52.480 end goal is to have arbitrary read/write,[br]right, and of course it was just a fuzzy 0:26:52.480,0:26:56.269 idea at that point and you know that's[br]always the goal, but when you study the 0:26:56.269,0:27:03.620 bug and you see the different code paths[br]and how the things you affect are used, 0:27:03.620,0:27:08.330 then you have some maybe not completely[br]concrete things in your mind, but you know 0:27:08.330,0:27:14.234 that interesting things can happen, so[br]that's what I had at that point. 0:27:14.234,0:27:23.871 Okay, so let's talk about the exploitation[br]strategies now. So at stage one I sprayed 0:27:23.871,0:27:31.399 the kernel heap with vm_map_copy structs[br]and I decided to work on the kalloc.256 0:27:31.399,0:27:36.279 zone, and the reason for that was[br]completely arbitrary... was because of all 0:27:36.279,0:27:40.590 the kernel debugging I have done up to[br]this point of this entire binary I saw 0:27:40.590,0:27:45.860 that this kalloc zone was not really used[br]that much, either by the kernel or by 0:27:45.860,0:27:51.970 whatever the exploit was doing. So...[br]that's good because it means that you 0:27:51.970,0:27:55.950 can... you as an exploiter can have much[br]better control over the kernel heap if 0:27:55.950,0:28:04.701 there aren't other things placing[br]allocations on the zone you work. So I 0:28:04.701,0:28:12.610 decided to use the kalloc.256 zone and I[br]avoided of course kalloc.384 because the 0:28:12.610,0:28:20.559 tty structs were going there and that[br]would really mess up my heap arrangements. 0:28:20.559,0:28:30.286 So the first... let me actually... ok. So[br]what I wanted to do was to do this. 0:28:30.286,0:28:37.249 So initially you spray the heap with[br]vm_map_copy structs and you control both 0:28:37.249,0:28:41.820 their size and their contents, the content[br]don't matter at this point. So it... just 0:28:41.820,0:28:48.419 the size matters. So I spray with 256[br]bytes vm_map_copy structs and then I free 0:28:48.419,0:28:53.131 every other second one and I create this[br]kind of pattern like a vm_map_copy and a 0:28:53.131,0:28:59.210 free slot and a vm_map_copy and a free[br]slot and then I grow the pis_ioctl_list 0:28:59.210,0:29:08.620 array to 256 bytes and then it goes into[br]one of these free slots here. Now, the 0:29:08.620,0:29:14.990 code for doing that looks something like[br]that, so what this basically does it 0:29:14.990,0:29:24.509 sends... it creates this... so if you see[br]here the out of line mach messages as 0:29:24.509,0:29:31.570 basically these vm_map_copy structs and...[br]Their size is 256, their buffer doesn't 0:29:31.570,0:29:37.950 matter at this point and you just send[br]them like machs and methods. And then 0:29:37.950,0:29:42.990 after you've sprayed with them then you[br]free every second one here... with this 0:29:42.990,0:29:51.779 loop here. So in order to make this free[br]slot you just receive this mach out of 0:29:51.779,0:29:58.027 line messages that correspond to the[br]vm_map_copy structs. And after you've 0:29:58.027,0:30:04.519 created the holes you basically grow the[br]array to 256 bytes. How do you do that? As 0:30:04.519,0:30:12.010 I mentioned earlier you open the dev ptmx[br]device a number of times. How many times 0:30:12.010,0:30:18.429 doesn't matter, like a specific number of[br]times that I mentioned earlier, that I 0:30:18.429,0:30:26.370 have noticed grows it 256 bytes. So that's[br]the arrangement you have at that first 0:30:26.370,0:30:35.520 stage. Okay, so the second stage is done[br]on the kalloc.88 zone. So I spray again 0:30:35.520,0:30:41.640 with vm_map_copy structs and this [br]time I make them 88 bytes to go to 0:30:41.640,0:30:50.570 the kalloc.88 zone and then I create again[br]holes. And then I trigger the bug with an 0:30:50.570,0:30:56.250 invalid index value and remember that when[br]you trigger the bug a ptmx_ioctl struct is 0:30:56.250,0:31:01.610 allocated and this goes to kalloc.88. But[br]because on kalloc.88 I have created this 0:31:01.610,0:31:06.840 pattern of used free used free it goes[br]into one of the free slots. So now I have 0:31:06.840,0:31:13.620 a ptmx_ioctl struct in one of my free[br]slots. I don't know where that is but I 0:31:13.620,0:31:23.089 know that it falls into the pattern,[br]right, so I trigger the bug and remember 0:31:23.089,0:31:29.200 that basically you control this index,[br]right, so since I control the index I 0:31:29.200,0:31:35.270 point it to the vm_map... to the kdata[br]element of the vm_map_copy struct that I 0:31:35.270,0:31:39.809 know is below the free slot that the array[br]went into. I don't know the address, 0:31:39.809,0:31:46.950 right, I can't put like an address there,[br]but I can... I know the relatives... the 0:31:46.950,0:31:52.330 relative distance in bytes because I[br]created the pattern... the heap pattern. 0:31:52.330,0:31:58.289 So let's go to... okay. So it looks like[br]that. So that's my first stage, right, 0:31:58.289,0:32:02.594 free, vm_map_copy, ... and this is the[br]same pattern on the kalloc.88 zone. 0:32:02.594,0:32:08.000 When you trigger the bug, this ptmx_ioctl[br]structure is allocated. It goes into one 0:32:08.000,0:32:16.590 of the free slots, right, and then the bug[br]itself, which is what we see here is... 0:32:16.590,0:32:21.340 remember you control the index, so this is[br]the new allocation that went here, and 0:32:21.340,0:32:27.210 then it goes and stores the address where[br]the index tells it to store it. But 0:32:27.210,0:32:31.499 remember that this is controlled, we[br]control that, so what I do I point this 0:32:31.499,0:32:36.809 here relatively to the neighboring[br]vm_map_copy struct at the kdata field, 0:32:36.809,0:32:42.465 right. So in this kdata field here of the[br]vm_map_copy struct I have now this 0:32:42.465,0:32:52.740 address, right. So that's how the heap[br]looks like. I have here the code, it's 0:32:52.740,0:33:00.660 very similar to the first stage that you[br]spray with vm_map_copy structs of size 88, 0:33:00.660,0:33:05.919 machs and methods, right, and then you[br]receive every second one, you create the 0:33:05.919,0:33:15.909 holes on the 88 zone and then you trigger[br]the bug here, right. This invalid pis 0:33:15.909,0:33:29.610 index number here is basically what points[br]relatively here, right. So I have now the 0:33:29.610,0:33:37.179 address of this ptmx_ioctl struct which is[br]an address on the kalloc.88 zone. I have 0:33:37.179,0:33:42.669 it on the kdata field of this vm_map_copy[br]struct here. So what I do... I can simply 0:33:42.669,0:33:51.350 receive these methods and in its content I[br]can see the address of that slot on the 0:33:51.350,0:34:00.539 kalloc.88 zone. So that's the code to do [br]that, I simply receive all the messages 0:34:00.539,0:34:12.080 and that's my address. Okay, so at this[br]point I only... what I only have is this 0:34:12.080,0:34:21.500 address here, right? I have the address of[br]this heap slot. So, at that point I 0:34:21.500,0:34:28.699 started looking at other code paths that[br]this invalid index... what other 0:34:28.699,0:34:34.595 variables this invalid index was[br]influencing and I found the code path that 0:34:34.595,0:34:40.270 was actually giving... was giving me a[br]write and... But in order to reach that I 0:34:40.270,0:34:45.570 needed to survive several dereferences,[br]and what I only knew was just the 0:34:45.570,0:34:50.790 kalloc.88 address, right? Nothing else. So[br]I will now walk you through everything 0:34:50.790,0:35:00.710 that gave me this write. So I clean up the[br]kalloc.256 zone and I spray it again with 0:35:00.710,0:35:06.384 vm_map_copy structs and create holes[br]exactly like the previous step... 0:35:06.384,0:35:15.073 the first stage. Again, next to the[br]pis_ioctl_list array I have a vm_map_copy 0:35:15.073,0:35:23.110 struct, but at this time I... in all the[br]the vm_map_copy structs I put a payload of 0:35:23.110,0:35:29.890 the... of this fake ptmx_ioctl address I[br]have. And remember that the first element 0:35:29.890,0:35:40.250 of the ptmx_ioctl struct is a pointer to[br]tty struct and I can use the leaked 0:35:40.250,0:35:44.860 address I have for this pointer that I[br]don't know... I didn't know where to point 0:35:44.860,0:35:52.880 it to. So, the next step was to clean up[br]the kalloc.88 zone and spray it again, and 0:35:52.880,0:35:58.650 again I sprayed with vm_map_copy structs,[br]but at this time at their payload I can 0:35:58.650,0:36:07.231 put now the fake tty struct that the[br]ptmx_ioctl struct is pointing to. The 0:36:07.231,0:36:15.780 problem at that point was that the tty[br]struct with 256 bytes and kalloc.88 has... 0:36:15.780,0:36:22.480 the slots are only 88 bytes, so I couldn't[br]just with the elements of the... just with 0:36:22.480,0:36:29.311 the first 88 byte elements, I couldn't get[br]to the path that was giving the write, so 0:36:29.311,0:36:44.730 I needed to find some other way to host my[br]fake tty struct. So remember that I 0:36:44.730,0:36:50.730 couldn't work on any other kalloc zone or[br]anywhere else because what I only knew was 0:36:50.730,0:36:59.207 the address of that kalloc.88 zone, I had[br]nothing else to build on. So at that point 0:36:59.207,0:37:07.070 I started doing a much more complicated[br]heap arrangement. So instead of spraying 0:37:07.070,0:37:15.830 just one thing I was spraying... I was[br]trying to create a pattern of two 0:37:15.830,0:37:20.480 controlled things. Now, I couldn't use [br]vm_map_copy structs for both these slots 0:37:20.480,0:37:24.930 because the vm_map_copy structs has[br]a header, right? So it would mess up my 0:37:24.930,0:37:34.390 fake tty struct. So by reading i0n1c's[br]kernel heap exploitation slides, I 0:37:34.390,0:37:40.828 realized that I could spray the heap with[br]XML properties of length 88 from that 0:37:40.828,0:37:48.411 AppleJPEGDriver and I could place as a[br]second controlled object after the 0:37:48.411,0:37:53.130 vm_map_copy struct these XML properties[br]which are completely controlled in 0:37:53.130,0:37:58.190 content, and I could host the second part[br]of the tty struct there. I mean, it's 0:37:58.190,0:38:06.190 still not 256 bytes, but what it gives me[br]is the ability to survive all dereferences 0:38:06.190,0:38:14.430 to reach the write that I was interested[br]in. Okay. So, a few things about the 0:38:14.430,0:38:20.080 tty struct. So that's what I got... I[br]wanted to create on the kalloc.88 zone, 0:38:20.080,0:38:28.051 right, so that's the tty struct that the[br]ptmx_ioctl struct is pointing to. Now, 0:38:28.051,0:38:38.230 what basically I wanted to do here is I[br]wanted to point... the final thing was 0:38:38.230,0:38:45.610 to use this clist struct to control this[br]element here, c_cs, as a start of the ring 0:38:45.610,0:38:50.609 buffer for the tty, to give me an[br]arbitrary write... Sorry, to give me a 0:38:50.609,0:38:56.500 controlled write. I started playing a bit[br]with to use it to do arbitrary write, but 0:38:56.500,0:39:04.340 I found that I wasn't able to do it[br]because at later stage some other parts of 0:39:04.340,0:39:09.957 the tty struct were needed that I wasn't[br]able to control, so I only had two 0:39:09.957,0:39:17.500 88-slots to host my fake tty struct. So[br]that wasn't stable. So I was only 0:39:17.500,0:39:25.660 using that to do a relative write. So[br]we'll see the code later on, let's go to 0:39:25.660,0:39:32.430 the heap layout. So that's the third[br]stage. Again, remember I sprayed the 0:39:32.430,0:39:38.940 kalloc.256 zone with vm_map_copy structs/[br]frees, just place my pis_ioctl_list array 0:39:38.940,0:39:43.150 next to vm_map_copy struct. Remember that[br]I control the contents of vm_map_copy, 0:39:43.150,0:39:52.270 right, so I placed in the buffer of[br]vm_map_copy this ptmx_ioctl address that I 0:39:52.270,0:39:59.650 know and I point the invalid index that I[br]control to this ptmx_ioctl... this address 0:39:59.650,0:40:03.830 that I put here. And what is this address?[br]It's that leaked address that I got in the 0:40:03.830,0:40:11.550 previous stage which points to the [br]kalloc.88 zone. And what's the arrangement 0:40:11.550,0:40:16.780 of that kalloc.88 zone? It's as I told you a[br]vm_map_copy followed by an XML properties. 0:40:16.780,0:40:21.170 vm_map_copy, XML properties... And all[br]this hosts this fake tty struct, right? 0:40:21.170,0:40:28.160 All these are the same, I just explained[br]here how it looks like. So this points to 0:40:28.160,0:40:35.090 the kdata element here and the rest of[br]it holds the rest of the... all this is 0:40:35.090,0:40:39.660 basically the fake tty struct, like the[br]buffer of the vm_map_copy and then 0:40:39.660,0:40:47.370 following the XML contents of this heap[br]allocation. And where do I... this c_cs 0:40:47.370,0:40:53.045 pointer that I told you that I wanted to[br]control, where do I point it? I point it 0:40:53.045,0:40:56.572 relatively again, I don't know any[br]addresses but I can put it relatively 0:40:56.572,0:41:02.420 since I know the... since I created this[br]heap arrangement, I can put it relatively 0:41:02.420,0:41:07.380 to the size of the kalloc size of the[br]neighboring vm_map_copy struct. And why do 0:41:07.380,0:41:13.720 I need this? Because I want to use the[br]vm_map_copy technique by Mandt and Dowd 0:41:13.720,0:41:20.060 that I mentioned earlier, so that's the[br]end goal. So what's the code looks like? 0:41:20.060,0:41:25.910 Okay, that's the spray of 256, we've seen[br]that a lot of times, then we have the 0:41:25.910,0:41:34.004 freeze... wait, no, that's not the freeze.[br]So that's the allocations of the 256... 0:41:34.004,0:41:37.864 that's... yeah, I don't have the freeze[br]here because they don't matter, because we 0:41:37.864,0:41:42.880 have seen them before. So what I have here[br]is the spray of the kalloc.88 zone and the 0:41:42.880,0:41:46.720 important thing here is that... what I[br]wanted to show you that is that at every 0:41:46.720,0:41:53.510 step I took two allocations. One is the[br]vm_map_copy struct here with the machs and 0:41:53.510,0:42:00.840 methods, and the second part is the XML[br]properties, which are sprayed on the heap 0:42:00.840,0:42:09.920 when you open the device driver, the[br]AppleJPEGDriver. And what are the contents 0:42:09.920,0:42:15.590 of that XML properties? They're basically[br]that fake... the second part of the fake 0:42:15.590,0:42:20.282 tty struct that you have the controlled[br]c_cs pointer that will give me the 0:42:20.282,0:42:27.438 relative write. So if you see here, I have[br]this function setup_fake_tty that 0:42:27.438,0:42:33.230 basically creates the structs so I don't[br]have to type all the time, and we are at 0:42:33.230,0:42:37.740 second stage here, and basically what you[br]can see here is the creation of the 0:42:37.740,0:42:41.770 fake tty struct, right? So that's the[br]different elements of the fake tty as we 0:42:41.770,0:42:47.690 saw it from the code. And that's the write[br]offset I wanted to... that I pointed to 0:42:47.690,0:42:54.050 the kdata field of the neighboring[br]vm_map_copy struct. So, again, that's how 0:42:54.050,0:43:02.360 it looks like in the heap. Okay, so after[br]that, after we have arranged the... we 0:43:02.360,0:43:08.780 have arranged it this way, we trigger[br]again the invalid index array bug, but at 0:43:08.780,0:43:13.920 this time on the slave ptmx device. I was[br]only doing that on a master ptmx device, 0:43:13.920,0:43:18.070 but in order to reach that write code path[br]that I mentioned, you need to get on a 0:43:18.070,0:43:24.080 slave ptmx device. So that's what happens[br]here. And then you simply write to the 0:43:24.080,0:43:29.830 corresponding descriptor and it just[br]dereferences this c_cs that you controlled 0:43:29.830,0:43:33.860 and your end... and it writes with[br]whatever you want to write. And what do I 0:43:33.860,0:43:39.010 want to write? I want to write a new size[br]for the vm_map_copy struct... for the 0:43:39.010,0:43:42.841 kalloc size field of the vm... of the[br]neighboring vm_map_copy struct, so I can 0:43:42.841,0:43:52.730 use the Dowd and Mandt technique. So,[br]putting everything together. So at that 0:43:52.730,0:43:57.410 point I have a controlled corruption of a[br]vm_map_copy struct and I can use the 0:43:57.410,0:44:04.000 primitives to get arbitrary... an[br]arbitrary leak, so I can leak for example 0:44:04.000,0:44:10.230 the KSLR-slide and I can do a heap[br]overflow. Again these are how you can use 0:44:10.230,0:44:18.580 the primitives that Mandt and Dowd gave[br]us. Now I also know my location on the 0:44:18.580,0:44:24.610 kernel heap, and remember that... that's[br]basically... we found that on the stage... 0:44:24.610,0:44:29.380 on the first... on the first of stages and[br]we only... we use only that, like where 0:44:29.380,0:44:36.580 that ptmx_ioctl struct was stored on the[br]kernel heap, that's the only thing we 0:44:36.580,0:44:41.770 knew, that address, in order to[br]successively build on it, in order to 0:44:41.770,0:44:47.200 reach like a much more useful primitive.[br]And the important... the interesting thing 0:44:47.200,0:44:50.690 here is that everything up to this point[br]is data only, right? So you haven't 0:44:50.690,0:44:55.090 injected any code, you haven't done[br]anything at all that you could be caught 0:44:55.090,0:45:00.850 somehow by a kernel self-protection[br]mechanism or these kind of things, 0:45:00.850,0:45:10.310 everything's data only. So once you reach[br]that point, how do you get PC control? So 0:45:10.310,0:45:18.400 since you can use Dowd's and and Mandt's[br]technique, you can basically do a heap 0:45:18.400,0:45:23.480 overflow, so you can again do a heap[br]arrangement, you can place IOKit objects 0:45:23.480,0:45:31.000 next to vm_map_copy structs where you can[br]overflow from, and you can corrupt IOKit 0:45:31.000,0:45:36.840 objects and from there you can have...[br]also you can do an arbitrary write... 0:45:36.840,0:45:43.470 read/write, so you can... by the arbitrary[br]read you can read the vtables of the IOKit 0:45:43.470,0:45:48.650 objects so you know the KSLR-slide[br]and you can corrupt it in order to get PC 0:45:48.650,0:45:55.500 control. Of course getting to a whole[br]jailbreak from that point is out of the 0:45:55.500,0:46:01.030 scope of this talk, and... but is not that[br]hard actually from that point on. And 0:46:01.030,0:46:09.551 okay, so after doing all that how close[br]was that exploit to the evasi0n... to the 0:46:09.551,0:46:15.660 real evasi0n7 kernel exploiter? I'd say it[br]was pretty far off, but I mean it wasn't 0:46:15.660,0:46:22.040 my point to recreate it like completely,[br]but it was my point to play with the heap 0:46:22.040,0:46:29.260 and to try to do complex heap arrangements[br]and to see how much I understand the iOS 0:46:29.260,0:46:36.730 kernel heap, that was the point of this[br]whole exercise for me. Okay, so some 0:46:36.730,0:46:44.290 lessons learned. So the real surprising[br]thing for me at that point was that I 0:46:44.290,0:46:52.760 couldn't believe that Apple does kernel[br]debugging by KDB. It was very flaky, it 0:46:52.760,0:46:57.630 was very unstable as I told you. If you[br]type commands too fast it froze, if you 0:46:57.630,0:47:03.430 type commands very slowly it had like a[br]go-stop timer and froze, I think. 0:47:03.430,0:47:08.280 there was a claim of something like that[br]and it's unbeliev... I couldn't believe 0:47:08.280,0:47:14.670 that the Apple engineers were using this[br]interface to do kernel debugging. So it 0:47:14.670,0:47:23.730 was really hard to do anything on the[br]kernel side of idevices. But of course I 0:47:23.730,0:47:27.280 don't really mean that you shouldn't mess[br]with these things, right? I mean, these 0:47:27.280,0:47:31.941 devices are really interesting and it's[br]really becoming harder to hack them, but I 0:47:31.941,0:47:37.070 think it's much more fun and I think the[br]only takeaway may be that you shouldn't 0:47:37.070,0:47:41.310 report bugs to Apple at all and if you[br]need street cred you should just report 0:47:41.310,0:47:48.060 white elephant bugs now. I mean that's[br]always good. And I mean this very... this 0:47:48.060,0:47:52.220 is getting very esoteric, right, there are[br]not a lot of information and Apple keeps 0:47:52.220,0:47:55.690 changing stuff and everything is closed[br]source, I mean, all the important parts 0:47:55.690,0:48:01.110 are closed source... and I mean, I really[br]think people that work on that things 0:48:01.110,0:48:08.240 should share notes as much as possible.[br]Okay, so these are some of the people I 0:48:08.240,0:48:15.190 was talking to while doing all this and I[br]want to mention them, and basically that's 0:48:15.190,0:48:21.570 all of the material I have and I'm open to[br]any questions you might have. 0:48:21.570,0:48:32.850 applause[br]Herald: Thank you, argp, for the talk. So 0:48:32.850,0:48:42.831 we have prepared microphones 1, 2, 3 and 4[br]in the room and we have a Signal Angel, I 0:48:42.831,0:48:50.870 think. You... when you have questions, you[br]can give me a hand sign, but I 0:48:50.870,0:48:58.050 think we start with microphone 2 here in[br]the front. And please ask questions and no 0:48:58.050,0:49:01.510 comments, there's time after the talk.[br]Okay, go ahead. 0:49:01.510,0:49:03.830 Q: Thanks for the awesome talk.[br]argp: Thanks. 0:49:03.830,0:49:11.960 Q: I have a question about heap spraying.[br]Was your heap spraying really stable? If 0:49:11.960,0:49:17.080 it is not successful, did it crash the[br]device? 0:49:17.080,0:49:21.850 argp: Yeah. So I haven't mentioned it[br]here, but it was pretty stable I think. 0:49:21.850,0:49:25.130 It was something like... because I did a[br]lot of tests for that because it was 0:49:25.130,0:49:31.480 really interesting for me to know. It was[br]maybe something like 90%, so 9 out of 10 0:49:31.480,0:49:35.141 times it worked, but if it didn't work -[br]yeah, then... yes it crashed the kernel 0:49:35.141,0:49:40.250 and crashed the device, yeah.[br]Q: And did you try to return heap into 0:49:40.250,0:49:44.990 some kind of initial state to start your[br]exploit from scratch? 0:49:44.990,0:49:50.230 argp: Yeah, that's true I haven't included[br]that, but you're right. So the initial 0:49:50.230,0:49:56.860 step on every spray that I mentioned here[br]was to spray a lot of objects of the 0:49:56.860,0:50:01.740 specific size you were targeting in order[br]to get basically a new page of the kalloc 0:50:01.740,0:50:07.120 zone, right? So you... so even if as I[br]told you the kalloc 256 zone wasn't 0:50:07.120,0:50:11.220 that busy, it's still... there were still[br]allocations going on it, right? So if you 0:50:11.220,0:50:16.390 did a lot of initial spraying, you were[br]making sure that when you're... the 0:50:16.390,0:50:21.690 allocations that mattered to you we're[br]made, were on a new page that weren't... 0:50:21.690,0:50:24.110 wasn't too much noise from other[br]allocations from the kernel. So yeah, 0:50:24.110,0:50:26.930 you're right I haven't included that, but[br]yeah, that happened. 0:50:26.930,0:50:29.900 Q: Thanks, great.[br]argp: Thanks. 0:50:29.900,0:50:36.200 Herald: Then microphone 1, please.[br]Q: Also thank you for your awesome talk 0:50:36.200,0:50:37.710 again.[br]argp: Thanks. 0:50:37.710,0:50:43.609 Q: My question was nowadays it's way[br]harder to use vm_copy I think Apple truly 0:50:43.609,0:50:49.480 deprecated it, it's not possible anymore[br]that due to security. Do you see hope in 0:50:49.480,0:50:54.560 reconstructing some function that does the[br]same or is it totally dead now? 0:50:54.560,0:50:57.780 argp: Oh, you mean the vm_map_copy[br]technique? 0:50:57.780,0:51:00.740 Q: Yes.[br]argp: No, I think it's completely dead 0:51:00.740,0:51:03.940 now.[br]Q: All right. And I recently saw on the 0:51:03.940,0:51:10.310 iOS logs vulnerabilities that again a[br]vulnerability in AppleJPEGDriver was 0:51:10.310,0:51:15.060 found. Do you think... have you looked[br]into it or... 0:51:15.060,0:51:20.050 argp: Well, Apple... the AppleJPEGDriver[br]is one of the 4, I think, IOkit drivers 0:51:20.050,0:51:25.820 that you can reach from the container[br]sandbox, right? So that means it's very 0:51:25.820,0:51:31.260 fast by everyone, Apple included, and[br]very audited. So I'm not saying that there 0:51:31.260,0:51:36.170 aren't many... there aren't things there,[br]like interesting findings, but if there 0:51:36.170,0:51:38.640 are they're not going to live much longer,[br]I think. 0:51:38.640,0:51:41.680 Q: Okay, thank you.[br]Herald: Thanks for your question and now 0:51:41.680,0:51:45.000 from the Signal Angel a question from the[br]Internet. 0:51:45.000,0:51:48.650 Signal Angel: Yes, I have a question from[br]the internet. How long did this research 0:51:48.650,0:51:52.800 take you? You said two weeks in the[br]beginning, but from begin to end, how many 0:51:52.800,0:51:55.430 hours about? Because you also said it was[br]during work? 0:51:55.430,0:51:59.750 argp: No, it didn't it didn't take two[br]weeks, no. It took like maybe close to 0:51:59.750,0:52:05.030 three months or two months and something[br]like that. So I spent... as I mentioned I 0:52:05.030,0:52:09.190 spent like a complete month, I think, like[br]- maybe three weeks, maybe not a complete 0:52:09.190,0:52:16.560 month just on reversing redsn0w and trying[br]to get redsn0w to play with iOS7. So I 0:52:16.560,0:52:21.790 wouldn't count this month in the exploit[br]part of it, right? So if you're interested 0:52:21.790,0:52:29.000 just in the kernel exploit part I would[br]say something like maybe seven weeks, 0:52:29.000,0:52:36.170 something like that. But just with 2 maybe[br]3 days per week right, not complete weeks. 0:52:36.170,0:52:40.240 Herald: Okay, then microphone 1,[br]please. 0:52:40.240,0:52:45.740 Q: Congratulations on your talk which was[br]really interesting, I liked it a lot and 0:52:45.740,0:52:51.090 my question is if the technique you used[br]to exploit the bug was in FreeBSD or any 0:52:51.090,0:52:56.320 other BSD as well?[br]argp: Oh no, no. I mean, the vm_map_copy 0:52:56.320,0:53:02.900 struct doesn't exist anywhere else except[br]the XNU kernel. But I think the 0:53:02.900,0:53:06.921 interesting takeaway is that you can do[br]complex heap arrangements if you 0:53:06.921,0:53:13.960 understand the kernel heep allocator,[br]right? So this process I described by 0:53:13.960,0:53:18.740 creating holes and maybe controlling 2[br]allocations in order to host fake 0:53:18.740,0:53:24.630 structures that you are able then to use[br]to get exploitation primitives then that's 0:53:24.630,0:53:30.740 applicable everywhere, right?[br]Herald: Okay, then we go to microphone 2 0:53:30.740,0:53:35.810 again, please.[br]Q: So I saw one sentence, just not report 0:53:35.810,0:53:42.830 or... just don't report the bugs. I would[br]like to understand your thinking behind, 0:53:42.830,0:53:48.980 because I think this is really important[br]for companies to know the bugs that they 0:53:48.980,0:53:54.800 made and yeah, make the products better[br]and this is really beneficial for 0:53:54.800,0:54:00.950 researcher because for example Apple they[br]pay a lot of money for the bugs. What... 0:54:00.950,0:54:07.050 argp: Okay, yeah, I don't have much to say[br]on that. I mean, apart from: if all the 0:54:07.050,0:54:11.030 bugs are fixed then you won't be able to[br]do this kind of work and it's no fun. 0:54:11.030,0:54:17.760 Sorry, I don't have anything else to say[br]on that. Sorry, I don't have anything 0:54:17.760,0:54:23.140 else, no comment.[br]Herald: Okay. Signal Angel, do we have 0:54:23.140,0:54:31.310 another question from the internet? Okay,[br]then please a big round of applause for 0:54:31.310,0:54:33.539 our speaker![br]argp: Thanks. 0:54:33.539,0:54:35.233 applause 0:54:35.233,0:54:39.864 postroll music 0:54:39.864,0:54:57.000 subtitles created by c3subtitles.de[br]in the year 2020. Join, and help us!