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