 Good afternoon everybody. Welcome to the last day of DEF CON 26. Yeah. And uh, I'm assuming most of you are still waking up. Uh, but this will be a really good presentation. Uh, you uh, Wang, uh, is going to be, or Yuang, is going to be talking about attacking the Mac OS kernel graphics driver. So please give them a hand and welcome them here. Yeah. Hello everyone. Uh, welcome to my presentation, uh, especially during lunchtime. My name is Wang Yu, uh, from DD Research America. Uh, what I, I'd like to share with you today is related to Mac OS graphics driver vulnerability and, uh, Mac OS kernel security. Um, I started to pay attention to Mac OS kernel security last year, including, uh, kernel driver development, bug hunting, and, uh, vulnerability exploitation. Before that, I preferred to study the Windows kernel security and, uh, Android Linux kernel root. Um, yeah. After entering the Mac OS kernel world last year, I learned a lot of well-known kernel vulnerabilities and I picked up four of them as the background for today. The first case is from EMBU, from Google project zero. And the CV number is the CV 2015, 3712. It's a NVIDIA G-force driver, arbitrary kernel memory write vulnerability. This vulnerability can eventually lead to code execution due to lack of input parameter validation. And, uh, at here, uh, you can find a POC. Uh, the second vulnerability comes from Cisco Talos research team. Uh, we just, uh, a non-point dereference bug. Uh, it seems that the non-point dereference type of vulnerability can be exploited two years ago, which also means, uh, which also means that I'm late. Um, you can see that, uh, there's a full exploit code on the exploit database, which is a good starting point for, uh, exploitation research. And the next case is from my friend, Chen Liang. The tech service he chooses is, uh, user-mode graphics demon. And he won the pontoon game, pontoon game, uh, with this vulnerability two years ago. The user-mode demon associated with, uh, graphics library has certain permissions. And they are usually accessible in the sandbox process. And the logic of those demons is usually very complicated. Uh, this condition determines that the demon are nature attack surface. And you can, uh, get more detailed information from the write-ups. Uh, the last is also from King Lab. The CV number is, uh, 2016, uh, 1850. It's a, it's an IO accelerator family out of bounds, kernel memory write-up vulnerability. The graphics rendering engine is one of the hardest hit areas on any operating system platform. From the 1-3-2-k driver on windows to, uh, to the IO accelerator family in kernel extension on macOS. Um, those type of, uh, uh, uh, the type of those four vulnerability I choose ranged from non-point dereference, double-free, and use-after-free to, uh, arbitrary kernel memory write vulnerability. And also, uh, the ranged from user-mode to kernel-mode. Uh, this case has repeatedly reminded us that the graphics security cannot be ignored. So therefore, I decided to start my kernel macOS kernel research from here. And part two, part two is, uh, from end-day POC to zero days. When I decide to investigate the Apple graphic driver vulnerability, last year I started my research from the POC samples from EMBU, such as, uh, uh, 2017 to 443 and, uh, 2017 to 489. The reason for choosing this example is that they are very easy to learn. Um, the logic of the POC code is clear, and the amount of the code is less than 100. Uh, we can take, uh, to the first one, the, the two, four, four, three as an example. Two, four, four, three is a kernel arbitrary code execution vulnerability. Uh, as you can see, uh, the target of the POC is the Intel FB client control. Uh, it's a, it's a number, number one in green color. And the input selector here, uh, uh, it's a number three in blue color. The input selector is 291, uh, in, in hex format. And then the only thing we need to do is, uh, fill the input buffer with random garbage data. It's a number three in red color. So just this. So I think for the security research community, uh, each of us will think about how to start a new round of kernel code auditing from here. Um, after I had this idea, one of my friends told me that starting from here might be a, we stop time because the binary has already carefully examined by Google project zero. Um, this, uh, reminds me of my Windows kernel found scalar engine vulnerability presentation at black cat USA four years ago. At that time, Jura from Google project zero found a large number of kernel found, uh, scalar vulnerabilities. But I can still find a new kernel, find new kernel double fetch zero days in the code that has been audited such as, uh, three two thousand four fifteen, uh, one nine, one eight, one nine. So this time I still want to give it a try. But, but then I began to feel that my friend was probably right. My, my fasting tour didn't have any valid it's out food, uh, on the first day. And, and even the break points I set it in, uh, macOS kernel didn't trigger. Um, uh, fortunately for me, I didn't give up at that time. Otherwise, I, I don't think we will meet today. Um, when I analysis the root cause, I found at least three problems, uh, hidden, uh, the work of my fasting system. Uh, without first serving, uh, these problems, the whole system will become very efficient, efficient. Um, there are, yeah, there are three obstacles. The first one is, uh, target selection. And second one is, uh, is a fuel driver protection. And third one is, uh, unremarkable selectors. Yeah, let me, uh, discuss it in detail. Um, first one, target selection. Uh, there are, there are many different targets on the macOS system from kernel extension to internal classes. And, uh, uh, we, we mentioned before that Intel FB client control is just one of the very small branch of the graphics, uh, kernel. Uh, I list some of the target drivers here. There are a lot of from, uh, AMD to, uh, NVIDIA to Intel, uh, and also, uh, IO family drivers is a, is a, uh, AMD, uh, Intel is like a mini pod driver and the, and the family driver is, uh, more general driver, kernel driver. And I think, uh, as a professional, uh, security researcher, we should not miss any possibility. Um, and next one is the most, more important. The second obstacle is the fuel to driver. Uh, before touching the target graph driver, there are usually a fuel to driver that protect them, which can, uh, cause our fuzzing tool to fail into an effective loop. Um, in this, in this figure, uh, we can see that before touching the graphics driver, uh, Apple Intel, FrameBuffer, Azo, uh, fuel to driver, Apple graphics device can choose, is defining against the malicious input for the graphics driver. Um, here is the fuel to driver in right line and, uh, the green line is, uh, it's a graphics driver itself. More specifically, in this example, Slector 707 represents, uh, FB set EDID and correspondingly in the filter driver here, at here. If the input buffer length is not equal to, uh, 408 bytes, all fuzzing attempts for the interface are meaningless. This means that if we only rely on the static analysis of the target driver and then build the fuzzing process, it's obviously not enough. We need to consider the entire architecture of the graphics driver set. Otherwise, we are just wasting our time. The third obstacle is, uh, unremarkable selectors. After actually getting to the target driver, I found that there are still some hidden control codes or selectors. And I, uh, found, uh, the are also, uh, the control code, um, the control code, uh, affect, uh, the, uh, infections of the fuzzing system indeed. This control code are important because they are the key to open the door to another world. Uh, meaning that there are a lot of unknown code behind their doors, their doors. Um, after extracted all the validated control codes with ID script last year, I found at least, uh, one such key. It's, uh, 80, 0, 0, 0, 0, and some random data. As you can see, after entering the corresponding handler, there's another word hidden there. And after taking, uh, after taking, so after taking their small, three small steps, things quickly become clear. And I found a lot of problems in just one day. Let me show, uh, share some examples with you. The first, the first one is, uh, unpatched, uh, local panic caused by a division by zero error. But be aware that the root cause behind this error is, uh, is, uh, out of bounds read access to the input buffer. Uh, it's, uh, it's a division, uh, by zero. Um, uh, register R 12, R 12 is zero. And a key two. Key two is, uh, is an unpatched local panic. Caused by non-point dereference. And the root cause of the problem is that the driver, uh, incorrectly initialized, uh, and the dereference, uh, variable. Um, at here, RSI register is zero and, uh, offset is, uh, three F 70. The next case is, uh, kernel stack, stack-based buffer vulnerability. As you can see here, um, uh, this stack overflow vulnerability is mitigated by stack cookie. So in order to exploit this case, we need to have, uh, we need to have the kernel arbitrary memory reading capability. Fortunately, I quickly found one. Uh, CVE 2017 13383. Combined with, uh, two vulnerabilities, we can bypass the stack cookie protection. And again, kernel arbitrary code execution capability. Uh, but compared to kernel, uh, arbitrary kernel memory reading, uh, I think, uh, uh, kernel arbitrary memory writing capabilities often what we really want. And here is an example. CVE ID 7155. And through it, we uh, I, I find more cases such as, uh, CVE 2017 7163. Yeah, let's take the, uh, let's, let's take this one, uh, as an example, uh, to discuss the kernel arbitrary memory write vulnerability. The root cause of this vulnerability is that frame buffer driver lacks input validation and the sanitization. Um, and as you can see here, this instruction, uh, this instruction, uh, move edx to rax plus rsi. Um, this instruction is going to write value uh, in rd edx to offset of, uh, to the offset of rax plus rsi. And rax at here is a base address of a kernel object is, um, and uh, we can lock it through the arbitrary kernel memory read vulnerability. And we can control the ESI register at here. It's all a, a, a, a, a, a. We can control this, uh, register. This means that we can control the target memory address of arbitrary write primitive. And then we can fully control the rd edx register. At here, uh, edx is, uh, all controlled by, uh, attacker. Um, this means that, uh, we can control the value to be written. The above conditions are perfect to achieve arbitrary memory, uh, arbitrary memory write arbitrary values. So, so, in my opinion, the, the quality of this vulnerability is pretty good. Yeah, but I still choose to report it to Apple last year. Um, yeah, yeah, because I'm not using my laptop, I'm, I'm able to, I'm able to make the, uh, demonstration. Um, yeah, I didn't take the video for it, but, uh, trust me, uh, this type of, uh, demo is boring. Uh, just, uh, run the exploit and, uh, pop up a root shell. And, and, and the quality of this, uh, because the quality of this vulnerability is pretty, pretty good. So, it's very easy to write exploit, exploit code for this. Uh, I think you can give it a try. Yeah, the, the first part is, uh, yes, here, uh, from there, uh, NDPOC to there. The next part, I think is more, uh, interesting. A chemo framework and, and, and other projects I, uh, I did last year. Last year, one of my task was to build a kernel monitoring system for our DLP project, data leakage prevention project. And when I went to study the existing kernel monitoring interface, I found that the building monitoring mechanisms were not very friendly for a third-party development. Specifically, uh, there are two building monitoring mechanisms available. Uh, kernel authorization subsystem and manager access control, uh, policy subsystem. But the bad news is, is that they are not suitable for the current security related kernel development tasks. Uh, the kernel authorization subsystem was introduced in the macOS, uh, 10.4 Tiger kernel in 2005. And the problem now is that, uh, this callback interface lack the necessary maintenance and have not been upgraded for about 13 years. Um, yeah. Uh, for, for the, uh, scope file operation, number two, for the file operation listener. There are only seven file operation related callbacks available. Uh, I think which is not, which is obviously not enough. There are only, uh, file open, close, delayed, read-write, uh, rename, exchange, and, uh, create process. But I, I think this is obviously not enough. And for, uh, for the operation, file operation listeners, they are unable to block any file operations. Just notification, uh, just notification is, uh, unacceptable. Uh, say, uh, we detect the ransomware and, uh, we can only watch it and we cannot block it. So if my endpoint security solution is this, I think my boss might fire me. Um, and for some specific callbacks, the input parameter often lack critical context information. For example, for create process callback handler, the input parameter is missing command line information. Uh, this is very important to us. And, uh, in the file operation callback handler, we cannot distinguish between new file creation and the open existing. It's also important to us. And for, we know the listeners, uh, not every file system operation triggers an authorization request. This means that our monitor can be bypassed. Uh, it's also not acceptable. Um, yeah, compared with current authorization subsystem, monitor access control framework has a series of more granular callback interface, which are introducing into kernel from macOS 10.5. Yeah, 10.5. However, Apple quickly banned the third parties from using this interface and climbed that, that this interface were not part of the KPI, a KPI is short for kernel programming interface. This means that the monitor access control framework is totally private. Yeah, uh, we cannot use that, uh, interface. But if you really want to, uh, use that interface in kernel, uh, since we are all kernel extension, we have permission to, uh, locate the target function in kernel and, uh, and then invoke it. Yeah, if you really want to use the interface in kernel, I think you will meet the following capability, uh, compatibility issues. I reviewed almost all the kernel open source code about mac policy. Um, and I, I found this one, uh, the following cases. The case one, case one shows that the interface were deleted or replaced, replaced directly by kernel. This, this is unacceptable because the feature disappeared, uh, disappeared directly. Uh, this can't, I cannot accept this. And, uh, case two, case two shows that the protocols and the input primeters were changed directly. It's also unacceptable because my driver will panic. Uh, you cannot add a, add a, uh, a parameter directly into the prototype. Right. And case three shows that the interface was inserted into the middle of the dispatch table. Yeah, my, my driver will panic too. And, uh, here's the case four. The interface has been rewritten but forgot to upgrade the policy version number. So my point is that as a third party developer, we have to use this mechanism very, very carefully. And in order to bring out some changes, I'd like to introduce you to Kimo, uh, open source and open source pre and post callback based framework for macOS kernel monitoring. Um, since there's no patch guard or similar kernel self-detection subsystem, I built the pre and post operation callback interface based on my kernel inline hook engine. Uh, by using this framework, I can, uh, add new features to any function I care about. Uh, the, the base, the idea of the pre and the post operation callback architecture is, uh, actually is borrowed from Windows kernel. Uh, generally speaking, uh, in the pre callback handler, I can field the input parameters. And in the post callback handler, I can reset the function's return value if needed. I have two examples here. Um, the first one is, uh, is a kernel extension monitor or, uh, kernel extension firewall. Yeah, I, I know there's a, there are similar functions in mac, managed access control policy mechanism, but I still want to use my own method to achieve it again. As can be seen, uh, here, the first line is a pre callback handler. And in the pre callback handler, I can field the input parameters. Uh, it's, it's, it's more. Um, such as, such as, uh, I can get the, um, UID, I can get PID, uh, parent ID, and, uh, the kernel extension name is, uh, com.mandinate.monitor and pass and also version number, uh, mo, module base and a module, module size. Um, yeah, in, in this case, I use a file, manage it to our, uh, it's named monitor.app as an example. The reason is just because it contains the driver and will load that driver into kernel. This is true. Um, yeah. And in the post callback handler, in the pre callback handler here, I using a disassembly to, uh, search the end point of the target driver and I can patch the driver end point. So, as can be seen here, the driver failed to load. And in the post callback handler, I can reset the function return value if needed. Another more interesting example in the manager access control policy is, uh, manager access control policy monitor. Um, so, uh, are you, uh, wondered about, uh, which module in the system use, uh, manager access control policy and which policy set do they use? I, I think here is the answer. As, as can be seen, the first one, uh, I dumped from kernel is AMFI. AMFI is short for Apple mobile file integrity. And, uh, it's all handlers of this module, uh, including, uh, base address, a module of set, set and, uh, policy name. Um, yeah. As you can see, uh, AMFI and, uh, this one is, uh, sandbox. Uh, Mac sandbox registered a large number of Mac policies. Um, yeah, the, the tricky part of this feature is how to get the mutex lock. Um, I mean, we need to hold the lock before accessing kernel data structures. Um, yeah, but the policy lock, policy mutex lock is not exported. Unfortunately, I found, uh, I finally found a way to, to lock that, uh, uh, that mutex lock. And you will, you can, uh, reveal my code for, for more information. And in addition to, uh, in, in, in illuminating and monitoring manager access into policy, Kimon can also, um, block or handjake arbitrary handlers if needed. In this case, I still use the file maintenance to monitor dot APPS and example. Uh, the reason is this tool will try to register five, uh, amazing callbacks. The first one is, uh, is for, uh, process monitoring. The second one is for dynamic library monitoring. The third one is for a keyboard monitoring and, uh, and it's, uh, file operation. Last one is kernel extension. Um, and Kimon can block. There's the request. Here's the example. Um, yeah, demo. I, I demo, demonstrated, uh, demonstrated this, uh, at blackhead arsenal three days ago and I didn't make the video for it. Yeah, but, but don't worry. Um, talk is cheap. Show me the code, right? Definitely. I released all my source code. Um, yeah, please check out my source code for more detailed information. Um, yeah, in addition to the two application above, I also implement a kernel buzzing helper by using, by using Kimon framework. I call it, uh, keeper. A keeper can randomly inject arrows, uh, assist in recording the input parameters and call stacks of the graphics driver. Yeah, for me, uh, this feature is very helpful. Uh, as can be seen here, uh, I, uh, I unhooked, uh, into every client control do attributes and, uh, and this is my buzzing tool. A selector is, uh, is a random and input data is, uh, it's also random. Um, yeah, and, and this, uh, figure shows that the input data is, uh, is random data and I can do bit flipping here. Um, actually I, I, I also implement another, uh, two, uh, also project for monitoring, uh, IPC communication. Okay. Okay. Yeah, last part, uh, last part is, uh, discussion of zero days and, uh, MacOS kernel protection. Um, yeah, first, let me show you a graphics driver related to zero day. Uh, I have a simple demo. This system has, uh, all the system patches installed and, and, uh, after running my POC, the system crashed. It's, it's really, really, really good. And, and here is the cost stack information. Um, it's a heap overwrite vulnerability and the panic cost stack shows that, uh, it's a victim thread. This victim thread is accessing the corrupted heap and, uh, and this is another crash, uh, crash thread. In fact, there are all victims of the vulnerability because the, the thread are crops, crops, the heap is not theirs. And the root cause of this vulnerability is the following piece of code. Uh, let me give you some background on this code. The input, uh, in the yellow color, the input is the length of my input tent data. And, uh, the length of the input data should be a multiple of 10. Uh, all, all numbers are in Higgs format. It should be a multiple of 10. And, uh, the general logic of this code is that it processed, uh, uh, one round every 10 bytes. Um, if the final length is less than 10 at here, if the final length is less than 10, the code breaks the loop. So, can you find the bug in this code? I, I find the bug manually. Uh, yes, uh, the, the problem comes from this, uh, subtraction, uh, operation. If the input buffer length is greater than 10, this code is fine. Uh, but, but if the, the buffer size are passing is less than 10, you can see here, less than 10, this subtraction will cause an integral flaw. And then, the memory copy here, at here, will destroy the adjacent heap. Um, and I submitted this, uh, vulnerability to Apple security this week, and I also met them this morning. Uh, I'm sure the vulnerability will be fixed soon. And to protect against the threat from the graphics drivers, I did some extra work based on the Keymoon framework. By using the kernel inline hook engine, I hooked up some key functions of graphics drivers, such as, uh, uh, do attributes interface. Uh, as can be seen, uh, in those handlers, I can filter the opening and setting operations of untrusted domain. The, the untrusted domain is, uh, uh, my, uh, graphics further process. Um, so which means I can reject some, uh, malicious requests. Uh, by the way, I, I'm very much, uh, hope that Apple can add the similar functionality to kernel through the, uh, manager access control policy and, or detrace interface. Yeah. Um, yeah, this is almost my presentation. Um, we, we discussed the bug hunting, uh, zero, zero day vulnerabilities and the Keymoon open source project. And I also mentioned, uh, third party kernel protection and mitigation. Um, I released all the source code. Uh, please check it for, for more detailed information. Yeah, that's it. Thank you guys.