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