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!