1
00:00:03,509 --> 00:00:08,860
all right so Aloha and welcome to my
2
00:00:06,189 --> 00:00:12,879
talk about getting cozy with auditing on
3
00:00:08,860 --> 00:00:15,190
Mac OS his Matt mentioned my name is
4
00:00:12,880 --> 00:00:17,200
Patrick Wardle and I've worked at a
5
00:00:15,190 --> 00:00:18,970
variety of acronym places including some
6
00:00:17,200 --> 00:00:21,460
government agencies currently I'm the
7
00:00:18,970 --> 00:00:23,259
chief research officer at a small
8
00:00:21,460 --> 00:00:25,570
start-up called digital security and
9
00:00:23,259 --> 00:00:29,460
very briefly digital security we're
10
00:00:25,570 --> 00:00:31,869
creating enterprise tools for the Mac
11
00:00:29,460 --> 00:00:34,360
alright so what are we going to be
12
00:00:31,869 --> 00:00:37,149
talking about today so we're gonna start
13
00:00:34,360 --> 00:00:39,309
with an overview of auditing on Mac OS
14
00:00:37,149 --> 00:00:41,199
now I'll be the first to admit that
15
00:00:39,309 --> 00:00:43,358
talking about auditing might not seem
16
00:00:41,199 --> 00:00:45,820
like the most sexy or interesting topic
17
00:00:43,359 --> 00:00:47,710
but the reality is it's actually very
18
00:00:45,820 --> 00:00:48,010
relevant in something important to talk
19
00:00:47,710 --> 00:00:51,039
about
20
00:00:48,010 --> 00:00:53,559
so as we'll see auditing is very useful
21
00:00:51,039 --> 00:00:55,449
for both malware analysis and forensics
22
00:00:53,559 --> 00:00:57,909
and if you're interested in creating
23
00:00:55,449 --> 00:01:00,218
security tools we'll show how you can
24
00:00:57,909 --> 00:01:01,899
utilize the auditing mechanisms built
25
00:01:00,219 --> 00:01:05,379
into the operating system to build some
26
00:01:01,899 --> 00:01:07,720
very powerful security tools also if you
27
00:01:05,379 --> 00:01:10,210
are a hacker or if you are developing
28
00:01:07,720 --> 00:01:12,820
offensive cyber security capabilities
29
00:01:10,210 --> 00:01:15,009
it's very important to know what type of
30
00:01:12,820 --> 00:01:16,990
auditing may be going on on the system
31
00:01:15,010 --> 00:01:19,800
so that your tools your exploits your
32
00:01:16,990 --> 00:01:22,720
capabilities remain undetected
33
00:01:19,800 --> 00:01:25,660
well then dive into a built in auditing
34
00:01:22,720 --> 00:01:27,070
mechanism or subsystem called open BSM
35
00:01:25,660 --> 00:01:31,330
and we'll see that this is kind of the
36
00:01:27,070 --> 00:01:34,119
de-facto auditing mechanism on mac well
37
00:01:31,330 --> 00:01:36,880
then dawn on our black hats and kind of
38
00:01:34,120 --> 00:01:39,250
take a more offensive turn to talk about
39
00:01:36,880 --> 00:01:41,890
some vulnerabilities in the auditing
40
00:01:39,250 --> 00:01:43,840
subsystem so first we'll talk about a
41
00:01:41,890 --> 00:01:46,240
kernel panic and then we'll end by
42
00:01:43,840 --> 00:01:48,340
talking about some more interesting bugs
43
00:01:46,240 --> 00:01:50,050
in the kernel one being an information
44
00:01:48,340 --> 00:01:54,310
leak and the other being an exploitable
45
00:01:50,050 --> 00:01:58,420
heap overflow so let's start by talking
46
00:01:54,310 --> 00:02:00,190
about auditing mechanisms on Mac OS now
47
00:01:58,420 --> 00:02:02,380
first you might be wondering what is
48
00:02:00,190 --> 00:02:04,360
auditing anyways and this is a question
49
00:02:02,380 --> 00:02:06,670
I had when I began this research and
50
00:02:04,360 --> 00:02:08,318
there's a great quote from Jonathan 11
51
00:02:06,670 --> 00:02:10,959
Jonathan is the author of the very
52
00:02:08,318 --> 00:02:12,969
popular Mac OS internal books highly
53
00:02:10,959 --> 00:02:16,030
recommended if you're interested in iOS
54
00:02:12,969 --> 00:02:17,230
and Mac OS internals and as he states in
55
00:02:16,030 --> 00:02:19,659
his book he says
56
00:02:17,230 --> 00:02:23,470
editing enables the recording of events
57
00:02:19,659 --> 00:02:24,579
which may have security implications now
58
00:02:23,470 --> 00:02:26,379
another question might be what's the
59
00:02:24,580 --> 00:02:28,750
difference between logging and auditing
60
00:02:26,379 --> 00:02:31,840
and this is again very valid question
61
00:02:28,750 --> 00:02:35,349
so logging can be thought of a way to
62
00:02:31,840 --> 00:02:36,940
kind of monitor any kind of activity so
63
00:02:35,349 --> 00:02:39,129
you think you know in your application
64
00:02:36,940 --> 00:02:41,650
you add a print statement or a syslog
65
00:02:39,129 --> 00:02:43,298
statement you can print some value of
66
00:02:41,650 --> 00:02:44,620
some variable right this doesn't
67
00:02:43,299 --> 00:02:47,260
necessarily have to have security
68
00:02:44,620 --> 00:02:49,269
implications auditing as I mentioned is
69
00:02:47,260 --> 00:02:51,790
generally going to be logging or
70
00:02:49,269 --> 00:02:55,180
recording actions that have security
71
00:02:51,790 --> 00:02:56,890
implications logging is also opt-in so
72
00:02:55,180 --> 00:02:58,989
if your application doesn't have printf
73
00:02:56,890 --> 00:03:01,358
statements or syslog it's not going to
74
00:02:58,989 --> 00:03:04,030
generate any logging auditing on the
75
00:03:01,359 --> 00:03:06,040
other hand is an enabled by default and
76
00:03:04,030 --> 00:03:09,129
is usually implemented at the kernel
77
00:03:06,040 --> 00:03:11,200
level so for example say there's some
78
00:03:09,129 --> 00:03:14,310
auditing enabled that audits login or
79
00:03:11,200 --> 00:03:17,709
logout events or syslog call assist
80
00:03:14,310 --> 00:03:19,390
system calls you know your application
81
00:03:17,709 --> 00:03:20,980
might not want to be audited but it's
82
00:03:19,390 --> 00:03:25,119
it's gonna get audited by the system
83
00:03:20,980 --> 00:03:27,099
regardless why auditing briefly
84
00:03:25,120 --> 00:03:28,720
mentioned from a security point of view
85
00:03:27,099 --> 00:03:31,060
it's a very important thing for an
86
00:03:28,720 --> 00:03:34,000
operating system to have so it can be
87
00:03:31,060 --> 00:03:37,120
used very very useful for helping to
88
00:03:34,000 --> 00:03:39,700
uncover or understand intrusions or even
89
00:03:37,120 --> 00:03:42,609
malware infections so for example as
90
00:03:39,700 --> 00:03:45,970
we'll see when events such as a new
91
00:03:42,609 --> 00:03:48,099
processes started you know a new file
92
00:03:45,970 --> 00:03:50,290
i/o activity perhaps even a new network
93
00:03:48,099 --> 00:03:52,238
connection these are all events that can
94
00:03:50,290 --> 00:03:53,798
be audited by the operating system so
95
00:03:52,239 --> 00:03:55,900
obviously if a piece of malware or a
96
00:03:53,799 --> 00:03:58,000
hacker gets into your system these are
97
00:03:55,900 --> 00:04:00,209
all events that can be recorded and can
98
00:03:58,000 --> 00:04:03,069
then help potentially uncover that
99
00:04:00,209 --> 00:04:05,019
infection or intrusion now more
100
00:04:03,069 --> 00:04:07,298
interesting to me though is using the
101
00:04:05,019 --> 00:04:10,060
audit subsystems to create security
102
00:04:07,299 --> 00:04:12,160
tools so for example and we'll talk
103
00:04:10,060 --> 00:04:13,690
about some other tools later I wrote a
104
00:04:12,160 --> 00:04:16,029
simple utility that's able to
105
00:04:13,690 --> 00:04:18,399
generically detect ransomware on Mac OS
106
00:04:16,029 --> 00:04:21,190
so all the tool does is look for the
107
00:04:18,399 --> 00:04:23,560
rapid creation of encrypted files by
108
00:04:21,190 --> 00:04:26,050
untrusted processes this is basically
109
00:04:23,560 --> 00:04:27,490
something that ransomware does so what
110
00:04:26,050 --> 00:04:29,500
the tool does is it taps into the
111
00:04:27,490 --> 00:04:30,800
auditing subsystem to get processed
112
00:04:29,500 --> 00:04:33,680
notification events
113
00:04:30,800 --> 00:04:35,270
and also file i/o events so the audit
114
00:04:33,680 --> 00:04:37,280
subsystem will now tell the tool
115
00:04:35,270 --> 00:04:39,979
whenever a new process is started and
116
00:04:37,280 --> 00:04:42,198
also whenever a new file is created or
117
00:04:39,979 --> 00:04:44,150
modified so then all the tool has to do
118
00:04:42,199 --> 00:04:45,979
is examine that file to see if it's
119
00:04:44,150 --> 00:04:48,020
encrypted and then keep track of some
120
00:04:45,979 --> 00:04:50,330
files and also see what process is
121
00:04:48,020 --> 00:04:52,940
creating those encrypted files and then
122
00:04:50,330 --> 00:04:55,039
it can generically detect all known Reds
123
00:04:52,940 --> 00:04:57,169
where on Mac OS so again a very powerful
124
00:04:55,039 --> 00:05:00,550
tool that's pretty easy to implement
125
00:04:57,169 --> 00:05:02,810
thanks again to the auditing subsystems
126
00:05:00,550 --> 00:05:05,599
so what auditing mechanisms are
127
00:05:02,810 --> 00:05:07,789
available on Mac OS turns out there's
128
00:05:05,599 --> 00:05:09,949
quite a few and we'll talk through all
129
00:05:07,789 --> 00:05:12,830
of these kind of looking at the pros and
130
00:05:09,949 --> 00:05:15,229
cons of each and also identifying any
131
00:05:12,830 --> 00:05:18,258
limitations of each of these auditing
132
00:05:15,229 --> 00:05:21,258
mechanisms so we'll talk about FS events
133
00:05:18,259 --> 00:05:26,900
kadiebug events D trace and finally open
134
00:05:21,259 --> 00:05:29,780
BSM so first up we have FS events FS
135
00:05:26,900 --> 00:05:32,840
stands for file system now if you're
136
00:05:29,780 --> 00:05:35,900
familiar with Linux these FS events are
137
00:05:32,840 --> 00:05:39,138
pretty much similar to Linux I notifies
138
00:05:35,900 --> 00:05:41,630
subsystem so as its name implies FS
139
00:05:39,139 --> 00:05:44,630
events you can use this auditing
140
00:05:41,630 --> 00:05:47,810
mechanism to monitor or audit for file
141
00:05:44,630 --> 00:05:48,550
IO events you can do this in three easy
142
00:05:47,810 --> 00:05:51,409
steps
143
00:05:48,550 --> 00:05:54,440
so the first thing you do is connect to
144
00:05:51,409 --> 00:05:58,490
slash dev slash FS events this is a
145
00:05:54,440 --> 00:06:01,460
special device file on Mac OS you then
146
00:05:58,490 --> 00:06:03,590
clone this file descriptor and specify
147
00:06:01,460 --> 00:06:05,870
what events are of interest to you for
148
00:06:03,590 --> 00:06:08,719
example file creations file deletions
149
00:06:05,870 --> 00:06:11,629
etc etc then what you do is in a while
150
00:06:08,719 --> 00:06:14,389
loop you just read off this file handle
151
00:06:11,629 --> 00:06:18,139
and the kernel will deliver file i/o
152
00:06:14,389 --> 00:06:20,330
events to you so let's look briefly in
153
00:06:18,139 --> 00:06:23,779
code how we can implement something such
154
00:06:20,330 --> 00:06:25,580
as a simple file monitor so again you
155
00:06:23,779 --> 00:06:28,400
can see in the code at the very top we
156
00:06:25,580 --> 00:06:31,370
call open and we open this dev /fs
157
00:06:28,400 --> 00:06:32,150
events device file we then specify or
158
00:06:31,370 --> 00:06:35,090
tell the colonel
159
00:06:32,150 --> 00:06:37,159
what file IO events are of interest to
160
00:06:35,090 --> 00:06:39,049
us and since we're writing a file maaan
161
00:06:37,159 --> 00:06:41,810
utility we basically tell it hey we're
162
00:06:39,050 --> 00:06:44,070
interested in everything so we set FS e
163
00:06:41,810 --> 00:06:46,080
underscore report to every single
164
00:06:44,070 --> 00:06:48,900
event.we then clone the file descriptor
165
00:06:46,080 --> 00:06:51,690
and then we very bottom we enter a while
166
00:06:48,900 --> 00:06:53,969
loop just reading forever off this file
167
00:06:51,690 --> 00:06:55,770
handle and again as these file i/o
168
00:06:53,970 --> 00:06:57,900
events come in the kernel will deliver
169
00:06:55,770 --> 00:06:59,909
them to user mode via that file and
170
00:06:57,900 --> 00:07:02,729
since we're reading off those file we
171
00:06:59,910 --> 00:07:04,770
can consume and parse those events so at
172
00:07:02,730 --> 00:07:07,290
the bottom for example if I touch a file
173
00:07:04,770 --> 00:07:09,150
and then remove that file running this
174
00:07:07,290 --> 00:07:11,700
code the file one utility we can see it
175
00:07:09,150 --> 00:07:14,700
detects the touch event and also the
176
00:07:11,700 --> 00:07:17,130
remove event so again pretty easy to
177
00:07:14,700 --> 00:07:19,440
write a fairly fully featured Taman
178
00:07:17,130 --> 00:07:22,350
utility using the FS events auditing
179
00:07:19,440 --> 00:07:24,360
mechanism the next auditing mechanism I
180
00:07:22,350 --> 00:07:27,360
want to talk about is the kadiebug
181
00:07:24,360 --> 00:07:30,930
utility this is a built-in kernel trace
182
00:07:27,360 --> 00:07:32,790
auditing capability now unlike FS events
183
00:07:30,930 --> 00:07:35,250
which are limited just to file system
184
00:07:32,790 --> 00:07:37,770
events the kadiebug events pretty much
185
00:07:35,250 --> 00:07:40,620
trace all activity on the system and
186
00:07:37,770 --> 00:07:43,169
Apple actually uses kadiebug events in a
187
00:07:40,620 --> 00:07:44,970
variety of their own tools so they have
188
00:07:43,170 --> 00:07:47,610
a latency tool they have another tool
189
00:07:44,970 --> 00:07:50,070
called SC underscore usage which shows
190
00:07:47,610 --> 00:07:52,530
system calls and then they actually have
191
00:07:50,070 --> 00:07:55,349
a file mod utility called FS underscore
192
00:07:52,530 --> 00:07:57,599
usage that's built into Mac OS now it's
193
00:07:55,350 --> 00:07:59,970
interesting that they don't use the FS
194
00:07:57,600 --> 00:08:02,370
events auditing mechanism they instead
195
00:07:59,970 --> 00:08:04,560
decided to use the K debug and this is
196
00:08:02,370 --> 00:08:08,130
because the Canadian ism is so much more
197
00:08:04,560 --> 00:08:10,740
powerful so what happens is kadiebug
198
00:08:08,130 --> 00:08:13,320
events are generated when code in the
199
00:08:10,740 --> 00:08:16,050
kernel calls a macro such as kernel
200
00:08:13,320 --> 00:08:17,940
underscore debug underscore constant so
201
00:08:16,050 --> 00:08:20,070
on the slide for example we can see the
202
00:08:17,940 --> 00:08:22,620
SIS call handler this is the interface
203
00:08:20,070 --> 00:08:25,200
in the kernel where user mode code that
204
00:08:22,620 --> 00:08:27,780
is making system calls will go through
205
00:08:25,200 --> 00:08:29,729
and enter the kernel and we can see in
206
00:08:27,780 --> 00:08:32,459
the code there is a call to the kernel
207
00:08:29,730 --> 00:08:35,849
debug constant macro and this will
208
00:08:32,460 --> 00:08:37,710
generate a kadiebug event so if we're
209
00:08:35,849 --> 00:08:39,990
reading these events and user mode we
210
00:08:37,710 --> 00:08:43,710
will get an event that assists call has
211
00:08:39,990 --> 00:08:46,260
occurred so programmatically how does
212
00:08:43,710 --> 00:08:49,110
one subscribe to these kadiebug events
213
00:08:46,260 --> 00:08:50,550
to get these audit notifications so the
214
00:08:49,110 --> 00:08:52,980
first thing we have to do is we have to
215
00:08:50,550 --> 00:08:55,260
tell the kernel to enable this audit
216
00:08:52,980 --> 00:08:57,210
mechanism and you do that via assist
217
00:08:55,260 --> 00:08:57,960
control when you pass in the current KD
218
00:08:57,210 --> 00:09:02,100
enable
219
00:08:57,960 --> 00:09:04,710
value and then once it is enabled you
220
00:09:02,100 --> 00:09:05,550
basically read events by again invoking
221
00:09:04,710 --> 00:09:08,400
sysctl
222
00:09:05,550 --> 00:09:12,900
this time with the Kern underscore KD
223
00:09:08,400 --> 00:09:15,569
read TR value and this will then we get
224
00:09:12,900 --> 00:09:18,240
deliver to you these kadiebug messages
225
00:09:15,570 --> 00:09:20,910
from kernel mode to user mode now these
226
00:09:18,240 --> 00:09:23,490
messages are compressed and encoded as
227
00:09:20,910 --> 00:09:27,120
Jonathan notes but what we can do is we
228
00:09:23,490 --> 00:09:29,310
can consult the trace dot codes file
229
00:09:27,120 --> 00:09:32,970
which is a file that is in Mac OS and
230
00:09:29,310 --> 00:09:34,680
this allows us to decode the events so
231
00:09:32,970 --> 00:09:37,980
again Jonathan has created an open
232
00:09:34,680 --> 00:09:40,709
source utility called kdv and so this
233
00:09:37,980 --> 00:09:43,230
code for example is from his utility so
234
00:09:40,710 --> 00:09:45,240
if we compile and run that utility we
235
00:09:43,230 --> 00:09:48,390
can see a ton of events I mean this is
236
00:09:45,240 --> 00:09:50,010
just gonna you know fulfill the screen
237
00:09:48,390 --> 00:09:52,920
with all sorts of events so for example
238
00:09:50,010 --> 00:09:57,990
we can see events related to the CPU
239
00:09:52,920 --> 00:10:01,079
utilization mock events etc etc next up
240
00:09:57,990 --> 00:10:03,750
we have d trace DTrace is a
241
00:10:01,080 --> 00:10:06,930
cross-platform auditing mechanism that
242
00:10:03,750 --> 00:10:10,110
is also available on Mac OS and until
243
00:10:06,930 --> 00:10:12,930
recently it was the de-facto tracing
244
00:10:10,110 --> 00:10:16,140
mechanism so in a nutshell what you do
245
00:10:12,930 --> 00:10:18,650
is you talk to a DTrace driver and you
246
00:10:16,140 --> 00:10:21,240
either do this through an API or through
247
00:10:18,650 --> 00:10:23,579
d'être scripts which are written in the
248
00:10:21,240 --> 00:10:25,350
deprogramming like library language
249
00:10:23,580 --> 00:10:28,080
which is why it's called DTrace and
250
00:10:25,350 --> 00:10:30,780
basically you specify to the kernel what
251
00:10:28,080 --> 00:10:32,790
probes or events are of interest to you
252
00:10:30,780 --> 00:10:35,550
and there's thousands of these probes
253
00:10:32,790 --> 00:10:38,790
that you can turn on there's ones for
254
00:10:35,550 --> 00:10:41,819
you know processes Mach traps syscall
255
00:10:38,790 --> 00:10:43,949
memory notifications so on the table we
256
00:10:41,820 --> 00:10:47,130
can see some of the details provide urse
257
00:10:43,950 --> 00:10:49,320
and again these providers basically you
258
00:10:47,130 --> 00:10:51,480
can think of them as class the
259
00:10:49,320 --> 00:10:55,200
high-level classes which the probes are
260
00:10:51,480 --> 00:10:58,470
kind of associated with so here's an
261
00:10:55,200 --> 00:11:01,920
example of using DTrace this is actually
262
00:10:58,470 --> 00:11:04,350
a dtrace script that ships with mock OS
263
00:11:01,920 --> 00:11:06,270
and it's called exec snoop and what it's
264
00:11:04,350 --> 00:11:09,420
designed to do is basically allow you
265
00:11:06,270 --> 00:11:10,699
from user mode to observe process
266
00:11:09,420 --> 00:11:12,439
creation
267
00:11:10,700 --> 00:11:15,470
and exit so basically it's a process
268
00:11:12,440 --> 00:11:18,740
monitor unfortunately though on recent
269
00:11:15,470 --> 00:11:21,140
versions of Mac OS DTrace is neutered by
270
00:11:18,740 --> 00:11:23,690
Apple's system integrity protection or
271
00:11:21,140 --> 00:11:25,310
sip basically Apple says okay DTrace is
272
00:11:23,690 --> 00:11:28,040
awesome but we think it's a little too
273
00:11:25,310 --> 00:11:30,890
powerful for the everyday user so we are
274
00:11:28,040 --> 00:11:33,079
going to disable it so even though their
275
00:11:30,890 --> 00:11:35,150
OS still ships with these scripts if you
276
00:11:33,080 --> 00:11:36,740
try run these scripts they're gonna fail
277
00:11:35,150 --> 00:11:38,959
it's gonna say Oh system integrity
278
00:11:36,740 --> 00:11:40,910
protection is on you have to turn this
279
00:11:38,960 --> 00:11:42,920
off if you want this script to execute
280
00:11:40,910 --> 00:11:45,469
and you can turn system integrity
281
00:11:42,920 --> 00:11:47,990
protection on if you boot reboot into
282
00:11:45,470 --> 00:11:50,270
the recovery mode and toggle it but
283
00:11:47,990 --> 00:11:51,950
that's gonna work for example on your
284
00:11:50,270 --> 00:11:54,410
own developer box if you're poking
285
00:11:51,950 --> 00:11:56,990
around but if you want to utilize DTrace
286
00:11:54,410 --> 00:11:59,900
for example in a security tool that's
287
00:11:56,990 --> 00:12:01,160
not gonna work for end-users because
288
00:11:59,900 --> 00:12:02,870
they're obviously gonna have system
289
00:12:01,160 --> 00:12:04,370
integrity turned on and they're not
290
00:12:02,870 --> 00:12:07,430
gonna want to jump through the hoops of
291
00:12:04,370 --> 00:12:09,830
turning it off so finally we have open
292
00:12:07,430 --> 00:12:12,829
DSM and open DSM as I mentioned is the
293
00:12:09,830 --> 00:12:15,530
de-facto auditing mechanism on modern
294
00:12:12,830 --> 00:12:18,230
versions of Mac OS interestingly it
295
00:12:15,530 --> 00:12:21,430
originally was developed on Solaris and
296
00:12:18,230 --> 00:12:23,510
then was ported to Mac OS by McAfee
297
00:12:21,430 --> 00:12:26,209
Apple apparently had a contract with
298
00:12:23,510 --> 00:12:28,880
McAfee to do that and on the slide we
299
00:12:26,210 --> 00:12:32,630
can see kind of a conceptual overview of
300
00:12:28,880 --> 00:12:33,890
how open bsm auditing works so in the
301
00:12:32,630 --> 00:12:35,960
kernel there's going to be some
302
00:12:33,890 --> 00:12:38,240
auditable event for example a new
303
00:12:35,960 --> 00:12:41,780
process that's created this will get
304
00:12:38,240 --> 00:12:44,240
noted by the open BSM subsystem it will
305
00:12:41,780 --> 00:12:46,880
then be added to a kernel queue and then
306
00:12:44,240 --> 00:12:50,300
committed to user mode either by writing
307
00:12:46,880 --> 00:12:54,080
to the open BSM audit a log file or to
308
00:12:50,300 --> 00:12:57,050
the user mode audit pipe so let's take a
309
00:12:54,080 --> 00:12:58,790
closer look at this briefly again we
310
00:12:57,050 --> 00:13:01,099
have the cisco interface that we talked
311
00:12:58,790 --> 00:13:04,189
about before and in this there's also
312
00:13:01,100 --> 00:13:06,440
some code to generate open BSM auditing
313
00:13:04,190 --> 00:13:08,450
events so for example we can see there's
314
00:13:06,440 --> 00:13:10,490
a call to audit underscore sis call
315
00:13:08,450 --> 00:13:12,290
enter and then after the sis call has
316
00:13:10,490 --> 00:13:14,570
occurred there's a call to audit
317
00:13:12,290 --> 00:13:17,480
underscore sis call underscore exit
318
00:13:14,570 --> 00:13:20,560
again these are open B SM macros in the
319
00:13:17,480 --> 00:13:22,880
kernel that will generate audit events
320
00:13:20,560 --> 00:13:24,569
so Jonathan's book kind of goes into the
321
00:13:22,880 --> 00:13:26,689
technical details of all of this
322
00:13:24,570 --> 00:13:29,880
but basically what these macros do is
323
00:13:26,690 --> 00:13:31,710
they generate audit events and then
324
00:13:29,880 --> 00:13:34,410
propagate that out to user mode either
325
00:13:31,710 --> 00:13:38,370
by writing to the log file or to the
326
00:13:34,410 --> 00:13:40,560
audit type so one of the cool things
327
00:13:38,370 --> 00:13:42,960
about open BSM is you can configure
328
00:13:40,560 --> 00:13:44,819
configure it with a variety of files and
329
00:13:42,960 --> 00:13:46,950
what the configuration files allow you
330
00:13:44,820 --> 00:13:49,470
to do is specify to the kernel what
331
00:13:46,950 --> 00:13:51,090
events are of interest to you so
332
00:13:49,470 --> 00:13:53,970
interestingly this is actually enabled
333
00:13:51,090 --> 00:13:56,520
by default on Mac OS and if we look at
334
00:13:53,970 --> 00:13:59,820
for example the audit control file which
335
00:13:56,520 --> 00:14:01,680
is in /xe slash security we can see
336
00:13:59,820 --> 00:14:03,660
there's these flagged parameters that
337
00:14:01,680 --> 00:14:06,630
have a variety of values specifically
338
00:14:03,660 --> 00:14:09,000
ello and comma AAA we can look at
339
00:14:06,630 --> 00:14:11,189
another file the audit classes to kind
340
00:14:09,000 --> 00:14:14,010
of decode what these are so we can see
341
00:14:11,190 --> 00:14:17,370
that ello maps to login logout AAA to
342
00:14:14,010 --> 00:14:19,170
authentication and authorization so what
343
00:14:17,370 --> 00:14:21,840
this basically means is the kernel is
344
00:14:19,170 --> 00:14:23,849
going to be auditing login and logout
345
00:14:21,840 --> 00:14:26,970
events and also authentication and
346
00:14:23,850 --> 00:14:29,250
authorization events but no other audit
347
00:14:26,970 --> 00:14:31,560
mechanisms audit events are going to be
348
00:14:29,250 --> 00:14:35,010
recorded unless you modify these flags
349
00:14:31,560 --> 00:14:36,689
so for example if you want to audit file
350
00:14:35,010 --> 00:14:38,840
events you basically just go in and edit
351
00:14:36,690 --> 00:14:41,310
these flags
352
00:14:38,840 --> 00:14:42,210
all right let's briefly talk about the
353
00:14:41,310 --> 00:14:44,609
audit logs
354
00:14:42,210 --> 00:14:46,920
they're basically stored in slash var
355
00:14:44,610 --> 00:14:50,640
slash on it and there are several files
356
00:14:46,920 --> 00:14:53,069
basically when a file max is hit what
357
00:14:50,640 --> 00:14:55,199
happens is the kernel just creates a new
358
00:14:53,070 --> 00:14:57,690
file and you can always tell what the
359
00:14:55,200 --> 00:15:00,300
current one is because it's going to be
360
00:14:57,690 --> 00:15:02,970
symlink to one that ends in knot
361
00:15:00,300 --> 00:15:06,120
underscore terminated now if you dump
362
00:15:02,970 --> 00:15:08,580
the data in these open BSM audit log
363
00:15:06,120 --> 00:15:10,590
files you'll see that the data is in a
364
00:15:08,580 --> 00:15:13,020
binary compressed proprietary format
365
00:15:10,590 --> 00:15:16,230
luckily though there's utilities we can
366
00:15:13,020 --> 00:15:20,069
use such as Apple's PR audit and this
367
00:15:16,230 --> 00:15:21,990
will decode the data for that so if I
368
00:15:20,070 --> 00:15:24,240
for example generate a login event by
369
00:15:21,990 --> 00:15:27,180
executing sudo and then some user and
370
00:15:24,240 --> 00:15:29,580
then when I'm done type exit to
371
00:15:27,180 --> 00:15:32,520
basically exit that session if I then go
372
00:15:29,580 --> 00:15:35,130
and examine the current open B SM audit
373
00:15:32,520 --> 00:15:37,500
log file I can see that both the user
374
00:15:35,130 --> 00:15:37,930
authentication event and a logout event
375
00:15:37,500 --> 00:15:41,100
has
376
00:15:37,930 --> 00:15:43,739
being recorded by the operating system
377
00:15:41,100 --> 00:15:47,200
okay so that wraps up our tour of
378
00:15:43,740 --> 00:15:48,730
auditing capabilities of Mac OS now the
379
00:15:47,200 --> 00:15:51,010
question is you know what of these
380
00:15:48,730 --> 00:15:53,320
mechanisms should we use either to
381
00:15:51,010 --> 00:15:56,350
perform continual auditing perhaps for
382
00:15:53,320 --> 00:16:00,190
incident response or most importantly to
383
00:15:56,350 --> 00:16:02,980
me programmatically in security tools so
384
00:16:00,190 --> 00:16:05,950
FS events is pretty good but the main
385
00:16:02,980 --> 00:16:08,529
limitation is it can only record file IO
386
00:16:05,950 --> 00:16:10,060
events so that's a pretty big limitation
387
00:16:08,529 --> 00:16:12,700
if we for example want to monitor
388
00:16:10,060 --> 00:16:16,209
process events or Network IO events we
389
00:16:12,700 --> 00:16:18,250
can't use the FS events ApS kadiebug is
390
00:16:16,209 --> 00:16:19,930
really powerful but there's one main
391
00:16:18,250 --> 00:16:22,510
problem with it and that is there can
392
00:16:19,930 --> 00:16:24,189
only be one consumer at a time so if you
393
00:16:22,510 --> 00:16:26,709
write a security tool and you're using
394
00:16:24,190 --> 00:16:29,020
the kadiebug auditing mechanism and then
395
00:16:26,709 --> 00:16:31,479
the user for example wants to use FS
396
00:16:29,020 --> 00:16:34,300
usage which is Apple's built-in file
397
00:16:31,480 --> 00:16:36,010
monitor that ships with Mac OS FS usage
398
00:16:34,300 --> 00:16:37,479
won't work anymore and we'll throw an
399
00:16:36,010 --> 00:16:40,630
error message saying hey someone's
400
00:16:37,480 --> 00:16:42,760
already using kata bug kata bug event so
401
00:16:40,630 --> 00:16:46,209
this is not really something you want to
402
00:16:42,760 --> 00:16:49,779
cause users so again it's not maybe the
403
00:16:46,209 --> 00:16:52,270
ideal mechanism to use DTrace again is a
404
00:16:49,779 --> 00:16:53,770
great mechanism but because it's not
405
00:16:52,270 --> 00:16:55,480
compatible with system integrity
406
00:16:53,770 --> 00:16:58,209
protection again it doesn't make sense
407
00:16:55,480 --> 00:17:00,400
to put into a security tool that you're
408
00:16:58,209 --> 00:17:02,500
going to deploy to a lot of machines so
409
00:17:00,400 --> 00:17:04,329
this leaves us with open BSM which kind
410
00:17:02,500 --> 00:17:05,650
of checks off all our boxes it's
411
00:17:04,329 --> 00:17:08,050
compatible with system integrity
412
00:17:05,650 --> 00:17:10,569
protection and gives us access to all
413
00:17:08,050 --> 00:17:12,730
the events of interest it also has a
414
00:17:10,569 --> 00:17:16,750
nice programmatic API and there can be
415
00:17:12,730 --> 00:17:19,209
multiple consumers so now let's talk
416
00:17:16,750 --> 00:17:23,490
about how to leverage open BSM
417
00:17:19,209 --> 00:17:26,350
programmatically in Mac security tools
418
00:17:23,490 --> 00:17:28,750
so one of my side hobbies is to create
419
00:17:26,349 --> 00:17:30,669
free a lot of open source Mac security
420
00:17:28,750 --> 00:17:33,960
tools and these tools need to perform
421
00:17:30,670 --> 00:17:36,640
things like tracking file a file file IO
422
00:17:33,960 --> 00:17:39,010
monitoring for new process creations and
423
00:17:36,640 --> 00:17:42,010
a lot more you can also imagine perhaps
424
00:17:39,010 --> 00:17:44,290
you want to create more traditional AV
425
00:17:42,010 --> 00:17:47,629
tools or malware analysis tools for
426
00:17:44,290 --> 00:17:49,970
example a file aman or a process maan
427
00:17:47,630 --> 00:17:52,370
that you know can use these auditing
428
00:17:49,970 --> 00:17:54,140
mechanisms so I used to use DTrace
429
00:17:52,370 --> 00:17:55,939
programmatically but as I mentioned due
430
00:17:54,140 --> 00:17:57,830
to system integrity protection it's
431
00:17:55,940 --> 00:18:02,120
essentially dead luckily though we have
432
00:17:57,830 --> 00:18:05,270
open BSN so programmatically how does
433
00:18:02,120 --> 00:18:08,360
one utilize or make use of open BSM in
434
00:18:05,270 --> 00:18:10,610
code for example in monitoring utility
435
00:18:08,360 --> 00:18:12,889
now we'll dive into each of these steps
436
00:18:10,610 --> 00:18:13,399
but conceptually from a high level it's
437
00:18:12,890 --> 00:18:16,460
pretty easy
438
00:18:13,400 --> 00:18:20,000
first you connect to the user mode audit
439
00:18:16,460 --> 00:18:21,740
pipe you then specify what audit events
440
00:18:20,000 --> 00:18:24,640
are of interest to you for example you
441
00:18:21,740 --> 00:18:27,020
can say I want file events and process
442
00:18:24,640 --> 00:18:29,150
notifications and then you basically
443
00:18:27,020 --> 00:18:31,820
read off this pipe and the kernel will
444
00:18:29,150 --> 00:18:32,740
deliver to you audit events so pretty
445
00:18:31,820 --> 00:18:35,780
standard
446
00:18:32,740 --> 00:18:39,920
so I mentioned step one is to connect to
447
00:18:35,780 --> 00:18:42,649
the user mode open bsm audit pipe so in
448
00:18:39,920 --> 00:18:44,870
code as root you just call f open on
449
00:18:42,650 --> 00:18:48,230
this pipe and it's at slash dev slash
450
00:18:44,870 --> 00:18:50,030
audit pipe and then as audit events are
451
00:18:48,230 --> 00:18:53,450
captured they will be written out to
452
00:18:50,030 --> 00:18:56,600
this pipe from kernel mode so now we've
453
00:18:53,450 --> 00:18:58,490
opened this pipe we need to specify as I
454
00:18:56,600 --> 00:19:01,340
mentioned what audit events are of
455
00:18:58,490 --> 00:19:04,190
interest to us so here for example let's
456
00:19:01,340 --> 00:19:06,290
build a simple process monitor so we're
457
00:19:04,190 --> 00:19:08,809
gonna say okay we're interested only in
458
00:19:06,290 --> 00:19:11,420
process events so we can go into the
459
00:19:08,809 --> 00:19:14,030
audit underscore class file and look up
460
00:19:11,420 --> 00:19:16,550
what open BSM audit events relate to
461
00:19:14,030 --> 00:19:18,920
process creation process events and we
462
00:19:16,550 --> 00:19:21,200
can see there's two there's pc and exec
463
00:19:18,920 --> 00:19:24,080
so in code what we do is we basically
464
00:19:21,200 --> 00:19:25,610
send an i octal to the kernel saying hey
465
00:19:24,080 --> 00:19:27,439
these are the open BSM
466
00:19:25,610 --> 00:19:31,639
auditing events that are are of interest
467
00:19:27,440 --> 00:19:33,830
to us now we've opened the fight pipe
468
00:19:31,640 --> 00:19:36,290
and configured it we can start reading
469
00:19:33,830 --> 00:19:38,960
off it and since we've configured it
470
00:19:36,290 --> 00:19:41,000
anytime now there's a process event the
471
00:19:38,960 --> 00:19:44,420
kernel will deliver that to this pipe
472
00:19:41,000 --> 00:19:46,340
and we can consume off that so if you
473
00:19:44,420 --> 00:19:49,280
look for the documentation you can see
474
00:19:46,340 --> 00:19:53,090
there is a open BSM api called au
475
00:19:49,280 --> 00:19:54,530
underscore read rec for record and it
476
00:19:53,090 --> 00:19:57,379
basically takes in the file descriptor
477
00:19:54,530 --> 00:19:57,830
to the audit pipe and a buffer for the
478
00:19:57,380 --> 00:20:00,450
record
479
00:19:57,830 --> 00:20:03,120
now the documentation says it
480
00:20:00,450 --> 00:20:04,890
terns zero on success but that is not
481
00:20:03,120 --> 00:20:07,110
true it actually returns the number of
482
00:20:04,890 --> 00:20:11,610
bytes it is read so the documentation is
483
00:20:07,110 --> 00:20:13,889
incorrect so now we have an audit record
484
00:20:11,610 --> 00:20:16,889
that we have read off the audit pipe and
485
00:20:13,890 --> 00:20:18,870
Apple calls this a token record we have
486
00:20:16,890 --> 00:20:21,540
to parse this in order to consume it or
487
00:20:18,870 --> 00:20:25,080
utilize it in our tool so what we do is
488
00:20:21,540 --> 00:20:27,360
we invoke the a you fetch tok method to
489
00:20:25,080 --> 00:20:29,790
tokenize the audit record and this will
490
00:20:27,360 --> 00:20:32,790
split it into a variety of tok ster
491
00:20:29,790 --> 00:20:35,159
structures now each of these structures
492
00:20:32,790 --> 00:20:37,560
contains some important members the
493
00:20:35,160 --> 00:20:40,680
first is the ID or type this allows us
494
00:20:37,560 --> 00:20:43,110
to identify the type of structure it is
495
00:20:40,680 --> 00:20:45,840
and all these structures are listed in
496
00:20:43,110 --> 00:20:49,590
the lib be smh file which ships with mac
497
00:20:45,840 --> 00:20:51,300
OS so some notable token types include a
498
00:20:49,590 --> 00:20:53,520
header and a trailer which obviously
499
00:20:51,300 --> 00:20:55,139
start and end or record and then
500
00:20:53,520 --> 00:20:57,870
there'll be other token types that
501
00:20:55,140 --> 00:21:00,330
correspond to the event so for example
502
00:20:57,870 --> 00:21:03,600
for a process creation event there will
503
00:21:00,330 --> 00:21:05,669
be a record that corresponds to the path
504
00:21:03,600 --> 00:21:06,899
of the process that is created there
505
00:21:05,670 --> 00:21:11,580
will be another one for the process
506
00:21:06,900 --> 00:21:13,710
arguments process parents etc etc so
507
00:21:11,580 --> 00:21:16,649
what we do is to process these tokens we
508
00:21:13,710 --> 00:21:18,360
just switch on the token type again to
509
00:21:16,650 --> 00:21:21,660
determine the type of token that we have
510
00:21:18,360 --> 00:21:23,520
and then we have tokens specific logic
511
00:21:21,660 --> 00:21:24,930
to pull out the information that's of
512
00:21:23,520 --> 00:21:27,150
interest so for example I mentioned
513
00:21:24,930 --> 00:21:28,980
there's going to be a path so what we
514
00:21:27,150 --> 00:21:31,650
can do is when we see the token that's
515
00:21:28,980 --> 00:21:33,780
associated with the path we can record
516
00:21:31,650 --> 00:21:36,240
this path for example convert it into an
517
00:21:33,780 --> 00:21:39,899
nsstring object and then consume that in
518
00:21:36,240 --> 00:21:42,360
our tool so if we put this all together
519
00:21:39,900 --> 00:21:44,400
we now have a nice process monitoring
520
00:21:42,360 --> 00:21:46,889
library this library is open source
521
00:21:44,400 --> 00:21:49,410
available on github and it's called proc
522
00:21:46,890 --> 00:21:51,870
info the cool thing about it is it's
523
00:21:49,410 --> 00:21:54,240
very easy to use you basically link in
524
00:21:51,870 --> 00:21:57,479
the library and then what you do is you
525
00:21:54,240 --> 00:21:59,610
create a block of code that you want the
526
00:21:57,480 --> 00:22:01,800
library to invoke anytime there's either
527
00:21:59,610 --> 00:22:04,020
a process creation or process
528
00:22:01,800 --> 00:22:07,080
termination event and then you basically
529
00:22:04,020 --> 00:22:09,840
allocate a process monitor object and
530
00:22:07,080 --> 00:22:12,120
then invoke the start method passing in
531
00:22:09,840 --> 00:22:12,899
the block the library takes care of
532
00:22:12,120 --> 00:22:14,310
everything else
533
00:22:12,900 --> 00:22:16,980
all the auditing
534
00:22:14,310 --> 00:22:19,110
figuration the tracking of process
535
00:22:16,980 --> 00:22:21,720
events parsing all the tokens etc etc
536
00:22:19,110 --> 00:22:24,840
and then it'll invoke this block of code
537
00:22:21,720 --> 00:22:25,890
whenever there's a process event and it
538
00:22:24,840 --> 00:22:28,199
also does other cool things like
539
00:22:25,890 --> 00:22:30,660
generate the signing information of the
540
00:22:28,200 --> 00:22:34,650
process that's being created extracts
541
00:22:30,660 --> 00:22:37,080
the ancestors etc etc so very easily now
542
00:22:34,650 --> 00:22:39,510
whenever a new process is created you
543
00:22:37,080 --> 00:22:41,159
can see who created it and also the
544
00:22:39,510 --> 00:22:43,800
signing information so you can say oh
545
00:22:41,160 --> 00:22:46,110
this is a trusted apple process this is
546
00:22:43,800 --> 00:22:50,129
something from the Mac App Store or this
547
00:22:46,110 --> 00:22:52,469
is unsigned that's odd okay so that was
548
00:22:50,130 --> 00:22:55,110
an overview of auditing mechanisms and
549
00:22:52,470 --> 00:22:57,810
how to utilize open BSM programmatically
550
00:22:55,110 --> 00:23:00,449
in security tools now since this is kind
551
00:22:57,810 --> 00:23:03,480
of a technical hacker conference let's
552
00:23:00,450 --> 00:23:05,400
now talk about some more interesting at
553
00:23:03,480 --> 00:23:07,650
least to me topics so time to put on our
554
00:23:05,400 --> 00:23:08,820
hacker hats either gray white or black
555
00:23:07,650 --> 00:23:11,160
you know we're not gonna discriminate
556
00:23:08,820 --> 00:23:14,909
here and we'll talk about some kernel
557
00:23:11,160 --> 00:23:18,330
bugs that existed in Apple's open BSM
558
00:23:14,910 --> 00:23:20,280
kernel mode code so the first bug we're
559
00:23:18,330 --> 00:23:21,960
gonna talk about is a kernel panic and I
560
00:23:20,280 --> 00:23:24,060
kind of like this bug because I found it
561
00:23:21,960 --> 00:23:26,160
totally by accident and I always kind of
562
00:23:24,060 --> 00:23:29,340
have this joke that like finding bugs on
563
00:23:26,160 --> 00:23:31,350
Mac OS is so easy that like if you're
564
00:23:29,340 --> 00:23:33,360
writing security tools or just Splunk
565
00:23:31,350 --> 00:23:34,679
around like you're gonna inadvertently
566
00:23:33,360 --> 00:23:38,520
come across a lot of really interesting
567
00:23:34,680 --> 00:23:40,560
bugs so I had this process info library
568
00:23:38,520 --> 00:23:42,840
I'd written again it utilized the open
569
00:23:40,560 --> 00:23:45,720
BSM auditing subsystem to generate
570
00:23:42,840 --> 00:23:47,850
process events again I mentioned that I
571
00:23:45,720 --> 00:23:49,890
have a variety of security tools for
572
00:23:47,850 --> 00:23:52,679
example one that generically detects
573
00:23:49,890 --> 00:23:55,140
ransomware and one of the capabilities
574
00:23:52,680 --> 00:23:58,470
of this tool is it needs to track
575
00:23:55,140 --> 00:24:00,900
processes so that when a certain process
576
00:23:58,470 --> 00:24:03,000
create creates files it knows you know
577
00:24:00,900 --> 00:24:06,320
what process that is who spawned it etc
578
00:24:03,000 --> 00:24:10,260
etc to basically classify that process
579
00:24:06,320 --> 00:24:12,899
so I swapped in my proc info open DSM
580
00:24:10,260 --> 00:24:15,210
auditing process monitoring library ran
581
00:24:12,900 --> 00:24:17,190
the tool went off to lunch and a few
582
00:24:15,210 --> 00:24:19,170
hours later came back and my box had
583
00:24:17,190 --> 00:24:20,940
panicked I was like okay it's kind of
584
00:24:19,170 --> 00:24:24,090
annoying like maybe there's some faulty
585
00:24:20,940 --> 00:24:26,550
hardware but started the tool again and
586
00:24:24,090 --> 00:24:27,360
came back the next morning again my box
587
00:24:26,550 --> 00:24:29,129
had panicked
588
00:24:27,360 --> 00:24:30,719
and again first I was a little annoyed
589
00:24:29,130 --> 00:24:33,210
but I said oh hey now we have a
590
00:24:30,720 --> 00:24:35,460
repeatable Colonel panic on the most
591
00:24:33,210 --> 00:24:39,450
recent version of Mac OS like that's
592
00:24:35,460 --> 00:24:41,790
kind of cool so let's do now is walk
593
00:24:39,450 --> 00:24:45,330
through that kernel panic to find out
594
00:24:41,790 --> 00:24:46,139
the underlying cause of the bug so the
595
00:24:45,330 --> 00:24:47,730
first thing we're gonna do is we're
596
00:24:46,140 --> 00:24:49,650
gonna start with the kernel panic report
597
00:24:47,730 --> 00:24:51,540
and kernel panic reports are great
598
00:24:49,650 --> 00:24:53,490
because as we'll see they have all the
599
00:24:51,540 --> 00:24:55,379
information that you need generally
600
00:24:53,490 --> 00:24:59,430
speaking to track down the underlying
601
00:24:55,380 --> 00:25:00,990
cause of the bug so if we look at this
602
00:24:59,430 --> 00:25:04,080
there's a lot of information but I've
603
00:25:00,990 --> 00:25:07,470
highlighted in green kind of the pieces
604
00:25:04,080 --> 00:25:09,540
of information that are valuable to us
605
00:25:07,470 --> 00:25:12,120
so first we see there's something that
606
00:25:09,540 --> 00:25:14,010
says type 14 equals page fault this
607
00:25:12,120 --> 00:25:15,689
indicates why the kernel panic it's
608
00:25:14,010 --> 00:25:17,790
basically said there's a page fault
609
00:25:15,690 --> 00:25:21,450
which means there was an invalid read or
610
00:25:17,790 --> 00:25:23,670
write likely to an unmapped page next we
611
00:25:21,450 --> 00:25:25,710
have our IP which is the 64 bit
612
00:25:23,670 --> 00:25:28,260
instruction pointer and this has the
613
00:25:25,710 --> 00:25:30,630
address of the faulting instruction so
614
00:25:28,260 --> 00:25:33,750
this is the line of code or the address
615
00:25:30,630 --> 00:25:37,320
of the opcodes that were being executed
616
00:25:33,750 --> 00:25:40,650
when the kernel panic occurred finally
617
00:25:37,320 --> 00:25:42,600
we have fault CR 2 this has the actual
618
00:25:40,650 --> 00:25:44,490
address that the kernel was trying to
619
00:25:42,600 --> 00:25:46,439
reference that triggered the page fault
620
00:25:44,490 --> 00:25:48,480
and then the very bottom we have the
621
00:25:46,440 --> 00:25:50,490
kernel slide which is just the amount in
622
00:25:48,480 --> 00:25:54,330
memory the kernel was slid due to
623
00:25:50,490 --> 00:25:55,440
address space layout randomization so as
624
00:25:54,330 --> 00:25:58,770
I mentioned the goal is to figure out
625
00:25:55,440 --> 00:26:00,900
why this panic occurred so since we have
626
00:25:58,770 --> 00:26:03,150
the address of the faulting instruction
627
00:26:00,900 --> 00:26:05,100
from the kernel panic report what we can
628
00:26:03,150 --> 00:26:08,580
do is we can disassemble the kernel and
629
00:26:05,100 --> 00:26:11,159
go to that address in the disassembly so
630
00:26:08,580 --> 00:26:12,570
we load up the kernel in Ida Pro and the
631
00:26:11,160 --> 00:26:14,700
first thing we have to do is we have to
632
00:26:12,570 --> 00:26:17,100
rebase the file image so that it Maps
633
00:26:14,700 --> 00:26:19,260
the in memory memory image because again
634
00:26:17,100 --> 00:26:24,560
when the kernel is loaded it gets slid
635
00:26:19,260 --> 00:26:27,900
in memory because of kaal arm so once we
636
00:26:24,560 --> 00:26:30,330
rebase the kernel we have the address
637
00:26:27,900 --> 00:26:34,050
from our IP in the kernel panic report
638
00:26:30,330 --> 00:26:37,710
we put that in the jump to address pop
639
00:26:34,050 --> 00:26:38,918
up in Ida and we hit G and what we do is
640
00:26:37,710 --> 00:26:41,590
we land
641
00:26:38,919 --> 00:26:45,809
a compare instruction in the audit argh
642
00:26:41,590 --> 00:26:49,059
sock adder function this is an open BSM
643
00:26:45,809 --> 00:26:52,210
audit function which makes sense because
644
00:26:49,059 --> 00:26:54,580
again my utility user mode utility that
645
00:26:52,210 --> 00:26:57,129
triggered the kernel panic was utilizing
646
00:26:54,580 --> 00:27:00,249
the open BSM auditing so basically this
647
00:26:57,129 --> 00:27:03,399
now indicates that in user mode if you
648
00:27:00,249 --> 00:27:05,379
were talking to the api's there was some
649
00:27:03,399 --> 00:27:07,149
bug in the kernel that would trigger and
650
00:27:05,379 --> 00:27:08,709
crash the box and we can see it's a
651
00:27:07,149 --> 00:27:12,518
compare instruction that's doing a
652
00:27:08,710 --> 00:27:15,509
compare of our bx + r 13 + 2 and it's
653
00:27:12,519 --> 00:27:18,970
basically checking if that address is 0
654
00:27:15,509 --> 00:27:20,889
now luckily the audit Arg sock adder
655
00:27:18,970 --> 00:27:24,279
function which we'll be talking about a
656
00:27:20,889 --> 00:27:26,320
lot is open source so we can browse to
657
00:27:24,279 --> 00:27:29,350
open source Apple comm and look at the
658
00:27:26,320 --> 00:27:32,259
source code for us so the goal is to
659
00:27:29,350 --> 00:27:34,570
figure out what line in this source code
660
00:27:32,259 --> 00:27:36,009
maps to the compare instruction again
661
00:27:34,570 --> 00:27:38,649
the compare instruction we got from
662
00:27:36,009 --> 00:27:40,419
disassembling the kernel so if we look
663
00:27:38,649 --> 00:27:43,479
at the kernel code we can see that when
664
00:27:40,419 --> 00:27:46,960
bind is called on a socket it invokes
665
00:27:43,480 --> 00:27:49,119
the argh audit argh macro to audit the
666
00:27:46,960 --> 00:27:50,739
socket event basically says okay binding
667
00:27:49,119 --> 00:27:52,509
a socket is an event that might have
668
00:27:50,739 --> 00:27:56,230
security implications so I'm going to
669
00:27:52,509 --> 00:27:57,399
audit this event so in turn it calls
670
00:27:56,230 --> 00:27:59,409
this audit argh
671
00:27:57,399 --> 00:28:02,320
sock adder function which among other
672
00:27:59,409 --> 00:28:05,679
things determines what the type of
673
00:28:02,320 --> 00:28:08,320
socket is creating so we can see there's
674
00:28:05,679 --> 00:28:10,629
a case for unix sockets AF underscore
675
00:28:08,320 --> 00:28:12,908
unix and what we can see is at the
676
00:28:10,629 --> 00:28:15,399
bottom of the slide there is some code
677
00:28:12,909 --> 00:28:18,279
that's checking to make sure that the
678
00:28:15,399 --> 00:28:21,428
path of the UNIX socket is null
679
00:28:18,279 --> 00:28:22,989
terminated so if we look at the source
680
00:28:21,429 --> 00:28:25,749
code we can see that this basically maps
681
00:28:22,989 --> 00:28:27,159
to our compare instruction so the
682
00:28:25,749 --> 00:28:29,169
question is you know what are these
683
00:28:27,159 --> 00:28:30,909
register values and more importantly why
684
00:28:29,169 --> 00:28:34,840
does this comparison cause a kernel
685
00:28:30,909 --> 00:28:37,419
panic so if we look closer at the audit
686
00:28:34,840 --> 00:28:40,480
argh sock adder function we can see it
687
00:28:37,419 --> 00:28:43,720
locally declares a sock adder UNIX
688
00:28:40,480 --> 00:28:45,460
structure for a UNIX socket and if we
689
00:28:43,720 --> 00:28:48,970
look at the definition of this structure
690
00:28:45,460 --> 00:28:52,250
it's in the U n dot H file we can see
691
00:28:48,970 --> 00:28:54,720
that there's a length a family and then
692
00:28:52,250 --> 00:28:57,510
so if we go back to the code for these
693
00:28:54,720 --> 00:29:01,080
UNIX socket we can see that it basically
694
00:28:57,510 --> 00:29:03,870
assigns a pass in passed in sock adder
695
00:29:01,080 --> 00:29:05,870
structure to the UNIX sock addict
696
00:29:03,870 --> 00:29:08,040
structure and then calculates a length
697
00:29:05,870 --> 00:29:10,080
now if we go back to the compare
698
00:29:08,040 --> 00:29:12,659
instruction we can now understand the
699
00:29:10,080 --> 00:29:15,240
values of each of these arguments so for
700
00:29:12,660 --> 00:29:17,760
example the RBX register at the time of
701
00:29:15,240 --> 00:29:21,390
the crash is a pointer to the UNIX sock
702
00:29:17,760 --> 00:29:24,030
adder structure r-13 is the length minus
703
00:29:21,390 --> 00:29:26,730
two and then there's a plus 2 because
704
00:29:24,030 --> 00:29:30,720
the offset of the path starts at plus 2
705
00:29:26,730 --> 00:29:32,790
within the socket structure so since the
706
00:29:30,720 --> 00:29:34,920
kernel panic report contains all the
707
00:29:32,790 --> 00:29:38,030
register values at the time of the crash
708
00:29:34,920 --> 00:29:40,800
we can basically plug in the values and
709
00:29:38,030 --> 00:29:42,450
basically recompute the address it was
710
00:29:40,800 --> 00:29:44,040
doing the compare instruction so we
711
00:29:42,450 --> 00:29:48,300
basically go to the crash report pull
712
00:29:44,040 --> 00:29:50,190
out our BX our 13 and add 2 and what we
713
00:29:48,300 --> 00:29:54,690
do is when we compute that address we
714
00:29:50,190 --> 00:29:57,210
get something that ends in 4 F 0 0 0 and
715
00:29:54,690 --> 00:29:59,880
two observations about that first that
716
00:29:57,210 --> 00:30:01,770
matches the fault CR to address which
717
00:29:59,880 --> 00:30:04,140
indicates yes this was the address that
718
00:30:01,770 --> 00:30:06,990
caused the kernel to panic and also
719
00:30:04,140 --> 00:30:10,890
since it ends in 0 0 0 this indicates
720
00:30:06,990 --> 00:30:12,990
it's at the very start of a new page so
721
00:30:10,890 --> 00:30:16,230
here's a diagram of exactly what was
722
00:30:12,990 --> 00:30:18,840
happening to cause the kernel panic so
723
00:30:16,230 --> 00:30:23,160
basically we have this UNIX structure
724
00:30:18,840 --> 00:30:25,770
that was size 16 or 10 in hex it was
725
00:30:23,160 --> 00:30:29,220
allocated at the very end of a memory
726
00:30:25,770 --> 00:30:31,940
page so basically memory page the last
727
00:30:29,220 --> 00:30:35,280
thing it had was this UNIX strong UNIX
728
00:30:31,940 --> 00:30:37,830
socket structure what happened was the
729
00:30:35,280 --> 00:30:40,770
compare instruction came along and since
730
00:30:37,830 --> 00:30:44,280
it's trying to check if the path in the
731
00:30:40,770 --> 00:30:46,320
UNIX socket is null terminated it goes
732
00:30:44,280 --> 00:30:48,360
to what it thinks is the end of that
733
00:30:46,320 --> 00:30:50,639
structure but it actually goes one byte
734
00:30:48,360 --> 00:30:54,000
past that and tries to read that byte
735
00:30:50,640 --> 00:30:56,490
and since the very next byte after the
736
00:30:54,000 --> 00:30:58,680
path is an unmapped page in kernel
737
00:30:56,490 --> 00:31:00,630
memory when the instruction tries to
738
00:30:58,680 --> 00:31:02,900
access that that's obviously going to
739
00:31:00,630 --> 00:31:05,160
cause kernel
740
00:31:02,900 --> 00:31:05,850
so I was intrigued I was like okay I
741
00:31:05,160 --> 00:31:08,400
understand
742
00:31:05,850 --> 00:31:10,169
you know why this bug is occurring but
743
00:31:08,400 --> 00:31:12,810
like you know why is this wise there's
744
00:31:10,170 --> 00:31:15,150
this off by one reader so if you read a
745
00:31:12,810 --> 00:31:17,490
little more about UNIX sockets you find
746
00:31:15,150 --> 00:31:19,200
out that this path does not have to be
747
00:31:17,490 --> 00:31:21,420
null terminated which is why Apple is
748
00:31:19,200 --> 00:31:23,610
checking to see if it is null terminated
749
00:31:21,420 --> 00:31:26,040
but there's all this confusion online
750
00:31:23,610 --> 00:31:28,229
about like how to check this path and
751
00:31:26,040 --> 00:31:30,360
the funniest is if you actually look at
752
00:31:28,230 --> 00:31:32,760
the source code in the Linux kernel they
753
00:31:30,360 --> 00:31:35,250
have an intentional off-by-one where
754
00:31:32,760 --> 00:31:37,800
they actually go one byte past the end
755
00:31:35,250 --> 00:31:41,250
of the path and check if that is a zero
756
00:31:37,800 --> 00:31:43,139
there however the code the comments in
757
00:31:41,250 --> 00:31:45,840
the code say this is intentional and
758
00:31:43,140 --> 00:31:48,360
this is okay because we guarantee that
759
00:31:45,840 --> 00:31:50,189
the very next byte after the end of the
760
00:31:48,360 --> 00:31:51,479
path is always going to be mapped in so
761
00:31:50,190 --> 00:31:53,370
this is never going to panic the box
762
00:31:51,480 --> 00:31:56,430
however that same assumption does not
763
00:31:53,370 --> 00:31:58,260
hold true on Mac OS so when you get a
764
00:31:56,430 --> 00:32:01,980
structure that's allocated at the very
765
00:31:58,260 --> 00:32:03,990
end of a page with the adjacent page
766
00:32:01,980 --> 00:32:06,530
being unmapped this cause as a kernel
767
00:32:03,990 --> 00:32:09,090
panic so kind of an interesting bug
768
00:32:06,530 --> 00:32:11,670
alright so that was a kernel panic kind
769
00:32:09,090 --> 00:32:13,879
of lame I mean it crashes the box it's
770
00:32:11,670 --> 00:32:16,380
just a read it's not exploitable so
771
00:32:13,880 --> 00:32:20,250
let's talk about some real kernel bugs
772
00:32:16,380 --> 00:32:21,900
now so the first thing did I reported
773
00:32:20,250 --> 00:32:24,180
this bug to Apple I said hey guys you
774
00:32:21,900 --> 00:32:27,210
know here's the scenario where user mode
775
00:32:24,180 --> 00:32:29,910
code can trigger a kernel panic if a
776
00:32:27,210 --> 00:32:32,580
UNIX socket is being audited and the
777
00:32:29,910 --> 00:32:34,980
structure happens to align right with
778
00:32:32,580 --> 00:32:37,980
the end of an unmapped page and they
779
00:32:34,980 --> 00:32:40,410
said okay cool we'll fix that they
780
00:32:37,980 --> 00:32:43,290
silently patched it so there's no CVE
781
00:32:40,410 --> 00:32:45,480
associated with this but if we look at
782
00:32:43,290 --> 00:32:48,300
the patch we can see that the way they
783
00:32:45,480 --> 00:32:52,410
decided to fix this was by using aster l
784
00:32:48,300 --> 00:32:54,360
copy now as their comment notes they say
785
00:32:52,410 --> 00:32:57,510
make sure the path is null terminated
786
00:32:54,360 --> 00:33:00,090
and if you're familiar with ster L copy
787
00:32:57,510 --> 00:33:02,100
it's basically a safe ster copy which
788
00:33:00,090 --> 00:33:04,860
means it'll never overflow the buffer
789
00:33:02,100 --> 00:33:07,530
but it will keep copying until it finds
790
00:33:04,860 --> 00:33:11,159
a null termination but again this path
791
00:33:07,530 --> 00:33:14,190
is not necessarily null terminated so
792
00:33:11,160 --> 00:33:15,610
more specifically ster all copy is as I
793
00:33:14,190 --> 00:33:18,700
mentioned going to copy until
794
00:33:15,610 --> 00:33:22,059
it fills up the buffer or until it hits
795
00:33:18,700 --> 00:33:24,429
a null or zero so if our socket is
796
00:33:22,059 --> 00:33:27,580
smaller than the buffer and we create a
797
00:33:24,429 --> 00:33:29,799
socket that isn't null-terminated we can
798
00:33:27,580 --> 00:33:32,100
potentially leak random kernel memory
799
00:33:29,799 --> 00:33:34,720
data so let's take a closer look at this
800
00:33:32,100 --> 00:33:37,870
first we have some code that creates a
801
00:33:34,720 --> 00:33:40,120
UNIX socket and if we look at the kernel
802
00:33:37,870 --> 00:33:42,520
we see that this is going to call first
803
00:33:40,120 --> 00:33:44,860
when we call bind on this it's going to
804
00:33:42,520 --> 00:33:48,040
call something that's a method or
805
00:33:44,860 --> 00:33:50,918
function called get soccer sorry get
806
00:33:48,040 --> 00:33:53,168
sock adders underscore s and what this
807
00:33:50,919 --> 00:33:55,210
function does is it's going to zero out
808
00:33:53,169 --> 00:33:58,450
a structure and then it's going to copy
809
00:33:55,210 --> 00:33:59,950
in that soccer socket structure that
810
00:33:58,450 --> 00:34:01,990
we're trying to Aude it basically it's
811
00:33:59,950 --> 00:34:04,630
copying it in from user mode to kernel
812
00:34:01,990 --> 00:34:06,640
book and it copies this in via the copy
813
00:34:04,630 --> 00:34:10,300
in method which just copies in some
814
00:34:06,640 --> 00:34:12,639
specified number of bytes so now let's
815
00:34:10,300 --> 00:34:14,800
try to create a UNIX socket that is not
816
00:34:12,639 --> 00:34:18,369
null terminated because again we want to
817
00:34:14,800 --> 00:34:20,679
basically get the vulnerable ster L copy
818
00:34:18,369 --> 00:34:22,300
to be called on a string that's not mall
819
00:34:20,679 --> 00:34:25,990
terminated so then it starts copying a
820
00:34:22,300 --> 00:34:28,240
random kernel memory into user mode so
821
00:34:25,989 --> 00:34:29,888
as I mentioned the way they copy in the
822
00:34:28,239 --> 00:34:32,589
path is they first zero out the
823
00:34:29,889 --> 00:34:34,480
structure and then copy that in so since
824
00:34:32,590 --> 00:34:36,250
they zero out the structure we have to
825
00:34:34,480 --> 00:34:37,990
create a path that fully fills up that
826
00:34:36,250 --> 00:34:39,820
structure because otherwise it'll be
827
00:34:37,989 --> 00:34:43,388
inadvertently null terminated because
828
00:34:39,820 --> 00:34:45,159
they first zero out that structure so if
829
00:34:43,389 --> 00:34:47,950
we look at the size of this structure we
830
00:34:45,159 --> 00:34:50,169
can see it has a max size of 128 so what
831
00:34:47,949 --> 00:34:53,888
we do in user mode is we simply simply
832
00:34:50,168 --> 00:34:56,560
allocate 128 bytes we fill that with 41
833
00:34:53,889 --> 00:34:59,680
41 41 and then we basically set the
834
00:34:56,560 --> 00:35:02,560
length to max and the family to UNIX
835
00:34:59,680 --> 00:35:05,080
socket we then call bind which will
836
00:35:02,560 --> 00:35:08,619
trigger the audit event of the socket
837
00:35:05,080 --> 00:35:10,299
and what we can do is we can see we have
838
00:35:08,619 --> 00:35:13,300
the socket structure on the slide so
839
00:35:10,300 --> 00:35:15,310
again we can see it's 128 bytes
840
00:35:13,300 --> 00:35:17,200
it's a UNIX socket and it's filled with
841
00:35:15,310 --> 00:35:18,910
40 ones most important thing though is
842
00:35:17,200 --> 00:35:22,899
it's not null terminated so there's no
843
00:35:18,910 --> 00:35:25,240
zeros in this structure if we then call
844
00:35:22,900 --> 00:35:28,769
bind this is going to trigger the
845
00:35:25,240 --> 00:35:31,680
vulnerable ster l copy in kernel
846
00:35:28,769 --> 00:35:33,839
and what its gonna do now it's going to
847
00:35:31,680 --> 00:35:37,078
start copying bytes from our non
848
00:35:33,839 --> 00:35:39,660
null-terminated path so here's a diagram
849
00:35:37,079 --> 00:35:41,910
of that and we can see if we have the
850
00:35:39,660 --> 00:35:43,410
structure in memory if after the
851
00:35:41,910 --> 00:35:46,440
structure there's a one two three four
852
00:35:43,410 --> 00:35:48,598
five six some number of bytes the stur l
853
00:35:46,440 --> 00:35:50,249
copy is just going to start copying all
854
00:35:48,599 --> 00:35:52,829
those bytes and then write that out to
855
00:35:50,249 --> 00:35:56,999
user mode either to the log audit log
856
00:35:52,829 --> 00:35:58,200
file or to the audit pipe and again
857
00:35:56,999 --> 00:36:00,720
obviously if there's sensitive
858
00:35:58,200 --> 00:36:03,450
information in the kernel hashes tokens
859
00:36:00,720 --> 00:36:05,339
and etc etc this will all get leaked
860
00:36:03,450 --> 00:36:07,229
I think end this was apple's fix to a
861
00:36:05,339 --> 00:36:10,259
camp kernel panic report so that's kind
862
00:36:07,229 --> 00:36:12,269
of the funniest thing of this all so
863
00:36:10,259 --> 00:36:14,220
let's briefly walk through this in a
864
00:36:12,269 --> 00:36:16,618
debugger to show this kind of happening
865
00:36:14,220 --> 00:36:19,259
in action so the first thing we do is we
866
00:36:16,619 --> 00:36:21,900
set a conditional breakpoint on bind and
867
00:36:19,259 --> 00:36:25,739
then here's our user mode code to create
868
00:36:21,900 --> 00:36:28,349
this null non terminated UNIX socket we
869
00:36:25,739 --> 00:36:30,539
then call bind in user mode this will
870
00:36:28,349 --> 00:36:33,029
trigger our kernel mode breakpoint to be
871
00:36:30,539 --> 00:36:35,549
hit and then if we dump various values
872
00:36:33,029 --> 00:36:38,489
we can see okay yes this is our kernel
873
00:36:35,549 --> 00:36:41,880
this is our UNIX socket and yes it has a
874
00:36:38,489 --> 00:36:43,920
path that's not null terminated so if we
875
00:36:41,880 --> 00:36:46,979
then set a breakpoint on the vulnerable
876
00:36:43,920 --> 00:36:48,960
code we can hit continue in the debugger
877
00:36:46,979 --> 00:36:53,098
and then it'll break as it's about to
878
00:36:48,960 --> 00:36:55,200
audit this UNIX socket so at that point
879
00:36:53,099 --> 00:36:57,089
we can look at the registers and we have
880
00:36:55,200 --> 00:37:00,269
a table on the slide which is the
881
00:36:57,089 --> 00:37:03,509
mapping of what the registers contain at
882
00:37:00,269 --> 00:37:05,758
the vulnerable stur L copy for example
883
00:37:03,509 --> 00:37:08,460
we can see that our ax points to the
884
00:37:05,759 --> 00:37:10,950
index of the bite to copy our BX plus
885
00:37:08,460 --> 00:37:14,099
two is the source sort bytes which is
886
00:37:10,950 --> 00:37:17,009
the pass and then our BP minus 130 is
887
00:37:14,099 --> 00:37:19,410
the buffer it's going to copy it into so
888
00:37:17,009 --> 00:37:22,799
if we step over this we can see that it
889
00:37:19,410 --> 00:37:27,989
returns 127 which means it's copied 127
890
00:37:22,799 --> 00:37:30,569
bytes so why 127 so recall we're copying
891
00:37:27,989 --> 00:37:34,410
from a UNIX sock adder structure and
892
00:37:30,569 --> 00:37:37,140
we've set its size to 128 now the path
893
00:37:34,410 --> 00:37:40,109
starts at offset 2 which means that the
894
00:37:37,140 --> 00:37:43,140
maximum path length is 126
895
00:37:40,110 --> 00:37:45,360
in memory if we dump the path there that
896
00:37:43,140 --> 00:37:48,029
we're about to audit we can see that
897
00:37:45,360 --> 00:37:51,360
right after it there's a random d7 and
898
00:37:48,030 --> 00:37:54,030
then a random 0-0 so what happens is the
899
00:37:51,360 --> 00:37:56,610
code has gone through copied to the end
900
00:37:54,030 --> 00:37:58,500
of the path since the path isn't null
901
00:37:56,610 --> 00:38:00,930
terminated it then copied the next byte
902
00:37:58,500 --> 00:38:02,460
which happened to be a random d7 looked
903
00:38:00,930 --> 00:38:04,770
at the next byte that happened to be
904
00:38:02,460 --> 00:38:07,830
zero so stop copying so in this case
905
00:38:04,770 --> 00:38:09,660
we've leaked one byte now you probably
906
00:38:07,830 --> 00:38:12,690
want to leak more than one byte at a
907
00:38:09,660 --> 00:38:14,879
time and it turns out you can so if you
908
00:38:12,690 --> 00:38:17,160
create a socket that's bigger than 128
909
00:38:14,880 --> 00:38:19,710
instead of getting allocated on the
910
00:38:17,160 --> 00:38:22,440
kernel stack it gets allocated on the
911
00:38:19,710 --> 00:38:24,810
kernel heap so then you create this
912
00:38:22,440 --> 00:38:27,540
socket and again just call bind on it
913
00:38:24,810 --> 00:38:29,730
and the vulnerable ster I'll copy we'll
914
00:38:27,540 --> 00:38:32,370
just start copying a random kernel bytes
915
00:38:29,730 --> 00:38:34,110
until it hits a zero so you can change
916
00:38:32,370 --> 00:38:36,299
the size of the socket you can call this
917
00:38:34,110 --> 00:38:38,850
as many times there's no side effect of
918
00:38:36,300 --> 00:38:41,070
this but every time you do this you will
919
00:38:38,850 --> 00:38:44,640
leak more and more kernel memory into
920
00:38:41,070 --> 00:38:47,340
user mode okay so we've talked about
921
00:38:44,640 --> 00:38:49,859
kernel panic and a kernel information
922
00:38:47,340 --> 00:38:53,250
leak but I still wanted something a
923
00:38:49,860 --> 00:38:55,890
little better so if we look within the
924
00:38:53,250 --> 00:38:58,170
same audit argh sock adder function we
925
00:38:55,890 --> 00:39:00,810
can see that there is an interesting B
926
00:38:58,170 --> 00:39:02,430
copy and a B copy is just a mem copy
927
00:39:00,810 --> 00:39:04,259
it's basically copying something from a
928
00:39:02,430 --> 00:39:08,490
source buffer to a destination buffer
929
00:39:04,260 --> 00:39:11,700
and some number of bytes now anytime you
930
00:39:08,490 --> 00:39:15,089
see a B copy function if it uses the
931
00:39:11,700 --> 00:39:16,649
source buffer as the number of bytes to
932
00:39:15,090 --> 00:39:18,660
copy take a very close look at that
933
00:39:16,650 --> 00:39:20,760
because if the destination buffer is
934
00:39:18,660 --> 00:39:25,020
smaller than the source buffer you may
935
00:39:20,760 --> 00:39:26,970
get a heap overflow so what B copy is
936
00:39:25,020 --> 00:39:29,220
doing it's basically just copying a
937
00:39:26,970 --> 00:39:32,700
soccer a socket into a sock adder
938
00:39:29,220 --> 00:39:34,529
structure so if we look at the table on
939
00:39:32,700 --> 00:39:36,689
the slide these are exactly what it's
940
00:39:34,530 --> 00:39:39,000
copying so the source is just a sock
941
00:39:36,690 --> 00:39:41,610
adder structure the destination is a
942
00:39:39,000 --> 00:39:43,830
sock adder storage which we'll look at
943
00:39:41,610 --> 00:39:47,940
that closer and the size is the length
944
00:39:43,830 --> 00:39:51,000
of the source buffer so the question
945
00:39:47,940 --> 00:39:53,550
then comes is can we basically create a
946
00:39:51,000 --> 00:39:56,040
source sock
947
00:39:53,550 --> 00:39:59,010
socket sock adder structure that's
948
00:39:56,040 --> 00:40:01,140
bigger than this destination buffer and
949
00:39:59,010 --> 00:40:03,060
the answer is yeah so the destination
950
00:40:01,140 --> 00:40:05,279
buffer is always going to be a hundred
951
00:40:03,060 --> 00:40:07,799
and twenty eight bytes in size so if we
952
00:40:05,280 --> 00:40:10,440
can create a socket that has more than
953
00:40:07,800 --> 00:40:13,290
128 bytes we will get a nice ring zero
954
00:40:10,440 --> 00:40:15,540
heap overflow so again we're gonna use a
955
00:40:13,290 --> 00:40:17,850
UNIX socket because a UNIX socket allows
956
00:40:15,540 --> 00:40:20,279
you to specify a path and the path can
957
00:40:17,850 --> 00:40:21,720
be bigger than 128 so this allows us to
958
00:40:20,280 --> 00:40:25,050
create a socket that's essentially
959
00:40:21,720 --> 00:40:27,569
bigger than the destination buffer so we
960
00:40:25,050 --> 00:40:29,970
create the socket and then we call bind
961
00:40:27,570 --> 00:40:32,040
the call to bind will trigger the
962
00:40:29,970 --> 00:40:34,740
vulnerable audit code which is trying to
963
00:40:32,040 --> 00:40:37,890
audit the socket and then this will
964
00:40:34,740 --> 00:40:39,839
invoke the vulnerable B copy so the
965
00:40:37,890 --> 00:40:42,390
diagram on the slide we can see we have
966
00:40:39,840 --> 00:40:44,640
this UNIX socket I've created it to be
967
00:40:42,390 --> 00:40:46,770
200 bytes in size it could be bigger
968
00:40:44,640 --> 00:40:49,529
could be smaller but the important thing
969
00:40:46,770 --> 00:40:51,540
is it's bigger than 128 so the B copy
970
00:40:49,530 --> 00:40:53,160
comes along and says okay I want to make
971
00:40:51,540 --> 00:40:56,190
a copy of this path I want to make a
972
00:40:53,160 --> 00:40:57,779
copy of this socket structure I'm going
973
00:40:56,190 --> 00:41:00,330
to basically copy it into this
974
00:40:57,780 --> 00:41:03,150
destination buffer that's 128 bytes in
975
00:41:00,330 --> 00:41:05,490
size and the length I'm gonna use is the
976
00:41:03,150 --> 00:41:08,220
size of this source buffer not the size
977
00:41:05,490 --> 00:41:09,990
of the destination so since the source
978
00:41:08,220 --> 00:41:14,970
buffer is bigger than the destination
979
00:41:09,990 --> 00:41:16,950
buffer we get an ICP overflow so how do
980
00:41:14,970 --> 00:41:18,359
you exploit this vulnerability due to
981
00:41:16,950 --> 00:41:20,339
time constraints can't really go into
982
00:41:18,359 --> 00:41:23,549
all the details but it's actually pretty
983
00:41:20,340 --> 00:41:25,530
easy for a variety of reasons so first
984
00:41:23,550 --> 00:41:28,200
we control the number of bytes to copy
985
00:41:25,530 --> 00:41:31,080
so it's a tactical over overflow you can
986
00:41:28,200 --> 00:41:33,569
copy and overflow as many or as few
987
00:41:31,080 --> 00:41:35,730
bytes as you want we also control the
988
00:41:33,570 --> 00:41:38,220
values of the bytes being copied so they
989
00:41:35,730 --> 00:41:39,780
can have zeros they can have 7f they can
990
00:41:38,220 --> 00:41:42,899
have you know there's no constraints on
991
00:41:39,780 --> 00:41:45,180
that most importantly though if we look
992
00:41:42,900 --> 00:41:47,580
at where this dish destination buffer is
993
00:41:45,180 --> 00:41:50,129
that's getting overflowed we can see
994
00:41:47,580 --> 00:41:51,450
that it's part of a larger structure so
995
00:41:50,130 --> 00:41:53,550
it's self-contained with something
996
00:41:51,450 --> 00:41:55,618
within another structure and this is
997
00:41:53,550 --> 00:41:58,380
important because this means that after
998
00:41:55,619 --> 00:42:01,200
that buffer there are always going to be
999
00:41:58,380 --> 00:42:03,630
other values for example pointers that
1000
00:42:01,200 --> 00:42:05,819
we can corrupt so normally when you're
1001
00:42:03,630 --> 00:42:07,320
exploiting a heap overflow you don't
1002
00:42:05,820 --> 00:42:08,880
know what's going to be next to the
1003
00:42:07,320 --> 00:42:10,470
buffer you're overflowing so what you
1004
00:42:08,880 --> 00:42:11,910
have to do is you have to spray you have
1005
00:42:10,470 --> 00:42:14,310
to allocate you have to groom the
1006
00:42:11,910 --> 00:42:16,500
Colonel Heep then you have to try to get
1007
00:42:14,310 --> 00:42:19,170
an adjacent object that you control
1008
00:42:16,500 --> 00:42:21,750
trigger the overflow and then gain code
1009
00:42:19,170 --> 00:42:24,180
execution that way in this case though
1010
00:42:21,750 --> 00:42:26,700
we have a self-contained overflow and
1011
00:42:24,180 --> 00:42:28,859
again the destination buffer is part of
1012
00:42:26,700 --> 00:42:30,870
another structure so there's pointers
1013
00:42:28,860 --> 00:42:32,370
there that we can tactically hit we
1014
00:42:30,870 --> 00:42:35,370
always know those pointers are going to
1015
00:42:32,370 --> 00:42:37,049
be there so here for example we can
1016
00:42:35,370 --> 00:42:40,980
corrupt some of those pointers and set
1017
00:42:37,050 --> 00:42:42,900
them to 41 41 41 41 so once you have
1018
00:42:40,980 --> 00:42:45,090
this ability there's some other talks
1019
00:42:42,900 --> 00:42:47,730
that have been presented about exactly
1020
00:42:45,090 --> 00:42:49,470
how to leverage this to get control of
1021
00:42:47,730 --> 00:42:51,140
the instruction pointer and then do all
1022
00:42:49,470 --> 00:42:53,330
sorts of evil things for example
1023
00:42:51,140 --> 00:42:56,129
disabling system integrity protection
1024
00:42:53,330 --> 00:42:58,620
gaining unsigned code execution in the
1025
00:42:56,130 --> 00:43:01,860
context of the kernel all that good
1026
00:42:58,620 --> 00:43:05,370
stuff all right so let's wrap this all
1027
00:43:01,860 --> 00:43:07,380
up so we started by talking about the
1028
00:43:05,370 --> 00:43:09,180
many benefits of auditing so again if
1029
00:43:07,380 --> 00:43:11,400
you're interested in doing malware
1030
00:43:09,180 --> 00:43:13,710
analysis or writing security tools for
1031
00:43:11,400 --> 00:43:15,690
mac OS definitely check out the auditing
1032
00:43:13,710 --> 00:43:18,630
mechanisms you can utilize them to
1033
00:43:15,690 --> 00:43:21,840
create very powerful auditing tools
1034
00:43:18,630 --> 00:43:24,330
pretty easily we talked about a kernel
1035
00:43:21,840 --> 00:43:26,490
panic that was inadvertently found by a
1036
00:43:24,330 --> 00:43:30,120
user mode process monitoring library
1037
00:43:26,490 --> 00:43:32,759
that was silently patched in the 10.12
1038
00:43:30,120 --> 00:43:34,859
dot 4 dot beta when I looked at apples
1039
00:43:32,760 --> 00:43:36,480
patch I saw that not only had they not
1040
00:43:34,860 --> 00:43:38,580
patched the bug they actually had
1041
00:43:36,480 --> 00:43:40,470
introduced an even worse vulnerability
1042
00:43:38,580 --> 00:43:41,880
so a little secret look at apples
1043
00:43:40,470 --> 00:43:44,220
patches because they mess them up all
1044
00:43:41,880 --> 00:43:45,990
the time so you can find some really
1045
00:43:44,220 --> 00:43:48,750
interesting bugs basically just wait
1046
00:43:45,990 --> 00:43:50,339
till they release some CVE details diff
1047
00:43:48,750 --> 00:43:54,330
the kernel will look at their patches
1048
00:43:50,340 --> 00:43:56,820
and Frio days and finally we also showed
1049
00:43:54,330 --> 00:43:59,100
a heap overflow that would give us code
1050
00:43:56,820 --> 00:44:01,080
execution in the context of the kernel
1051
00:43:59,100 --> 00:44:03,900
allowing us to do things like bypass
1052
00:44:01,080 --> 00:44:05,880
system integrity protection or execute
1053
00:44:03,900 --> 00:44:09,030
unsigned code in the context of the
1054
00:44:05,880 --> 00:44:11,220
kernel so very briefly since you're
1055
00:44:09,030 --> 00:44:13,080
attending my talk on Mac security I just
1056
00:44:11,220 --> 00:44:15,750
want to briefly mention my personal Mac
1057
00:44:13,080 --> 00:44:17,970
security website a lot of free
1058
00:44:15,750 --> 00:44:20,620
open-source Mac security tools I also
1059
00:44:17,970 --> 00:44:22,629
blog about Mac malware
1060
00:44:20,620 --> 00:44:24,759
and blog about zero days and
1061
00:44:22,630 --> 00:44:26,950
vulnerabilities I find so everything
1062
00:44:24,760 --> 00:44:30,670
here is free so hope this doesn't sound
1063
00:44:26,950 --> 00:44:32,830
like a sales pitch alright so that's a
1064
00:44:30,670 --> 00:44:35,050
wrap again I'm on Twitter a Patrick
1065
00:44:32,830 --> 00:44:37,210
world all the website is objective-c and
1066
00:44:35,050 --> 00:44:39,640
I think we have a few minutes for
1067
00:44:37,210 --> 00:44:41,380
questions if not I will be around after
1068
00:44:39,640 --> 00:44:43,569
the talk I would love to chat again
1069
00:44:41,380 --> 00:45:01,840
thank you so much for attending my talk
1070
00:44:43,570 --> 00:45:03,670
I really appreciate yes question yes so
1071
00:45:01,840 --> 00:45:06,250
the question was was the heap overflow
1072
00:45:03,670 --> 00:45:08,320
related to the same control flow the
1073
00:45:06,250 --> 00:45:10,240
same auditing mechanisms and the answer
1074
00:45:08,320 --> 00:45:13,810
is yes so all three bugs I talked about
1075
00:45:10,240 --> 00:45:15,459
were all within the open BSM code which
1076
00:45:13,810 --> 00:45:17,350
lives in the kernel the auditing code
1077
00:45:15,460 --> 00:45:19,060
and actually all three bugs were in the
1078
00:45:17,350 --> 00:45:21,069
same function so there's a lot of other
1079
00:45:19,060 --> 00:45:23,259
auditing functions that you might want
1080
00:45:21,070 --> 00:45:27,430
to take a look at I don't think anyone's
1081
00:45:23,260 --> 00:45:29,680
audited the audit code but again yes so
1082
00:45:27,430 --> 00:45:31,600
basically to answer your question it you
1083
00:45:29,680 --> 00:45:34,480
know it was all within the auditing
1084
00:45:31,600 --> 00:45:36,310
subsystem first the the the panic was
1085
00:45:34,480 --> 00:45:37,690
triggered inadvertently when I just
1086
00:45:36,310 --> 00:45:39,400
started using it and then I took a
1087
00:45:37,690 --> 00:45:42,700
closer look audited some of the code and
1088
00:45:39,400 --> 00:45:44,560
found the kernel information leak due to
1089
00:45:42,700 --> 00:45:46,029
apples patch and then the heap overflow
1090
00:45:44,560 --> 00:45:48,610
was just actually three lines of code
1091
00:45:46,030 --> 00:45:49,690
above so I would audit that code there
1092
00:45:48,610 --> 00:45:57,610
might be some other interesting bugs
1093
00:45:49,690 --> 00:45:59,800
there yes question so the first one was
1094
00:45:57,610 --> 00:46:01,390
okay so the first one the first panic
1095
00:45:59,800 --> 00:46:02,800
and I was like this is annoying I was
1096
00:46:01,390 --> 00:46:04,900
like oh cool this is like a security bug
1097
00:46:02,800 --> 00:46:06,970
and then I decided to look at apples fix
1098
00:46:04,900 --> 00:46:09,310
because I wanted to make sure that when
1099
00:46:06,970 --> 00:46:11,439
I deployed my tool my user mode tool it
1100
00:46:09,310 --> 00:46:13,750
wasn't gonna cause users computers to
1101
00:46:11,440 --> 00:46:16,000
panic and then I looked at their fix and
1102
00:46:13,750 --> 00:46:18,070
I was like what were they thinking like
1103
00:46:16,000 --> 00:46:20,470
they they say it's not null terminated
1104
00:46:18,070 --> 00:46:23,050
and they use asteroid copy and then you
1105
00:46:20,470 --> 00:46:24,160
know the the function was 20 lines of
1106
00:46:23,050 --> 00:46:25,570
code and I was okay there's very two
1107
00:46:24,160 --> 00:46:27,970
bugs in here there might be something
1108
00:46:25,570 --> 00:46:29,380
else and you know when I was testing the
1109
00:46:27,970 --> 00:46:31,480
kernel information leak it actually
1110
00:46:29,380 --> 00:46:34,690
triggered the heap overflow so again
1111
00:46:31,480 --> 00:46:36,690
like finding kernel bugs and
1112
00:46:34,690 --> 00:46:39,070
you know it's it's still pretty easy so
1113
00:46:36,690 --> 00:46:44,800
or maybe I'm just really lucky but now
1114
00:46:39,070 --> 00:46:46,510
it's it's easy awesome well thanks again
1115
00:46:44,800 --> 00:46:49,090
for attending and I'll be around if you
1116
00:46:46,510 --> 00:46:53,070
want to chat also these slides I will be
1117
00:46:49,090 --> 00:46:53,070
online I think tomorrow so thanks again