Um, so, hey everyone. Um, that's my first DEF CON actually. So, smile. Okay, um, so, today I'm going to present to you a research that we have, uh, done last year on Qualcomm driver's code for Android. So, uh, our agenda for today, first we'll briefly speak about chipsets, uh, their location in the Android ecosystem, how they affect the overall security of, and how they affect the overall security of Android. Then we'll focus on Qualcomm as a chipset and review its various, uh, subsystems. After all, we will reveal four new OD vulnerabilities that we have recently discovered, including a fully working exploit for one of them. Finally, we will discuss some ideas for improving the overall security of Android. So, just a little bit about myself. Um, my name is Adam Donenfeld. I've been a security researcher for years, uh, both in the mobile and in the PC field. I've mainly done, uh, vulnerability assessment and exploitation. Uh, right now I work at Checkpoint as the lead security researcher for Android, and in my free time, I also study German. Uh, additionally, I would like to thank, uh, Avi Bashan, Daniel Brody, and, uh, Pavel Berengold for supporting me during the research. Okay, so, um, I'm most people think that go- only Google is involved in the development of Android, but that's not the case. Many other third-party vendors still take a large part in the final product we buy. Um, the heart of every Android is obviously, um, Deluxe Kernel. Afterwards, we have, uh, the AOSP, uh, Android Open Source Project, which is developed exclusively by Google. And then things, uh, start to get a little bit more complicated, because then we have the chipset. So, what is the chipset? Well, the chipset is, uh, uh, uh, uh, uh, uh, uh, uh, uh, uh, uh, uh, uh, uh, uh, the chip that is actually the chipset. So when you buy an LGA, uh, HTC, Nexus, or Samsung device, even though these companies do manufacture some of the hardware, the majority of the hardware is actually manufactured by the chipset vendor. Now, not only the hardware is manufactured by the chipset vendor, uh, but the driver for this hardware is also a role vendor. And then, this entire package is forwarded, uh, to the OEMs, and is modified by each OEM. and receives various customizations. And then finally we we get our device. Now as you can see uh chipset is very essential in this process. And if you find a vulnerability in the chipset in the chipset code it means that it has to go through the entire uh all the OEMs. So does not it does not only mean a long wait and fix but also a very large victim pull to attack. So if you find a vulnerability in Qualcomm we're opposing this to all Nexus, HTC, LG and many Samsung devices. So um Qualcomm has a very large impact on the overall system. In fact there are a lot of different subsystem systems which are completely written by Qualcomm. Each one of these subsystems is a great place to start look for uh vulnerabilities. And if the component is low level enough in the system uh one vulnerability would probably be enough to completely compromise the system. And that's without mentioning uh components that have been modified by Qualcomm to to satisfy its requirements. And we'll see an example soon. Um so second. So today I will be disclosing four new audio vulnerabilities. Each one of them accessible for any unprivileged application on the device. The first one is a devil. Uh the second one is koala root. Uh which we already exploited. The third vulnerability is called syncoca root. And the last one is kangaroo root. So let's start with with uh shmanyan devil. So a shmanyan devil is a vulnerability in the ashmem mechanism. Uh ashmem or android shared memory is a unique shared memory uh allocator for android. It reminds a little bit the Linux S-A-Gem mechanism. Uh it's uh it's uh it's uh it's uh it's a little bit different from the ashmem. But with a slightly different behavior. And it supports a very simple uh file based API. Now Qualcomm expanded the functionality of ashmem. The API of ashmem. So it can easily obtain um an information about the file. An ashmem file from an FD. So for example we use it if you want to map ashmem uh memory to the GPU. So Qualcomm added this function. So basically uh sort of uh what the function does is uh it's uh it's uh it's a function that it gets a file descriptor and a few output pointers. It extracts from the file descriptor uh the internal kernel structure of the file. It checks that this file is actually an Ashman file and if it is it extracts data uh from the file. If it's not the ref count is dropped back and the function uh is finished. So it's kind of straight forward and in fact we couldn't find a vulnerability there. But a question that most of us ma- must uh must ask ourselves is how does Qualcomm actually verify that our file descriptor is an Ashman file descriptor? So the way to do that to do that in Linux is first to extract from the file descriptor the internal uh structure of the file which we can see here. Just a second. Uh which you can see here. And then each file in the in the system uh I mean for let's take for example a socket file. Each socket in the system has a file. So there are a lot of file types in the system. So in order to determine their type each socket each file has its um operate a specific operation handler. For example let's say that we perform a write operation on a socket file. The behavior in comparison to a regular file is obviously different. So we simply have to check. What is the operation uh we have to check the the handler of the specific operation and then we know the type of the file. So uh Qualcomm decided decided to reinvent the wheel and the way that they checked for a type file um was by the name of the file. Yeah. If the file is called Ashman it must be an Ashman file right? So so so what we got here. Uh if we have a file called Ashman on the root of any mounting point we can fake the internal Ashman uh data. But unfortunately slash is read only and any mounting point on the system uh that uh is inaccessible for unprivileged applications. And we say that we want to exploit it without any prior permissions. So what we did to overcome that was using uh a feature called OBB. So OBB or OPCS. So OPCS is an OPCS. So it's an OPCS that you binary blobs is a deprecated feature that fortunately still works. So as you might know Google Play doesn't allow apps with file size that is greater than 100 megabytes. Now obviously there are some apps especially games that have lots of sound stu- structure uh textures uh pictures whatever and they cross the 100 megabyte limitation. Um so what I usually do is first downloading just the call functionality and then they download the code. And then they download the code and then they run it externally and the rest of the textures. So what OBB is is basically a file system that uh any app can download and mount. And so let's say that we let's take Angry Birds for example of a game. Once we the first time we launch Angry Birds it downloads externally all the all the pictures and sounds. And then it just it downloads an OBB file and it mounts it. So any developer can create an OBB file and put there any file he wants. Externally it's already downloaded and then just mount it on the device. So in order to fake an Ashman file what you can do is first just create an OBB file and put there a file called Ashman in the root uh directory. Then we can just mount the OBB and then we can send our file script to the Ashman file from the OBB to the system. And therefore we can fake um the Ashman uh in terms of data. Thank you. Okay so um now going to the second vulnerability uh Koala Root. So Koala Root is a vulnerability in the IPC mechanism of Qualcomm. It's basically a new address uh family in the system uh AFMSM IPC. It says uh but it says some unique features. For example uh I can whitelist or backlist a black list um other sockets in the system and filter them by uh the group ID or other um uh properties. And therefore I can prevent unprivileged processes from communicating with me. And now another cool feature in this IPC, anyone can monitor the entire system. So for example I can get a notification for any creation or destruction of a socket with this uh address family. And the best thing about it, no permission. So I can get permission to do that. So um this this uh address family has four different uh sub-types. Uh we're going to focus only on client port and control port. Mainly because IRSC port and server port require um high privileges. So every time you create a socket, the socket is a client port socket. A client port socket can communicate with other endpoints and send and receive uh data. Now control port, it's not a control port. It is an a socket that cannot communicate with other endpoints. It will only receive messages about the creation or destructions or destruction of sockets in this address family. So how do we create a control port? Um we simply issue an octal on the client port. So the function that um handles the octal is this one. Basically uh um it locks the our current endpoint. So we can um um um um um um um um um um um um um um um we can't issue two octal simultaneously on the same socket. And then according to our command, it uh performs operations. So if we issue IPC router octal bind control port, it will be converted from a client port to a control port. So that's the function that converts uh our socket. So each type has a list and the conversion is simply uh taking out a a client port from its list and putting it back into um and putting it into the control port list. So that's the conversion function and there is a vulnerability here. So let's examine this function uh step by step and find a vulnerable code. So can you see the code here? Is it visible? Okay. So the first uh instruction is um taking a lock on the client list. That's because you modified the list. And then we take the object out of it from his list. Then we unlock the client list. We lock the control list. We add our object to the to the control list and then we unlock the control list. So let's examine it. Locking the control- the client list. Taking the object out from his list. Unlocking the client list. Locking the control list. Adding our object there. And then unlocking the control list. Um pretty straightforward and in this flow nothing was um problematic. But what happens if we try con- to convert an object that we have already converted before? So we lock the client list. We take the object out from his list which is not the client list. We unlock the client list. We lock the control list. We put the object back and we are unlocking the control list. So for those of you who missed uh we even though we take a lock on the client list we are modifying without uh locking uh we modify uh the control list. So um we got something here. The control ports list is modified without a lock and therefore there is a race condition. We can delete two objects simultaneously from the control ports list. Okay. So now um second sorry. Let's see what happens when we delete two objects simultaneously from the list. Um uh we're we're working in the context of A. Uh that's the Linux kernel code that removes objects from uh double linked list. And if you can see it. If you can see it. So we have the pseudo code here. So basically uh we are taking now A is next which is B. And we set B's pref to be A's pref. So B's pref equals control ports. And now since the list is not locked there might be a context switch. So and now we're working on the context uh of B. So we take B's next which is C. And we set C's pref to be B's pref. So C's pref equals control ports. And now we have to take care of um B's pref which is control uh which is um uh control ports. The second. Yeah. Now take care here. Sorry. So we set control ports next to be B's next. So control ports next equals C. And finally B is B now points to poison. And remove is removed from the list. And it's not just removed from the list but it is also freed. So now this memory is reclaimable by kernel heap spraying or any other method you choose. And now uh going back to A. Uh we take care of A's pref. So control ports next equals B. And just like B. A is removed from the list. It will now point to poison. And uh that's it. So if we uh remove all the unused object in this list. You get this. So the list now points to a free reclaimable by kernel heap spraying data. So uh we just use a unix dgrams to spray that. Now since this is the list of the control ports. Uh we can now uh uh uh uh uh uh uh uh control ports. Now once we fake an object there. We want the list to be used. So we just create or destroy any endpoint in this address family. Because and each time we do that all the object on this list must be more uh notified about that. So the notifying function is post packet to port. So each object in the control ports list is transferred to the post packet to port uh function. So that's the function. Uh we're not going to go over uh through uh over uh all over the here. We'll go it. But as you can see here we have a lot of new primitives from information disclosure to function calls and memory corruption and many other um primitives. I think that there is at least one more way to exploit the vulnerability but the path that we chose was using wake up. So what is wake up? Wake up is actually a macro to another function called uh wake up common. And as you can see here since we control um the first parameter of wake up we also control queue. Now task list is derived from queue so therefore we control we control curve. So we have a new primitive here. We can we can call any kernel function um on the uh we can call any kernel function while we control uh a large portion of the first parameter. Now if we wouldn't have SMAP it would be uh game over but uh we wanna overcome SMAP. So a new primitive uh kernel function call with the first with the first parameter control uh controllable. However uh it's not good enough for commit creds. Commit creds for those of you who don't know is a kernel function that allows you to change your current credentials. Now since we control most but not all of the first parameter we can't call the first parameter. We can't control commit creds because we want full capabilities. That's because the kernel address is a part of the first parameter. So if you want to control the accurate kernel address we cannot control one one hundred percent of the first parameter. So we had to upgrade our primitive. We have to find a function that controlling just a little bit of its first parameter will allow us to call another function uh which fo- one hundred percent control over um its parameters. So this is a function that we can control. So we look for such a function and we got USB reads done walk FN. Um as you can see here we control walk so we control S8 uh CH controlling CH allows us to control REC and therefore we can call any function while we have one hundred percent control of the first parameter and so buff is an address so we can just put any pointer here. And if we call this come on. So each time you want to call a kernel functionality we have to go to over uh our of this chain so first we call uh wake up common which you can say here then we call using this function you call USB reads down walk FN and finally we can call any kernel function uh while controlling uh the first parameter and now we have enough uh primitives to completely compromise the system get ourselves roots it helped us in Linux and clean up our mess. So uh let's start again능 exploitation flow. We have a list uh a double linked list and each time we create or destroy an endpoint on the list the list is iterated and where we can uh it will be used. So the first thing that we want to do is get the use after free situation that we saw before using the vulnerability and therefore put a fake object there. So firstly um so there is a free object in the list. Now uh since this memory is reclaimable we can just can uh use heapspring to uh reclaim this data. We used unique sigrams but again you can choose your uh convenient uh convenient uh spring method. And now we control this object. Sorry. Control this object and the next thing we want to do is get the system to use this object. So trigger trigger an iteration on the list. So we just close or create a any socket on this endpoint. And the list uh our object is being used. And then we go to the function chain call. We go to wake up common which uses our fake task list. And then we can call uh kernel functions uh conveniently. So the first function function that we call is qdisk listdel. Um it cleans up the list so our fake object will no longer be there. In fact the list will be just empty. So for for the use of the list nothing will crash. Then we call enforcing setup which uh effectively sets SCD look so be permissive. And finally we call commit creds which sets our UID to zero and gives us the full available capabilities of on available to the system. And we want. Yeah. And now um time for a demo. So uh on the left we have a console I hope you can see it but if you left believe me. Uh first we install uh our demo app um now and we are going to see that this device is uh a marshmallow device with a relatively new Linux kernel version. Now uh initially we're going to see that SELinux is fully enforced uh and that uh SuperSuite is not installed on the device so it's not rooted it actually comes like from the store like that. And uh we're going to see that we are not root so it's we are we are running on the user two zero zero zero so shell. Um okay now our payload uh our payload uh put a solid file in the system partition and it creates a service uh a local a local uh uh uh uh uh uh uh uh uh uh uh uh uh uh uh uh uh uh netcat server listening on port one three three seven which simply uh which just forwards commands to um bash s root. So now we're going to see that system is not modified and that this local server uh does not exist. So now we're going to see that it's not working. Okay and now we're going to launch our exploit uh so we're gonna see some crap on net uh locat uh be patient. That's it we're root. So now we just uh clean some stuff uh the entire and uh it takes approximately two seconds to exploit this um vulnerability and then you get you can run your own payload uh s root without nothing inter uh that uh stands on your way. So now we are going to see that um we're still not root you don't have like a sue and we are not root yet. But s linux is now no longer enforcing it's permissive. And if we try to netcat to our local server instead of getting connection refused we are in. So now we see that system has a new file called so gang that's access in German. I'm studying German. And we're going to see now fstab which is only accessible to uh root. So and finally id shows that we run as the kernel and boy my returns root. Um thank you. Uh so that was quite interesting. So now we're going to uh the last two vulnerabilities. Sinkoka root and uh GA Kanga root. But before we talk about them uh we have to uh talk a little bit about a mod um a mechanism called IDR. So IDR is a linux kernel mechanism so it's not just for Android. And it allows mapping between numbers like just ID's to kernel pointers. When do you use that? Uh let's say that we want to let the user uh run a reference kernel object so we don't want to reveal the kernel address of this object so we just give them uh an uh a safe ID. So how does it look? Uh the user wants to create an object so it sends the kernel a create object request. Now the kernel allocates data and initializes a new object. Now the kernel doesn't want to give back this address to the user. So instead of instead of doing this it just uh passes this address to the IDR mechanism which now maps between this address and the number one. And now the number one is returned to the user and each time the user wants to update the object uh destroy the object do whatever it wants with the object it will send a kernel uh just hey I want to update this object object ID ID one and the kernel uh will use the IDR mechanism to get the address from this one. And now uh Sinkoka root. So Sinkoka root is a vulnerability in an object called Sink Source uh in an object called Sink Source. Uh it's in the synchronization mechanism between the GPU and the currently running application. We don't have to know a lot about this object to understand and see the vulnerability. We just have to see how to create and destroy this object. And as you've seen before the IDR mechanism this object is referenced with the IDR mechanism. So that's the function that destroys that freezes the kernel. So uh this is the function that uh is the object. Um uh the user controls data. I mean it's it is sanitized so actually it just controls uh ID here. And KGSL Sink Source gets obtains from this ID this IDR ID a kernel object uh called Sink Source. Now how does it work here? It's a ref count based object. So first the ref count is one. Once we did that what we once we called this function the ref count is increased to. Two. Then it is dropped once for the creation of the object because it's the destroying function. And it it is called once again because we increased the ref count here. So at this point the object is freed. But something is missing here. Is there any pending free check um on the object? What happens if we call this uh this function on two different threads simultaneously? So let's examine this. So let's look at the object. Examine it. We have thread uh thread A and thread B. Thread A called uh the destroying function. So now the ref count is two. Now it drops the ref count uh to one. And then there may there might be a contact a contact switch. So thread B now calls the destroy function. Now the ref count is going again to two. But immediately it uh dropped back to one. Then we are going back to thread A which drops the drops the ref count to zero. And on this point the object is going back to zero. So the object is freed. Reclaimable and any can uh uh heapspring will catch it. And finally uh since thread B did not finish the destroy sequence the ref count will be dropped to a minus one. And on this point once the ref count is zero we can cause another object our our malicious fake object to be freed. And then we can further it. So again the POC uh we are creating an object and a sync source object. And we create we create two threads which call destroy which use the destroy function on the object simultaneously. Ref count will be dropped to minus one. Before it gets to minus one it's on zero. And then we can uh heapspring the kernel catch it and we have a double free which leads to use after free. So that was in coca root. And now finally uh kangaroo root. So uh kangaroo root is a vulnerability um in the KGSL minus uh 3DO uh zero um mechanism. It's the wrapper between uh the user mode and the GPU. Um so each time we map um data to the GPU another object called KGSL mem entry is allocated and this object uh manages the address range the range uh that is uh mapped. Uh how many uh object like a ref count uh protection level and many other properties. And again if you uh if you uh if you uh if you uh if you uh if you uh if you want to un-map this data we can use the IDEO mechanism because the mappings are mapped uh used by the IDEO mechanism. So the first thing that we did was going to the destroy function. And we saw this which looked pretty cool because there was uh there was also no pending check on their um on the destroy sequence. And then we went to shared mem free entry. And for some reason unfortunately they didn't forgot to do that here so it's appropriately um locked. So we don't have the same vulnerability again. So in for in frustration we went to the creation a creating object. So uh this is uh this uh uh function gets I told the KGSL mem entry. So we just get blob of data. It associates this this data with the uh with an IDR uh with an ID using the IDEO mechanism. And then it is it initializes uh the uh the uh the uh the uh the uh the uh the data. It's mapped it to the GPU and it added to some lists. So that's not appropriately locked. Why? Because once we associate we associate it with an IDEO number it is already be a ref a we can already reference it from the user uh from the user mode. So here is how we use this object. Fred A creates some uh he allocates some data. It's already uh everything here is by the way it's already uh it's already in the channel already. So uh Fred A it allocates data. It associates the um the ID data with an IDEO number. So anyone can reference it now. And then it initializes uh the data. Then Fred B it it checks for if the IDEO item exists and since it is it passes this check and frees the data. But what happens? What happens if Fred A allocates data? Associates it with an IDEO number. And right then Fred B uh issues uh release uh a free request on this object. The object is already there. So we pass the if check. And then the object is freed. So even though the object is freed and reclaimable again by Kellen Hipspring. Fred A did not finish yet. So now uh free not unused data which can be used by us will be initialized and we have here another use after free. So again uh the POC uh first we map data data to the GPU. We get a number and we are going to know which is which number will be next because as you can see here it is always increased by one. And then we issue simultaneously a create request and a free request on another thread. And and there might be again a use after free in the function KGSL mem entry attach process on the entry parameter. And so that's the POC. Now uh disclosure. So obviously we disclose everything. We had a collaboration both with Google and with Qualcomm. And I must say that Qualcomm was very responsive. They uh were and very they were very uh collaborative. So uh CineCoco rules are very responsive. So uh club uh uh huhигрub xerenge. It is a data setup it is designed to do uh work with you very in the same le XZ by equalization by your own. So that needs to be done at local level. Uh this is one example uh that Musik to put a number right down. Because that makes sense for the the the the sort of Um we are going to mix right here now on xz here. We actually just created uh a free file which is a actually work with呢 unable you can essentially do any device was fixed so far at least not that no not no OEM that we know about so you're all vulnerable. Congratulations. Heh heh. And uh finally uh Qua- uh Kuala Lumpur. So I uh Kuala Lumpur was uh was the first vulnerability that we disclosed and even though Qualcomm released a patch back in April Google did did not deploy it yet. And I would like to talk about Google for one minute. So um despite the average bug report which usually contains a document and five lines of code in the best case we supply them with a fully working exploit for any Qualcomm based device. And they classified Kuala Lumpur as a loss of vulnerability. Now what the hell? I mean uh uh uh uh uh uh uh uh uh uh uh uh uh uh uh I mean it was an exploit. So we approached Google and we asked them why they classified this our vulnerability as a low severity vulnerability. And you know what they said? They said that they planned to block this mechanism using and using using NSLinux rule in the future. So we sent it to them. It was vulnerable on the on all the devices and yet they said yeah in the future we'll fix that. So just a matter of timing sorry. Um. So maybe I hope that it will it will it will be different for the next time. And this is just to see an example. I mean that that's like a working that's a proof that it's possible. We might have out there low severity vulnerabilities which are exploitable and it poses a very high risk on all our Android devices. So uh suggestions for the future. And I'm not going to push pay more attention to your code because it will never it that's that's not an a practical uh suggestion. I'm going to give you a concrete sug- suggestions. So uh the first one for more than for more than a decade commit credits was an extremely convenient function for exploiters. I mean back in 2008 people did that. So maybe we can somehow harden it. Let's take Cisco reboot for example. It actually receives magic. So you can't call Cisco reboot by mistake. So maybe we can harden it, make it inline, put magics but this function cannot be in the kernel anymore. Not in this current situation. Now my second advice um KSLR. So ASLR is not a new concept. iPhones are also running ARM and they have it for years. New Linux kernels do support ASLR and yet for some reason Android device uh Android users don't know how to use ASLR. So they don't know how to use ASLR and users don't enjoy from this benefit. So I really think that KSLR for Android should be prioritized. Without KSLR it would be much more complicated to exploit QualaWatts and I think every other kernel vulnerability. Um the last uh advice um so S-Linux is a very really great me-mechanic security mechanism and it's greatly decreased uh decreased the attack surface. Uh but still I don't think that unprivileged applications should have access to Qualcomm's internal IPC. And even though it's nice to have it but we should pay more attention to the rules that we deploy there. Now with that said the overall uh current uh the overall uh status of Android is fairly good. SMAP or PXN for ARM which was introduced last year made everything much more complicated and yet a few small components are missing to make everything much more safe. Now um we created an app we created an app which should be uh published like now. So it is called QualWatts scanner. You can check using the using this uh app you can check if your device is vulnerable. Now for Ashminian Devil it must be but you know for the rest of them you might be surprised if they it's um if it's like that or not. If it's vulnerable. So it is also searchable on the Google page. It's also available on the Google Play just QualWatts scanner. So um thank you very much. Uh I hope you enjoyed the presentation. And So we have like five how many how much time? Like we have like so we have you like five ten minutes for Q and A so if you wanna if you have a questions ask uh Q in front of the microphone and ask. How many devices you think are affected by these vulnerabilities? So the question was how many devices are affected by this vulnerability? By these vulnerabilities? So a few hundreds of millions. I think about about seven hundred eight hundred millions more or less. No small number. What are some of the kinds of issues that you might have Oh I-I think that we have been very focused on uh the uh top level level of work that we've done but uh the the the technologies and the services that we have is really helpful to us uh because uh it's something that we have been very focused on. Uh, you know, we've been working on the digital like our firstつ on the uh the uh the whole uh on the any of the non Linux stuff that's running. Hi. Okay. Ah yeah we actually we weren't sure about it but since for example um Qua uh the Android wearables like the watch since they also use the same okay for at least for Qualcomm since it's not ARC based just logical code I mean not logical but it's not based on the CPU um we do believe that it might be vulnerable we did not check that though. So we're welcome to do that. Yeah. Hi uh on the demonstration I noticed the security patch string was from October of 2015. Is there a reason you didn't demonstrate against the latest version? Um naturally we discovered it back in like January and that's the device January February so that's the device that's like we just took it from this uh date but um I don't know if you can see it on the screen but it's there's no reason for that. I mean on the latest versions uh Google did deploy a S-Linux um rule that blocks access to the Qualcomm IPC but you can just you can I mean if you disable S-Linux so it's exploitable and it is indeed vulnerable. I mean devices did not receive a patch yet. Uh did you get trust zone access at all? Through. Okay so um once you have root you can you have access to uh the uh the uh the uh the uh the uh the uh the uh the uh the trust zone man trust zone mechanism. This vulnerability uh is however in the an un un unsecured kernel uh context and therefore it does not give you access to the trust zone kernel. However you can exploit previously disclosed vulnerabilities to achieve this in the code execution in the trust zone level. Awesome. You've seen uh on other research uh research on the internet. Cool cheers Um other questions? Yes sir um our Thank you.