 Let's talk one clock is from Xiao Long from Alibaba and Spark. Let's give them a big DEF CON help. Welcome. Come on. Louder. I don't hear you. Louder. Yeah. Alright man. Thank you. Thank you. Uh, hello. Uh, okay. Uh, hello everyone. Uh, I'm Xiao Long Bai from Alibaba. Uh, this is Min Spark Zheng and uh, he's my colleague. And uh, today we are going to talk about iOS security. Uh, the title of our talk is uh, hack pack. Hacking point authentication in iOS user space. Uh, before starting our talk, I'd like to have a self-introduction. And, uh, I'm from Alibaba and uh, before joining Alibaba, I have got my uh, PhD degree in uh, Tsinghua University. And uh, I have published several papers on uh, Black Hat USA, Black Hat Europe and uh, The Big Four. Uh, my Twitter account name is BXL1989. Uh, so welcome to uh, follow me on Twitter. Uh, my colleague Spark Zheng is uh, is a PhD from uh, COHK and he's now a senior secretary expert in Alibaba. Uh, his Twitter account name is Spark Zheng. Uh, this talk will be separated into several parts. Uh, firstly I will have a brief introduction uh, of what the, the point authentication is. Uh, and then I will show how point authentication is a protecting iOS. Uh, and then uh, comes to the uh, main part of this talk. That is we found the design flaw in the user space point authentication. And with this uh, design flaw, I will show you how to do uh, exploitation in the uh, user space of iOS in this PSE era. Uh, and, and at last I will show you uh, uh, a tool we designed to uh, do uh, use basic specifications uh, which is called the PSE gadget. So, what is point authentication? Uh, point, point authentication is uh, uh, extended feature of ARM. Uh, it is available in uh, A12 uh, which is the call of iPhone XR, XS and XS Max. Uh, it protects pointers with cryptographic signatures. Uh, how does it work? Uh, it works by introduction of two uh, instruction sets which are called uh, PSE instruction uh, PSE instructions and AUT instructions. Um, PSE instructions calculate uh, PSE instructions calculate a keyed hash of the pointer uh, which is named the PSE and uh, inserts the PSE into the pointer. And the AUT instructions extract the PSE from the sender pointer and authenticate whether the PSE is consistent with the original pointer. Uh, you can see from the figure that when uh, PSE instruction is uh, executed on uh, pointer value, the PSE value will be uh, inserted into the pointer uh, like the red one. Uh, in PSE and AUT instructions there are two main factors. Uh, they are called keys and contacts. Uh, the PSE instructions work as, work as follows. Uh, it, it will use a key register and a contact register to sign uh, to calculate uh, PSE value from the register XD. And then it will uh, insert the PSE value into the register XD uh, which then forms uh, a signed pointer. And for AUT instructions uh, these instructions uh, extract the PSE value from the uh, XD register. And then it also use the key register and the contact register to verify whether the PSE, PSE value is consistent with the original uh, pointer value. If the verification succeeds uh, it will use the uh, verified pointer value to do jump or load. Uh, if the verification uh, fails uh, it will insert uh, error code into the uh, uh, into the, into the, into the pointer uh, so the pointer cannot be used for further use. Uh, there are five key registers in uh, in, in, in the CPU. They are called AI key, BI key, AD key, BD key and the G key. Uh, here the I keys means uh, is used for instruction pointers uh, sign and the verification. And the D keys are used for data pointers. Uh, these key registers are only readable and readable on exception levels larger than uh, ER1. Um, uh, different from the key registers, contact registers are only uh, general registers. Uh, they are used to prevent intro process pointer uh, substitution attacks. Uh, that is uh, when we send the same pointer value with the same key but different context value, we will result in different PSE values. Uh, as a result uh, for example uh, pointer uh, sign with context A uh, with the field verification with context B uh, even in the same process. Uh, but you should, you should remember that there are some instructions just using uh, now pointer uh, now, now, now context uh, I mean the, the context is all zero. Um, these are the list of uh, uh, supported PSE and the AOT instructions in the ARM. Um, so we know uh, what the pointer uh, we have a brief understanding of the pointer authentication. So how pointer authentication is protecting iOS? Uh, let's answer this question. Uh, pointer authentication uh, reduced the threat of memory corruption by preventing code reuse attacks. Uh, what is memory corruption vulnerabilities? Uh, it is one of the most frequently exploited vulnerabilities in iOS users based services under the kernel. Uh, typical memory corruption vulnerabilities include uh, user free and buffer flow. And when uh, we have uh, memory corruption vulnerabilities, we always use the code reuse attacks to uh, exploit these vulnerabilities. Uh, code reuse uh, attacks uh, always utilize the gadgets that already presented in the program or in uh, shared libraries uh, to do malicious things. Uh, typical code reuse attacks include uh, return oriented program which is also called ROP and uh, jump oriented program which is called uh, JOP. Uh, the difference between uh, ROP and JOP is that ROP, in ROP gadgets always analyze uh, write instructions. And uh, for JOP gadgets uh, uh, often uh, run it with uh, BRR and BR, they are jump instructions. Uh, sample buffer, buffer flow is like, like this. Uh, from this code uh, we can see that in the overflow function uh, there is a mem copy uh, function called. Um, but the mem copy function uh, that's not uh, before the mem copy function called uh, this function does not check uh, whether the uh, buffer size is uh, lower than, is lower than uh, 0, 0x uh, 4000. Uh, when we encounter this vulnerability, how do we exploit them? Uh, uh, we, we exploit it, it like follows. Uh, we can write more buffer, uh, more data into the buffer array. And uh, uh, the, uh, the more we, the, the data we, we write will overwrite the uh, the area in victim array. Uh, that is we, we may uh, overwrite the uh, uh, function pointer in the victim array uh, which is called a dummy. And uh, then uh, by uh, by giving dummy uh, uh, arbitrary uh, address, we can force the uh, victim process to jump to uh, other uh, locations. And uh, from those locations we can use R-P chain, R-P gadgets, or J-O-P gadgets to do malicious things. And uh, here the pointer authentication uh, is going to prevent uh, R-P and J-O-P uh, but how? Uh, it prevents R-P and J-O-P by replacing dangerous instructions in the uh, in the gadgets we, we see. Um, for R-P uh, uh, R-P, the for R-P uh, pointer authentication replaces the write addresses with uh, write instructions with uh, write A-B instruction. Uh, write A-B instruction ensures that the return address is uh, was correctly signed. So the signed return address is will be protected by the key under the context. And for J-O-P uh, BRR and BRR is now replaced by uh, BRRA and BRRA. Uh, these instructions ensure that the function pointers uh, we are going to use to jump was correctly signed. Uh, so the, now the signed pointer, function pointers is uh, protected by the key under the context. Uh, so now the instruction uh, by replacing uh, this uh, write and BRR, BRR uh, instructions uh, we can prevent R-P and J-O-P. Uh, even if the P-A-C, uh, even if we in um, uh, victim processes the uh, PCH hijacked, there is no way to launch further attacks. Uh, because the attacker cannot fake the uh, signed pointers that can be correctly verified. Uh, Apple has uh, iOS has already uh, deployed the P- um, pointer authentication protection in user space demons and in the kernel. Uh, so with the pointer authentication uh, since both the key under the context are unknown to the attacker, it can successfully uh, prevents R-P and J-O-P attacks. Sorry. Uh, so for now, uh, when we talk about iOS attacks and J-O-P-Rigs uh, we, we, we know that the iOS attacks and J-O-P-Rigs has come into the uh, P-A-C error. Uh, in previous J-O-P-Rigs R-O-P and J-O-P was the first step to exploit uh, user space demons and the kernel. But now, uh, R-P and J-O-P attacks are prevented by um, pointer allocations. Uh, instruction pointers are now sent everywhere. Uh, so uh, what can we do now? Uh, this talk will only focus on uh, pointer authentication in the, in the user space. Uh, in the uh, this means uh, when we talk about user space attack scenario, we mean that the attacker is a local application on the same device with the, with the target system service demons. Uh, for uh, security analysis on kernel pointer authentication, please refer to uh, Brandon's blog. Uh, so we, we know that the pointer authentication should be very strong. But uh, for now, we have found some weak points in the pointer authentication in user space. Uh, the foundation of successful pointer authentication protection uh, should be that the attacker cannot fake send pointers uh, that can be correctly verified by the target process. Uh, this is based on two uh, two uh, basic knowledge is that uh, which uh, we know that the sign key is unique for different uh, processes. And the context is also very private in different process. So uh, without knowing the sign key and the context, the attacker cannot create uh, uh, correctly signed pointers. But if the sign key and the context are identical in two different processes, uh, inter-process uh, pointer substitution attack uh, would be possible and uh, pointer authentication protection will fail. So here comes the question, is iOS correctly protecting sign key and the context? Uh, what if it, it fails to successfully protect us? So let's do some experiments. Uh, with, our experiments is set up as follows. Uh, we developed two programs called program A and program B. Uh, they are developed by different developer accounts. Uh, and uh, we sent a pointer in pro-pro-progress A and a verify it in progress B. With all the file key, uh, phone keys. With all the keys and the, and the two contacts, uh, the two contacts are zero contacts or uh, zero x one, two, three, four. So uh, what is this experiment for? We want to track whether the pointers signed in program A can be correctly verified in program B. If it can be correctly verified, uh, it should uh, indicate that the program A and the program B are using the same key. So if, if this is true, uh, there is a problem. Uh, let's see. So the experiment results, results show that uh, uh, the pointer is signed by A I key and the A D key uh, uh, in, in program A can be correctly verified in program B. So that's very uh, surprising. Uh, it seems that iOS is using the same keys in different user space processes. But it is more important to know whether the, the result is, is also true, uh, for user space system demons. Uh, we did the experiments on our own developed programs, but we should know whether it is true for uh, system demons. Uh, we can answer this question by checking, uh, whether a signed pointer in a service can be correct, uh, can be correctly verified in our own program. Uh, so how to retrieve a signed pointer from a user space demon of system service? Uh, here we use a denial of service vulnerability, uh, on a system service to retrieve a signed pointer. Uh, the, the, the basics here is that when a process, uh, encounters, uh, uh, denial of service vulnerability, it, it would crash. And when it crashes, uh, its register values are included in the crash log, uh, which may contain some signed pointers. We, we choose those signed pointers from the crash log. Uh, we found the null pointer dereference, uh, vulnerability in the service, uh, in the service log d, and, uh, which is in iOS, uh, 12.1. This null pointer dereference vulnerability will cause the log d service to crash. Uh, and, uh, we know log d service is unsold in the box and running as a root. Uh, so where is this vulnerability? Uh, log d provides a IPC service which is called com.apple.logd. Uh, the IPC service is implemented in the, uh, in, in the source called fairhose, uh, underscore, uh, server, dot c. And uh, in the, in the, in the source code we can find that, uh, fairhose, server, handle, mech event is the IPC handler. And, uh, from this handler, uh, it calls fairhose, server, demilx. And demilx dispatch the IPC request to different methods including fairhose, server register, fairhose, server push a sink and a fairhose, server push and wait. And during this process it creates, uh, uh, global variable called the current client info. Um, but it, it passes this, uh, global variable to different methods, uh, without checking whether the, uh, global variable is null. So, in, in those dispatch the methods, it just trust the, uh, uh, the current client info variable, uh, without checking whether it is null. Uh, when it uses it, it will call the null point dereference, uh, and it crashes the log d demilx. Uh, by triggering this vulnerabilities we can get a crash log like followed. In a crash log we can, we can see that the X16 register seems like a signup holder. And, uh, uh, by reverse engineering log d we can find that an instruction has just been executed before the crash. Uh, the instruction is like this, B-R-A-A, B-R-A-A X, uh, 16, uh, X17. This instruction, uh, verifies X16 with AI key as the key and the X16 as the context. Uh, from the crash log we know that, we know the value of X16 and X17. And, uh, we get these, uh, register values and use these, these register values to, uh, verify them in our own process. We try to verify X16 by AOTIA instruction in our own process. Uh, uh, in this way we are using the, uh, our own AI key as the, as the key and the, uh, the previous X17 value as the context to verify X16. And the result shows that the verification of the X16 is successful. So, uh, this, this experiment is, has the same result as the previous experiment. That means LS is really using the same AI key in our own process as the, under the system services. Uh, this is a flaw. Uh, but it, it should not be exploitable, uh, as I have said, that the context, uh, register is introduced to, uh, prevent a pointer substitution attacks. And the attacker should not know the context in another process, for example, the X17. Uh, but did you forget that, uh, I mentioned that there are some instructions that just use the zero context or not context. Uh, these instructions include the BRRAAZ and the BRRAAZ. Uh, when you use, uh, now context or zero context, uh, now context is not, uh, is, is not doing anything to help you to protect the signup pointers. So what does it mean, that means to an attacker. Uh, that means that a local attacker can create a signup pointers in his own process. And when the pointers are used in another system service process, uh, they will pass the verification of BRRAAZ and BRRAAZ in the system service. So, uh, the JLP is alive now. Uh, that means we can use, uh, we can, we, we can still use the, uh, gadgets that are under the, with the BRRAA, BRRAA, BRRAAZ or BRRAAZ to, uh, to find the JLP gadgets and the chain, uh, JLP gadgets to do malicious things. Uh, but how about ROP? Uh, we know that ROP, uh, gadgets are now ended with, should now be ended with our, uh, write AB. Uh, but in this, uh, in these instructions, uh, return addresses are now signed, uh, by, uh, by the B key and the, and the, which, which, uh, but the B key is unique in different processes. Uh, under, we also know that the, uh, our, uh, write AB, uh, the context of write AB is SP and also, uh, private in different processes. So, ROP, uh, has no chance. Uh, so we know that there is, uh, uh, key many, key management problem in ISU this space, uh, which is, uh, this, uh, we know A key is a pro device key. Uh, it is renewed at each device reboot and all processes are using the same A key. And the B key is a pro process key. It is renewed when a process restarts and different processes are using the different B keys. Uh, what is the root cause of this key management problem? Uh, the root cause is, is a trade off between, uh, the performance and the security. Uh, let's consider the situation that the function pointers, there are function pointers in shared libraries. Uh, you know, we, we know that the shared li, memory regions of shared libraries are copy and write. Uh, so if the pointers are signed by different keys in different processes, it will cost more time and more memory space to create a new, new process. Uh, in order to copy the shared libraries. Uh, like this figure shows, uh, if we sign the pointers with the same key in different processes, uh, when we foc or create a new process, the shared li, the shared, shared libraries, uh, do not need to, uh, be, uh, copy, uh, add to the foc. But if we sign pointers with different key in different processes, uh, we have to, uh, create a new copy of the shared libraries when we foc a process. So, uh, the actual copy will cost them more time and more memory space. That's a, uh, a lot of performance loss. So, Apple, uh, has no choice but to use the same key between different processes. This, this is a design issue, uh, which is inevitable. Um, with this issue, uh, um, let me, uh, let's have a look at how to do, uh, explorations in the, uh, user space right now. Uh, here I will use a real, uh, iOS user space vulnerability to show how to do, uh, explorations in iOS user space, uh, demons. Uh, this is, uh, uh, vulnerabilities in the, uh, demon called the Meteor Library D. Uh, Meteor Library D provides, uh, an SSPC service, which allows sandbox applications to execute, uh, SQL command on a SQLite database. Uh, the XPC, uh, function is called execute, uh, query, uh, in the left figure. Uh, in the right, uh, you, you can write, uh, okay, you, you, you, you can write the code like, like, like, write to, uh, execute some, uh, SQL commands on, uh, on a SQL database. Uh, SQLite has a very interesting feature, uh, which is that the users can create a customized token, uh, token, tokenizer implementation and specify the tokenizer to be used, uh, when indexing, uh, text. So how to create a customized tokenizer implementation? Uh, we can provide, uh, address in the SQL command and the SQLite will retrieve a function pointer from the address. And the function pointer, uh, is exactly the tokenizer implementation. Um, uh, you can see from the, uh, figure that we, uh, created a tokenizer called a my tokenizer, uh, which, uh, which is in the address, 4-1, 4-1, 4-1, 4-1. And we use the my tokenizer to create a table. And, uh, when this secure, uh, in, uh, commands are executed, um, the SQLite will, uh, try to, uh, find a function pointer, which is indicated in the 4-1, 4-1, 4-1, uh, address, uh, and use that function pointers to, uh, call function. So, so when those, uh, securing commands are executed, the media library will try to, uh, invoke, uh, customized tokenizer, uh, from a function pointer, uh, like follows. Uh, this is the, uh, the, the disassembled, uh, instructions. It will try to load, uh, a function pointer from, uh, X24, uh, plus 8. And, uh, the X, uh, the, the function pointer should be, uh, signed a function pointer, and it's stored in X8. And the media library will call the signed a function pointer, uh, by B-R-R-A-A-Z, uh, which is stored in the X8. So, uh, here, the texture can control the X, uh, 24. As a result, the texture can control X8 and further hijack, hijack the PC in media library D. Uh, how to further exploit this vulnerability? Uh, we, we know that, uh, now, uh, X8 is under our control. Uh, then we can use heap 3, uh, techniques to, uh, to, to punt the X8 to, uh, uh, to, to punt to the X8 to, uh, uh, arbitrary address. Uh, how to, uh, sorry. Here we know that X8 is a signed a pointer. And, uh, we created the signed a pointer in our all process, and put the signed a pointer in the heap 3 payload. And then, when we hijack the PC through the X8, the X8 will, will go through the, uh, signed a pointer we, uh, set in the heap 3 payload. And then from the signed pointers, we can do JLP. Uh, we, we can use managed JLP gadgets to do malicious things. Uh, as a, as an example, I will show you, uh, how to print a message in the media library D's, uh, service. Uh, we use a JLP gadget to call NS log. Uh, uh, the first thing we need to do is to find a JLP gadget to, uh, to call the NS log. Uh, we found a, uh, a, a gadget in the SQLite, uh, doll, uh, develop. Uh, this gadget, uh, sites, uh, uh, sets X, X0. And, uh, also, uh, retrieval function pointer, uh, from the X24. Uh, so, we can now control X24, X8, X0. And, uh, we can call, uh, then we can call S log from the X8. And we set the X0, uh, to be a string structure. Uh, so now we can print a log, uh, in the media library D. Uh, that is a more specific, uh, detailed, uh, uh, graph of, uh, what, what I have talked. Uh, we, uh, first control the, uh, X8 to point to, uh, the purple one. And, uh, the purple one will lead to, uh, the, uh, write gadget. And, uh, the gadget will, uh, further retrieve the function pointer, uh, in the green one. And, uh, also X, X0, uh, from the orange one. And then, the green one will lead us to the S log. So, we can successfully make, make, uh, uh, uh, the green one will lead us to the JLP exploit in the media library D. And, uh, from the, uh, log, we can see that the media library, the, uh, media library D is, is now controlled by us and print, uh, a message like this, hello, you're exploited. Next, I will show that, uh, in order to do, uh, JLP, uh, attacks in the PS era, uh, we have developed a, uh, new tool, which is called the PSGadget. Um, why we, uh, uh, want to build this tool? Uh, they build this tool because that manually looking for JLP gadgets is very tedious. Uh, so, so this tool, uh, so this tool will be used to, will be used to automatically find the, uh, JLP gadgets in, uh, banners protected by Ponto authentication. And, uh, we develop a PSGadget as the idea pro plugin. Uh, the basic workflow of PSGadget is, is like follows. Uh, we first find the BRRA, BRRA, BRRA is the, the BRRA is the instructions in the, in the banners. And uh, then we get a, uh, record a new instruction in the backwards order. And we check whether the instruction will affect the control. Uh, if it is true, uh, we go to the final. Uh, uh, if, if it's not true, we go to the, uh, second. And, uh, we, we, we get a new instruction in the backwards order. Uh, so in this way, we can get a, a few code sequence, uh, which, uh, which is under the, with those, uh, BRRA instructions. And, uh, this instruction, uh, this, this code sequence can be used, uh, in our JLP gadget. And also, PSGadget, PSGadget will further examine, uh, each instruction in the gadget, uh, in, in the code sequence we have found. Uh, it will check, uh, whether the branch target, uh, where the branch target is from, and what each registers, uh, can be influenced, uh, in this, this code sequence. Uh, it will also generate, uh, a short description of what the registers have been, uh, you, you, you can control, uh, in this code sequence. Uh, there is a special kind of, uh, JLP gadget, which is called dispatcher gadget. Uh, dispatcher gadget, uh, repeatedly, uh, invoke other gadgets or call functions in a well loop. Uh, the feature of dispatch gadget is that the loop body will load, uh, function pointer from the address, which is indicated by, uh, uh, base register plus offset, uh, uh, this offset is updated, uh, by a loop counter. Uh, with the high-powerful PSGadget, we automatically, uh, find such a, uh, dispatcher gadget, uh, in libc plus bus. Uh, you, uh, you can see from this, this figure that, uh, in this gadget, uh, the gadget will, uh, retrieve the, uh, function pointer from, uh, X19, and, uh, the, uh, the function pointer will be further used to call other gadgets. And, uh, we, we can loop us through the, through the gadget. So now with the, uh, dispatcher gadget, we can, uh, do arbitrary code execution in user space system demons. Uh, so next, I will conclude this talk. Uh, in this talk, uh, we can have a basic understanding of what, uh, pointer authentication is and how pointer authentication works, uh, and how it is protecting iOS user space demons. Uh, more importantly, I have shown that there is a design flaw in iOS user space pointer authentication. That is iOS using the same key in different user space processes. And, uh, I show that, uh, attacker can leverage this flaw to launch JLP, uh, attacks in user space demons. And, uh, I use a, uh, a real exploit to then demonstrate the JLP attacks in pointer authentication protected, uh, processes. And finally, I have shown a tool to automatically find the JLP gadgets in, uh, pointer authentication protected banners. And here are some, uh, references. Um, Brandon, as I, uh, uh, Brandon has already, uh, uh, do some exp, uh, research on the, um, pointer authentication issues in the kernel. And even beer has also, uh, do some experiments, uh, of pointer authentication in the user space. Uh, okay. And, uh, um, Protiz and Xrub has developed several tools to help you understand in what the pointer authentication is and how, how you can inspect, um, pointer authentication instructions in banners. So, that's all, thank you. Uh, if you are interested in my talk, uh, we can have a further discussion and please follow me on Twitter. Thank you very much.