 Our next speakers, one of them is returning, one of them is brand new. We have a little tradition for brand new speakers, so before we get started, we're going to do a shot. Hello, hello. So good afternoon everyone. Today, today we will present a topic about uh, kernel security. One byte and all your dreams will come true, analyzing and attacking Apple kernel drivers. So, uh, this is Bai Xiaolong. Um, my name is Zheng Min. You can call me Spark. Uh, we are PhDs and work for Alibaba. So here is the agenda. First, we briefly introduce what is kernel driver, then we talk about new vulnerabilities in Apple drivers. Uh, after that, we will talk about obstacles in analyzing Apple drivers and then introduce a new tool called RIC for analyzing and fuzzing kernel drivers. So, let's start. First thing you should know is every driver in uh, in kernel is, in X and U is a kernel extension. They share a same space with the kernel. On Mac OS, uh, the drivers locate in the uh, system library extensions. On iOS, drivers are integrated with kernel in the kernel cache. Uh, kernel drivers provide user client, which are kernel objects for drivers to provide service to programs in user space. Also, user client is an interface between user space, applications and devices. In order to provide services, uh, user clients need to implement several callback methods, like external method, client memory for type, register notification port, uh, client close and so on. Uh, the most important method, callback method is uh, uh, external method, which provides the methods to user space program. The selector is used to select the method in user client. Arguments are passed to the selected method. Uh, dispatch is uh, struck, struck representing the method to be called. The target is the target user client for the method to be called on. Reference is the result which is sent back to the user space. Uh, despite the strict, uh, sandbox restriction, some user clients are still be accessible to sandbox apps on iOS. For example, uh, IOHID Lib user client, and uh, IOS service root user client. So now we will share some vulnerabilities we found in Apple drivers. Uh, the first thing you should know is the driver is uh, the driver are good targets for exploring the kernel, because they share the same space with the kernel, and they have the same kernel privileges. So uh, some drivers are programmed by third party vendors, not the kernel developers. So uh, the code quality is not guaranteed. So a lot of drivers are frequently exploited uh, in attacks against the kernel, including the jailbreak. Uh, a lot of vulnerabilities are used in jailbreak. For example, iOS 11 used the IO service root. Uh, Pangu 9 used uh, first, uh, in their, in their first version they used the IOHID family, and the second version they used the IO buffer frame, IO mobile buffer, uh, frame buffer. Uh, the first, uh, this is the first vulnerability. Uh, it is uh, info, information link in IO firewall family. It is caused by uh, initialize the kernel uh, stack variable, which is out channel handle uh, in the ISO channel alloc keys. And you can see in the IOCH channel create, the out uh, channel handle is passed into the uh, add object function. In this function you can see the out handle should be set with the index of new added object. But when the new uh, capacity reaches FFFE, new object will not be added and out handle will not be set. Recall the allocation case in external method. Out handle is uh, uh, uh, initialize the uh, variable and return to user space. So that is uh, info, that is an information link. Uh, you can use this information to help you to get the kernel slide and then defeat KASLR. Uh, the second bug is, uh, use after free vulnerability in the IO accelerator family too. It has a method called S transaction end. In this method, the user client will call transaction end in IO uh, uh, accelerator uh, display pipe two. Note that all user clients share a same pipe two instance. Pipe two can uh, contains a link list for transactions. And pipe two will uh, traverse the link list to find a transaction. And then call the set transaction arguments for the found transaction. However, in the transaction arguments, set transaction arguments function, uh, user client, pipe user client two is a member of transaction two. And the function will call the return method uh, of the user client. But the pipe user client can be released by calling IO service closed for the uh, from user space which will call the user after free. So here is the steps for uh, exploit this bug. Firstly, we create two pipe user client. Then we add a transaction for the first user client. And then we release user client. After that, we end the transaction from the second user client. It will trigger the user after free. Uh, but this bug is fixed because uh, now uh, the pipe user clients don't share a same pipe. Uh, so how to exploit a user after free bug in the kernel? Here is the basic flow. Firstly, we construct rope chains and then trigger the release. After that, we use a fake object with fake Vtable to occupy the, the employee slot. Last but not least, we trigger the user after free by invoking the method of old object. The HIP3 technique we used in this vulnerability is OS uncentralized XML. Uh, you can invoke it by setting pro- properties of a device. Note that the spread data can be read and the head of spread data is controllable. So this is the rope chain for the privilege escalation. Firstly, we use a stack pivot to control the stack and then gets the pointer to the struct proc of current process. Then we get the U credit from proc and set CRUID, CRRUID and CRSVUID to zero. After that, we will use thread exception to exist the kernel mode and return to user mode. Then we can execute the system batch to get a, to get a shell with root privilege. Uh, the stack pivot we used in, uh, this rope chain is, uh, the following gadgets are used in the stack pivot. At the beginning, we use IX to control RZX. Then we use RZX to control ISP, which is the stack pointer. So here is the layout of gadgets in a rope chain. Note that IX is controlled by us. Uh, by using these vulnerabilities, we got a privilege escalation on Mac OS, uh, 10.13, 10.13.2 and 10.13.3. So, uh, here is a demo on 10.13.3. As you can see, we got a root shell in this, in this Mac OS. So, uh, Xiaolong will talk more about, uh, driver's analyzing and fuzzing. Okay. So, uh, here is a demo on, uh, sense batch. And, and next, uh, uh, we are going to show how we found those vulnerabilities. And, uh, Apple drivers are mostly closed-sourced. Uh, in order to find vulnerabilities, we need to do some reward engineering. But it is not that easy. Uh, let's first have a look at, uh, uh, the compiled code of driver banner racing, idea pro. In the, in the, the compiled code of Mac OS driver, uh, you can see that, uh, the function names are kept. And, uh, but there are many, uh, problems, uh, such as wrong parameter inference, uh, lost variable types, and, uh, unknown, uh, virtual function calls. Uh, as for iOS, uh, kernel drivers, uh, the situation is even worse. Uh, we have no idea, uh, of what this decompiled code represents. It's a mess. In fact, uh, in order to find some vulnerabilities, I'll do some reward. Uh, we want the, the compiled code to be just like the source code, uh, just like the figures, uh, suggest. Uh, so we propose a new tool to analyze, uh, drivers in Mac OS and iOS. Uh, this tool is called Ryuk, uh, which is a statistical analysis tool for making, uh, Apple drivers decompiled code, more like source code. Uh, it is implemented as an idea pro pattern script. Uh, the name Ryuk, uh, stands for character in the comic series. Uh, that's not, uh, allows eating Apple. So Ryuk has several features as below. Uh, it can identify name, size, and the retables for classes. Uh, it can recover function names, resolve variable types, extend cross-reference, extend the UI support, and construct all, uh, call graphs. So firstly, Ryuk identifies name and size for classes. Uh, we identify this information from some specific initialization function. Uh, as the figure shows, a sample initialization function looks like this. Uh, you can see that this code indicates some, uh, some information of the class. For example, the, uh, its name and its size. Uh, with these identified class name and size, uh, we can create structures in idea pro to represent these classes. Uh, besides, uh, Ryuk can also identify retables for classes. Uh, you should know that in C++, if a class, uh, has a, any virtual function, uh, it always has a structure called retable to organize its virtual functions, just like the figure suggests. We identify classes retables with a hint. And that is, ahead of a class, uh, retable, there is always a pointer pointing to the class, uh, meta, meta class object. This is a special object. And then recall that in the specific, in a special, uh, initialization function, uh, uh, this function also, uh, also shows where the meta class object is. So, with about hint, we can use the meta class object address to find the class retable. And after that, uh, we can, uh, create structures in idea pro to represent these retables. And send the first member, uh, of class structures to a pointer, uh, to their retables. The next feature of Ryuk is, uh, recovering function names. As we can see, uh, LS drivers are lost off symbols. Uh, functions in LS drivers do not have, do not have meaningful names at all. They are all, uh, meaningless names, uh, prefixed with some. Uh, we recover function names by leveraging several facts. The first fact is that most classes in driver, uh, incurred from classes in the kernel. And these kernel classes have symbols. The second fact is that in C++, when a class, uh, when a child class incurred a parent class and, uh, all rise a virtual function, the parent's function and the child's function, uh, should have the same name and the same offset as shown in this figure. So with the buff facts, we can recover the name, the names of virtual functions that override the functions in, uh, kernel classes. Actually this is not a complete solution, uh, but it can cover plenty of critical, uh, functions. Another critical feature of Ryuk is that it can, uh, resolve types of local, uh, local global, uh, and member variables into the compelled code. Its method is to first identify local variable's types and then perform type propagation, type propagation along control flows. Uh, there are mainly two kinds of local variables, uh, uh, which, which are called parameter variable and stack variable. For parameter variable, we identify their types by leveraging the fact that it's, uh, in the binary, C++ function names are encoded with their, uh, the functions class name and the parameter types. So by encoding these names, we can know the function's parameter types just as the, uh, figures, uh, shows. Uh, for stack variables, we identify their creation and initial register by finding some typical, uh, functions as listed here. So after variable types are identified, uh, we can propagate its type, its type along functions control flow graph. Uh, during type propagation, we figure out what the variables are assigned, are assigned with the variable whose type is defined. Um, and then send the types for them according to the identified types. Just, uh, just like this, this, this, this figure shows. Next, we extend cross reference for member variables and the virtual functions. We examine every sentence in the, the compiled code and, uh, of all functions and check whether any member variable or virtual function is used. And then we add a cross reference in the edit pro from the usage of, uh, from this usage, from this usage to, uh, member variable or virtual functions location in their class or with table structures. And, uh, then now, uh, you can see that the compiled code now looks more like the source code, right? Uh, further, uh, in order to, uh, in order for battery reward engineering experience, we extend U.S. operations, uh, in idea pro. For example, uh, as a demo we will show, uh, Rick allows jumping to a virtual functions implementation by just a double click on a virtual functions call. You can send, uh, you can see that the one, uh, double click, uh, we can direct jump to, to the functions implementation. And we can also jump to the trials in, into implementation and by pressing a, a hot key. Finally, after variable types are identified, virtual function calls are resold. Uh, and now we can generate call graphs for all drivers. And this call graph is very important for, uh, further interprocedure, uh, states, uh, control flow and data flow analysis. And now everything is ready. Uh, we can do manual analysis or other kinds of static analysis as we want. Uh, below we will show, uh, use case of Rook, uh, which is called Rook Fuzz. Uh, the idea of Rook Fuzz is to, uh, guide, uh, driver fuzzing with static analysis results. We implemented it by integrating Rook with the state of art driver fuzzer, uh, passive fuzz framework S10. Uh, Rook Fuzz, uh, takes two set steps. In the first step, it performed data flow analysis to infer drivers required, uh, user input formats. Uh, the second step uses the inferred input format to, uh, guide input, uh, to guide input generation in the fuzzing process and improve, uh, fuzzing efficiency. So in its first step, uh, we performed static data flow analysis in the, the compelled code, uh, to identify whether, uh, user input is checked in conditions and what parts are, uh, are checked and what is the condition. Just like, uh, this figure shows that we can identify that, uh, uh, the off-site 24 and site 1 should be, uh, should not be equal to 6 or 1 in order to, uh, uh, uh, avoid this, uh, this, this field pass. Uh, then we can know driver's requirements on user inputs, uh, for different execution paths and use such knowledge to guide fuzzing. Uh, but, uh, passive fuzz framework S10, uh, only works on macOS 10.11 now. Uh, for later versions, uh, there are, uh, still, still, there are several errors that need to be resolved. Uh, the first error is that, uh, it uses wrong buffer size to read the kernel header. Uh, passive fuzz framework S10, uh, suppose that the size of the kernel header is less than one page. Uh, actually after macOS 10.12, uh, the kernel header is larger than one page. In order to solve this problem, uh, we change the buffer size to two pages. The second problem is that, uh, uh, passive fuzz, uh, framework S10 uses a wrong way to infer the kernel text space. Uh, in its original implementation, it finds the address of interrupt handler, uh, which, uh, which was in the kernel text section and uses this address to find the kernel text space. But for now, uh, in the current macOS, the interrupt handler is no longer, is no longer in the kernel text. Uh, as a result, uh, we cannot find the kernel text space with the handler address. This change is caused by Apple's mitigation on, uh, the famous mail down, uh, vulnerability. Uh, in order to defend against mail down, uh, Apple decides to move the interrupt handler and other, and some other code related to the user space from the kernel text to another special location. Just like the, uh, the figure on the right suggests. So now the, uh, interrupt handler is not in the kernel text space. As a solution, uh, we look for the kernel text space with, uh, with another method. That is, uh, we find the address of some other, uh, kernel functions. For example, uh, the address of lock, mutex lock, uh, and, uh, try words back to find the kernel text space. And this is more stable than, uh, than the, than the previous method. Uh, so, uh, in, in conclusions, uh, in this talk, we have show several vulnerabilities that can be exploited for privilege, privilege escalation on macOS. And we have introduced the, uh, the technique of exploiting user free vulnerabilities, um, in the kernel. And, uh, we also explain the, uh, new static analysis tool called Ryuk, and also shows a, a use case called Ryuk Fuzz. Uh, most importantly, uh, part of Ryuk has been open sourced. Uh, you can, uh, fork, fork Ryuk, or style Ryuk on my guitar. And, uh, also, uh, very, very come to follow us on Twitter and we will, my Twitter account name is BXL1989. And, uh, Spark's Twitter account name is Spark Zheng. Uh, that's all. Uh, thank you for your attention.