 Welcome, everybody, to this next talk inside Android Safety Net Attestation, Attack and Defense. First of all, I would like to see a show of hands who among you has already developed an Android app. That's almost everybody, I would say, something between 90% and 98% of you and who of you has already used the Safety Net Attestation API. Please, another show of hands. That feels more like five or six and who of you has already heard about this API before coming here today? That's more perfect. That's why you are all here, I guess. So gear up for a very informative talk by Colin Maliner, an expert in the field of security research. And he's also the co-author of the Android Hackers Handbook. I'm very excited for his talk. Please give him a warm round of applause. I write in, this was basically, yeah, just some. I did a bunch of mobile security and development some years ago, wrote a bunch of guides and helped on this book. But let's get right to the talk. So what are the goals for this talk? The main goal for this talk is, of course, understanding what Android Safety Net and especially the Attestation API is, and actually how to really implement and deploy it. As you will see throughout the talk, it's not like that straightforward, unfortunately. And then we're just going to look at the Attestation API, really what can it do for you and what can it do for you? And I guess with most security systems or features, it's very interesting. The part what it can do is the most interesting part. And then we're going to look at some attacks and bypasses from other people and some of my own work. And the second main goal of this talk is basically document this API because Google's documentation is not very good. And that's how I thought, hey, let's talk a little bit about this. So of course, this entire system and this entire talk is about app security. And back in the day, all other apps did not communicate. But these days, if your app doesn't communicate, who cares? And mostly, it communicates with an app-specific backend. And if the app and the backend, everything works. The user is happy. Everybody's happy. And if it doesn't work, everybody's unhappy. And the company will not make any money. And they will discontinue their service. So mobile app security is really, really interesting because these days, an app or a mobile app is really just the gateway to the backend service. And these days, there is a lot of online service, which are basically mobile-only or at least mobile-first. If you think about something like Snapchat, they don't even have a website or anything. And app security is also about basically controlling data. So who displaying data and managing data by the app and making sure somebody is not allowed to copy out data that is managed by the app? And altogether, basically, mobile app security is really about protecting your service, your revenue, your brand, and hopefully, really hopefully, your customer or the consumer. So if you look at ad hacks in general, what are we looking actually at? The main part is OS modification. Basically, on Android, we'd say rooting. And rooting is basically just the break the assumptions of the security model. Because if you root like your phone, you suddenly are able to basically take content from apps that didn't want their content to be taken in the first place. And you can do this by just reading data or taking screenshots or instrumenting the app and pulling data out of it. And of course, you can also just modify the app directly. And then you can change whatever the app is doing or what the app is enforcing. And of course, there's also network traffic. But in this talk, I'm not going to look at network traffic at all. So if you look at rooting, what is rooting actually? Basically, it's regaining full control over your device. Because these days, any kind of phone or tablet, basically, you don't have root anymore. You don't have full access to everything like on your computer. And with rooting, you gain access again. You gain access to resources. You can read and write any file and modify parts of the SOR, like the software framework. And all of this rooting capabilities really highly depend on Android versions and really newer Android versions are much, much more hardened due to, for example, as a Linux policies. But I'm not going to jump into that part. So if you look at app security in the old days, what did you have? There were basic rooting checks. So apps would implement something like, hey, is the system, does system expand as you exist? So they were just checking, hey, did somebody root the file and reinstall as you? And if that was true, they would just say, yeah, your device is likely rooted. This app is not going to work. And the same with apps. They would just check if a specific package is present. Or they would check if expose is installed. And maybe would try to detect emulators by just seeing what get device ID returns. And if it returns zero, it's often like an emulator. So that's really the old days. And the old days, for the developers, it was really, really easy to implement because they knew they can just check for certain files or certain packages. And it's really easy to implement. You don't have to be a genius. You just have to check for this file. And then you can very easily deploy those kind of checks. But of course, for the attackers, easy as well. Because they also understand how this works. So they could just rename some files or move files around. And then they can, again, abuse those applications. So modern mobile app security really works by collecting data. Basically, you have some piece of code that just collects data and just sends it to the back end. And your back end will make the decision if a specific thing happened. For example, if your device is routed. And the idea behind it is that the attacker cannot just patch out your app, patch out checks on your app. Because imagine if you just have to file access check to a system bin as you, you can just remove that. And then the app will just work. But if you collect really a lot of data on the device, you really don't know what is used for what. And you basically have to fake all the data. And if you collect really a lot of data, you can't really do that. That's basically what all modern apps that have a high demand or a higher demand for security do these days. And also that is what safety and adaptation will do for you. So just to go a little bit back to Android. So in the early days, Android was very, I would say, very open. But these days, a lot of openness, like when the waves, they have secure boot now, which is basically just a trust anchor. Basically, they just are able to tell if you unlocked your bootloader and things like that. And of course, there's way more as a Linux restriction. So they have much stricter sandboxes. And then Google added this platform security service called SafetyNet. And SafetyNet is really just a brand name for security services on Android. They have a bunch of different services from verified apps to check for PHAs, which is Google's nicer term for malware. And then you have attestation. And then you have a capture service. And SafetyNet, in general, is designed to run on any Android device that has Google Play. So it's part of Google Play services. And the nice part, it's independent from the manufacturer. So this exists on any Android device, not only on the Google devices. And with attestation, you can do remote device and app attestation. And of course, Google also heavily uses their own APIs. For example, if you ever used Android Pay and saw this nice pop-up that meant SafetyNet actually failed to validate or attest your device or, I guess, the Android Pay app. And they said, oh, yeah, you modified something. And one of the intentions, I think, behind the attestation part was they can't really control security of other manufacturers' devices, but they wanted to support Apple Pay on them. So what did they do? They basically found a way to measure if your device or the device's Android Pay is running on. It was modified. And the nice part is they can really change SafetyNet, like the attestation part, on the fly. So you don't have to wait for a system software update. Basically, they can push code to the device at any point to check for modifications. And with that, they can really fast react to, say, new routes or something without having any software updates being delivered to the devices. So what is actually the attestation part? It's really the attestation of the device and the specific app that called the API. That's basically all of the things people used to implement themselves. And as I said, it's part of the Google Play services. And basically, you just call an API and validate that your app and device is the device of the user was not modified. Unfortunately, the documentation, as I said in the introduction, is not super detailed. And they leave a lot of things to your interpretation or just you have to basically use it to find out how this really works. So over time, it got much better. But when I started looking at it, which is by, I guess, yeah, one and a half, two years ago, some of the documentation was really bad. And they add new features without really documenting them. They have a private mailing list where they announce some stuff. But yeah, this is probably, I guess, the only piece of code, actually, I'm going to show. It's basically just how you call it. So SafetyNet is part of the Google API client. And you basically just say, I want a connection to the SafetyNet API. And then you just call it. So how does it actually work? So here in the middle, the box in the middle is basically that's the software that's running on the phone. You have the backend, the Google Play backend, and your application's backend. So if your app doesn't have its own backend, you really can't use SafetyNet at all. And you will see in a second why that is. So basically, what happens if your app talks to your backend for maybe wants to log in or do some very specific operation, and then your backend will say, hey, dear application, I need you. I request you to attest yourself. So the backend will basically send a request to its app. The app will then call the SafetyNet at the station API. And in this step, you actually see the attestation code on the device will inspect the device itself. So the operating system was it routed. And then it will also inspect the actual application. Some minor detail in the call, there should be a nonce to prevent replays. It's just like for documentation. So that's basically you, instead of having you implement everything yourself, you can just call this API. And you will have all the work done by Google engineers to do your security configurations, or security attestations. So what happens after attestation has checked you up on the device, it will send the data back to Google. Google will actually analyze it, and then will determine the state of your device and your app, and actually forward the response to your app in order to make sure the app, because if you modify the app in this case, and if it would not be signed, you could just like tamp it with this attestation response. So this is signed. So in the backend, you should validate that signature, and then validate the attestation, and then you actually know what you're dealing with. That's basically what you get back. It's really, really, really simple. Just some blobs of base 64 encoding. So Google has a signature validation API, which is basically just for development purposes. But yeah, that part is actually pretty well documented. I guess they do that a lot, like SSL, CertValidation. But let's look at the attestation data. So the attestation data, that's basically the main blob. You get back everything else is just like a chain and the signature. So you see the CTS profile match, and that's basically the core device integrity measure. And CTS refers to the Google compatibility test suite. So basically, whenever you build an Android device, you have to run this test suite and give Google the results. And basically, what this API does is basically collects data from your phone, and then it compares it to the data the manufacturer provided. And by this, they can determine if you modified contents of your system file system. And then you see which APK called the API, and then you get a digest of the APK itself. You get your non-spec, and then you also have timestamps. And the basic integrity is an indicator about routing. So this nice table was actually only, I guess, probably added to their documentation maybe seven months ago. And before, it was like, yeah, there's a true and false field. And yeah. So basically, here you can see, CTS will only be true if your device is genuine and passed the CTS data corresponds to the data that was collected. If as soon as you unlock your bootloader, that goes to false. But basic integrity will still be there. So if you just unlock your bootloader, but didn't modify actually the content of your file systems, your basic integrity is true. And that's basically, those two different indicators will basically help you to understand the state of the device. And with this nice table, you can basically implement your checks. So I wrote this small demo. I actually implemented that for a bigger company. But I also built this small demo app, which I'm going to show you at the end. And you see some, it will basically just run this attestation. And it will tell you if your device is rooted and what the app integrity is. And you see the blob of data below. And you see everything is, it passes all of the checks. And we're going to have some more fun with this later. Yeah, the big issue with safety net and the attestation API is error states. There's a ton of different errors. And if you don't know what you're dealing with, you can basically very easy bypass the entire system. If you as an implementer aren't aware of error messages. So for example, this is one of the nice basic errors. Basically, for some reason, the API call actually worked. But somehow the code inside the API just encountered some random error. You will get this. And they basically say, oh, yeah, we just have this random error message. And you're going to find out how this actually looks like. Because this is not really documented. And this error basically just means just call the API again and try again. Most of the time, it will just go up. Yeah, this is one of the more interesting errors. This basically says we can't really determine which API called the API. Also, they kind of think the device is generally untrusted. So they just removed a bunch of fields from this JSON response, which is also very confusing if you implement this the first time, because you suddenly get broken data blobs back. And again, of course, this was not really documented. So now you know, basically, we have this API. And maybe the JSON field looks strange. So basically, now you can go and implement your app. And have the interaction between your app and your back end, and your app running the attestation. But unfortunately, it's still not that simple. So also, all of the API calls can kind of fail. And they actually will fail on the wild. Like every API you call will actually fail at some point depending on your user group. If you're playing at home with one of your devices, you will never see any of those errors. But if your app runs on 100,000 or millions of devices, you will see every error eventually. When you have things like, oh, Google Play Services doesn't support SafetyNet yet, so what should you do? And one part is you can just force a user to update their Play Services. Or then there is just general error, connection errors. And in those cases, you just really have to retry. If you forget to handle one of those errors, that either means some client will basically not work on your network, or some client will be allowed to connect to your service, even if it was tampered with. In the lower three cases, that's really something you should actually be able to see during development. Because of your nonsense to short, it will actually just like directly fail. Yeah, some more examples. So I just uninstalled the all Play Services updates on this Nexus 7, which is an Android 4, which also doesn't have secure boot. And then if you just start the application, you'll just like nothing will work. Because you really need to update those Play Services. So a lot of the API failure things are basically temporary failures, so you basically have to start with retrying everything. Generic errors, networking errors. And in general, you should be like a good citizen and basically do an exponential back off after each failed try. Also, you can look into this JSON field or this JSON blob on the device itself and then determine if you want to do a retry, then you don't have to do a fall round trip to your back end. But basically, what you really need to do is report any of the failures to your back end and really plan what you're going to do if some device keeps just like throwing errors. Because that's, in the worst case, a user of your app that can never use the app because if they have some random error. So you have to really think hard about what you're going to do. Unfortunately, this, of course, is an app-specific behavior. Because in some cases, maybe it's going to let the person use it once or twice. But maybe you say, we never want anybody who fails this to ever use our service. And this is really more app-specific decisions. So let's look at, yeah. So the main function, or one of the two functionalities, like the OS and device integrity check. And that's basically just like those two fields which give you true or false. But app integrity works a little bit different. Because Google can't really tell you if your app integrity is there. And you have those two fields, the APK digest and the APK cert digest. And the cert digest is really like the digest of the key you assigned your APK with. So in the easy mode, so if you re-sign an application, the cert digest will be, of course, different. So if somebody just uses APK tool on the app, modifies the app, reinstalls it, the APK cert digest will be different. So the most easy check for app integrity is basically just like compare the APK cert digest. And you kind of say if you have five different apps, and most likely they will all be signed with the same cert, you basically only have to hard code this cert digest until you're back end once. And you can just always compare that. If you've done this, it's basically a very, very simple comparison. But with that, you can know if your app is not tempered with. But you can also go into advanced mode and basically also compare the APK digest. With that, of course, a little bit different or a little bit more difficult, because that means for every single APK you ever released to the app store, you basically have to record the digest of the file. Because if you didn't do that, you will just reject people and say, hey, we don't recognize this app. Yeah, you probably modified your app. But in reality, maybe you just forgot to collect the data. So you have to have very tight control over your release process. But you can do cool stuff like revoke specific APK versions at this very early part and the communication with your server by just deleting that specific digest from your database. And then SafetyNet will basically block this APK for you. So basically, to do the implementation and deployment, on the client side, you really have to check for error conditions, retry, and report failure codes in the back end. You really have to make sure to validate the signature and the attestation data. Check really all fields, timestamps, nones, and really make a decision about failures and what you want to do. And especially things like, do we want to force users to update their play services? And maybe have something like a white listing mechanism where you can whitelist maybe specific kind of devices because you will run into problems and you probably don't want to prevent a specific user group from not being able to use your service. So that's basically the part about what is at SafetyNet attestation, how does it work, what you should look out for when you're trying to implement and deploy it. But of course, as I guess anybody who is interested in security, and if you implement a new security system, you really want to know if you can actually trust that system or if it just does nothing. So when I first looked at it, I was like, let's see how good this actually is and can we do bypasses? And also, what are the limitations? Obvious limitations, I guess, were different Android versions because on Android 4 and 5, you really don't have this secure boot state. Applications cannot determine the boot state. So anything that would be based on unlocking your boot loader would basically work because if you can't detect that the boot loader is unlocked, you can't unlock a boot loader. And on Android 6, of course, you can detect the boot state. And then you can actually rely on everything that is based on the secure boot mode. But this, of course, already shows you that all devices are very much harder to judge in terms of the attestation system because of certain limitations of the actual OS. So in your security policy in your back end, you basically have to know that, hey, if something, like Android 4 or 5 devices, we might not be able to see certain things if you just use safety net. And you have other things with Android 4, so you don't have the invariate that means you can just remount and write or change files on the system partition. So you can do fun things like change, or rename, or move system X when it's used to some other directory. And then if you just run your safety net-enabled application, you will totally bypass. Or you will actually not bypass, but you will just pass the attestation because the system will say, yeah, fine, nothing. It was modified. And then after using that app, you can basically restore SU to, like, by copying it back. You could also, and that also is like another basically indicator of what you should do. If you only, like, basically run safety net on app startup, you can do things like that. But say if you use it more often, like at random intervals, just the back end server is like at random intervals, just like says, hey, can you rerun this attestation for me? Those things have become a little bit harder. Of course, none of this is documented at all. So this is my small demo application again. It's like this was like a Nexus 5, X with Android 6. And I just unlocked the boot loader. And then if you run the attestation, we'll see something like this, like CQ boot mode. That actually doesn't come from the attestation API. I just read that from the system properties. But it basically detects, yeah, unlocked boot loader. And so it will change, yeah, where is it? Yeah, the CTS profile in the middle to false. And it would also give you an advice. It's like, hey, you should relock your boot loader. And this advice field is also something that just added. I think earlier this year, just under, just like that, just added it. And you were like, I was looking at this JSON file. I was like, hey, there's a new field. And it's undocumented. Nice. So suhide and magisk. So obviously, if a system like that exists, people will try to bypass it. And one of the first bypasses for this was suhide. Basically, you can call it a root kit because it's really just hiding, trying to hide, basically, that you're rooted your device from safety net. And that was the suhide was very simple. And Google very easily actually detected it. And you could actually read in forums, like the people would post, oh, I can't use suhide anymore. They did not detect that. And two weeks later, it was like, or maybe two days later, there was an update. And it worked again. And then it was detected again. And that's really where this short iteration cycle, due to code pushing, comes into play. But Google can just really fast react to whatever changes. And then suhide was discontinued because the guy basically said, oh, I give up. Like, they can change their detection so fast. And I want to do something else with my life. Then just updating. But then there's Magisk, which is a more modern way of basically hiding root. But Magisk is based on unlocking the bootloader and patching as a Linux policies and so on. Actually, this is, as far as I know, completely undetectable at the moment due to safety net actually not running with full system privileges. But in this phase, you really have to unlock and modify or unlock your bootloader and do heavy modifications. So it's not probably done by a lot of users. But yeah, basically, those two are basically real root kits to hide root from security services on Android. And yeah, Google is playing a nice cat and mouse game. So yeah, and also, those two basically just try to hide system modifications or routing, which is only one aspect of safety net, or the safety net attestation API. So I was more interested in app integrity because the other two checks can obviously be bypassed. And really, nobody ever looked at app integrity. And I was really wondering why. And I was like, yeah, that's kind of interesting for us. So I was looking into app integrity. And basically, the goal behind app integrity is really to detect if somebody modified your application. And you do that by looking at the APK digest on the cert digest. Because if you could modify the APK, you can do something like remove the TLS cert pinning and modify traffic and things like that. So and you probably don't want that to happen. So that app integrity is very interesting. So how does app integrity or how does the cert digest actually work, or the APK digest? The interesting part is those two values are calculated on the APK file that is stored on disk. But if you know how Android actually works, you know Android doesn't actually execute the APK. Because APKs contain DAX files, and until Android 4 DAX files would be converted to ODEX, like optimized DAX files, which is like a bytecode. And Android 4.04 and 5 and later would just compile the DAX code to a native code. And there was three years ago, there was some work done on patching ODEX files. So this problem of calculating check sums on our digest on one file but executing another file can, I would say, obviously be attacked. So if you rehash the code running again, so on Android 4 and 5, you basically have the data directory, and we have under data, you have app where you're like APK sets. And then you have the program data, and then you have the code in data, Dalvik cache, and then you have this super long file name, which is basically the very optimized DAX sets. On Android 6 and later, you have just your package directory, and in the package directory, you have an APK, and you have the base ODEX file. But in this case, it's actually not an ODEX file. Oh, it's like an ODEX file, but it contains native code. The interesting part is those files are all owned by the system, and they can only be read and written by actually install D and Zygote. So your own app can actually not read its own binary, which makes this very interesting. Because Zygote just loads it into memory and then executes, so your app doesn't really need to be able to read its own code. So if you go back and look at generic app modification, how does this actually work? Normally, you would do something like APK tool, and then you just unpack the file, modify the Smiley code, and use APK tool to rebuild the APK. Then you just sign it to sign the file, and then you can just run the modified APK. Of course, in this case, the signature would be broken because you don't have the author's keys. On the device, APKs are compiled using DAX2out. We can just say, this is DAX file, this is the ODE file, and then you have the modified APK. So then what you do with this ODEX file, you still have to patch the modified ODEX file to be the ODEX file contains a CRC32 of the DAX file it was generated from. This is not a security check at all, it's just for the VM. So the VM can see that maybe the APK was updated, and now the CRC doesn't match the DAX file, and just recompile it. That's just a pure let's not run old code feature. It's not a security feature. And in order to patch the CRC file, I made a small tool that's really tiny, and that's also open source, where you can just patch the CRC of the ODEX file. So what you can do, basically, which will work on any Android version, you can just like, you need to override the ODEX file of the specific app. So if your device is rooted, you can just go and overwrite that specific file. And so either in the Dalvik cache or in the app, ODE cache, and then just stop the app and restart it and you can just have this modified APK. And it will actually bypass all of the checks because you only modified the code that's executed, but not the original APK. And then, of course, you have to unroot because you want to still pass the general device integrity checks. So if you go back to, if you think back about earlier slides where I said, oh, on Android 4, you can't really detect if a bootloader is unlocked. That basically means on Android 4, you can trivially bypass app integrity checks because if you have a root that is based on an unlocked bootloader, you can just do that. So that is bypassed. But I was like, yeah, so I bet we can also find other ways to do this. So the main goal for this attack is like as before, we really want to overwrite this one ODEX file. But we know only basically two demons can actually write or two binaries actually have the as a Linux privileges to write to this file or this class of files which is installD and thygod. But who else can write to any file in the file system? Of course, the Linux kernel. Because access anything that's like as a Linux or file permissions do not exist for the kernel itself. And two years ago, no, one year ago, there was this nice kernel bug by the name of Dirty Cow, which for this talk, I just like, yeah, you basically allowed you to overwrite any file in the file system that you can read. So as a shell user, you can obviously read all ODEX files. So now we can go and basically, since we can read any ODEX file, without routing the device, we can actually do this attack without routing a phone. So basically the same procedure, we APK tool the file, modify the ODEX file, and patch everything. But the one small issue is Dirty Cow cannot only overwrite files, but basically not depend or increase the size of a file. And the one easier trick that I've found is, so normally Dex2Out runs with processor-specific optimizations. As you can see down here, it's just like Cortex-A53. And optimizations can usually make files much bigger. So if you just compile, if you just run Dex2Out without optimizations, you will actually get a much smaller file. So even if you add a lot of code to the patched app, your file will still be smaller. And you can very nicely overwrite the ODEX file using Dirty Cow. Yeah, I'm actually going to show you, do a little life demo, because it's actually that simple. First, I'm going to show you. So let's see until I just have to wait a little bit until the camera adjusts to the white. There we go. So this is like the demo app I wrote. Yep, and we pass all of the checks. And so basically, un-routed device, un-modified app. Looks good. So is this readable? I think that's OK. That's fine. So this is the APK. So if you just unpack this APK quickly, and then we're just going to modify some code. So this is just some smartly code, which I'm going to patch into this application. That's all we need. So and now we can just rebuild with basically use APK tool again, and also use the JAR signer with the default key store to just have a self-signed APK. I guess I didn't set the path for that. Where is that path? Who knows where that file is? It's in build tools. Now I have the path for JAR signer, the command arguments for JAR signer. Yeah, that I guess I should have. Where is that? Oh yeah, I heard JDK is where that's exactly where it is. Where is my JDK? Definitely not here. Where is the JDK? There we go. It's like checks. Nope, should be more of those. Yeah, I was pretty sure. There we go. OK, so let's do this again. Yeah, so now we've re-signed the app. So what else do we need to do? So we have our re-signed app. So we want to compile this app on the device with basically pushing the new APK and getting the modified compiled ODEX. Now we want the original base file because we need to extract the original CRC. And now we can do, let's say, this is the original one. And this one is the one we want to change. So what you're going to do here is I want to change this one to this one. Now if we write it on this, nope, old CRC, new CRC. Yeah, it's always nice if you forget the command line of your own applications. And now we modify. Yeah, now it's modified. So this is like patched. And for the attack, basically, we push this modified app, the modified ODEX file to the device and then run dirty cow. It's another nice point of failure in this demo. And it didn't work. I can try again. I have a few more minutes. Yeah, I like life demos. They just turn to sometimes they do not work on the first try. It's all good. So you're just going to reinstall the original APK. Since you already have all the modified files, you can just skip everything else. So let's try it one more time. And it worked. So let's go to the camera. Let's wait until the white. And now you see this nice pop-up we added. And you will see all this checks passing. And so, yeah, and basically an unrooted device, but complete, basically, app compromised from the integrity level. So what is the actual impact of this attack? Yeah, it's, of course, limited to Android device. It's still vulnerable to dirty cow. There's probably a lot of them. The nice part is that basically the owner of the device has to perform this attack himself. Because apps, so if you get a malicious app that runs on your device, it could not modify another app because apps cannot open ODEX files. So that's good. Of course, the attack goes way beyond safety net attestation. So any device that any check you do on ODEX files or something will be vulnerable to this attack. The nice part is Android 7 devices will not be vulnerable because Google changed basically the policy for their CTS test. So they will actually check if your kernel still has this bug, and then you will not get Google certification for Android 7 devices. The generic attack I told Google many, I guess, now it's probably two years ago. So they know it, but it's hard to fix. Copperhead OS is like hard Android clone. They actually, not by accident, by design, mitigate any kind of these attacks by just recompiling every app on every start. So that would kill modified ODEX files. So I made some observations over time. So basic integrity was just like July 2016. Suddenly I found this, and I was like, hey, does anybody know because this is not really documented. And then again, I guess May this year, they added this advice field that will tell you about your bootloader or please reflash your device because we determined your device was temperate. So that was kind of interesting. Now there's also a mailing list where you can subscribe and they will tell you, I guess, about new features, but the website will still not be updated in a timely way at all. Also, the little bit more interesting part, so since attestation is based on CTS data, and CTS is run by manufacturers before they release an update or a patch or a phone, so if this data is false and not up to date, of course, the CTS test will fail and will tell you, like, hey, your device has been modified. And I actually found that on some Yota phone where I guess they rolled out a security patch and did not submit the CTS data. So on all of those patch devices, actually all of this would just fail just because Google didn't have the up-to-date data. And actually Google did it themselves. Here in March this year, Google had to pull a security update for the Nexus 7 because it broke their safety net and thereby also Android pay part. And that's probably the last part. I don't know how that happened, but basically if safety net attestation has an outage and you can't react to this outage, you will have an outage too as an app developer. And you probably do not want that. The fun part about safety net in general, Google really improves it all the time. If you follow forums, routing forums, and so on very closely, you will see this cat and mouse game. And it's mostly, for Google, I guess, mostly about protecting Android pay. But yeah, I guess the big benefit of safety net and the attestation part is that really you have a bunch of people at Google who constantly work on improving basically the results for safety net. So if you use that to secure your own app, you get a lot of security for free, where you otherwise would have to employ a bunch of people or buy a third-party product that does app and device integrity checks for your service. The nice part is attestation is free. But of course, it can go down and have outages. They basically don't get an SLA. There's rate limits which you should never be able to reach. Yeah, and it's free. If you compare it to third-party services that are not free, this should be interesting. On the side note about malware, so there's a lot of Android malware that basically is repackaged Android apps. So basically, people just add whatever they want to do to Angry Birds, and then you will download that modified Angry Birds. If that game or that app would actually run safety net, they would basically that repackaging wouldn't work, because the app would just say, hey, I was modified and it don't work. So they have to either cut out a lot of functionality of that specific app, and they probably won't do that because they will just go after some other app. So you can basically use this to basically prevent your product from being targeted by app repackaging malware as a side effect. So summary and conclusions. Basically, it's one of the essential platform security services. And if you're serious about any kind of app security on Android, you should really, really use it. As I showed you, there's some downsides or some things you have to be aware of, but you have to be aware of those anyway if you roll your own or buy a third-party service. And the majority of apps will just benefit from this. And it really will really get better over time. And you can really see Google doing improvements to that. And that's it. Slides are online. Tools are online on my GitHub page. Or if you go to malinar.org slash Android, you'll find everything related to this talk. Some more references to read up. That's it. Thank you very much. And I guess we have two minutes for questions. I'd like to take one question from the internet, please. Oh, and we just mentioned that people really like to run in the Q&A, and Google has another tool in the Q&A. We do the Q&A. Yep. What does safety net not run with full permissions? Because it runs inside the Google Play services. Basically, the Play app, the Android Play app service, and that only runs as system service. And so it doesn't run with full services because of that. It just runs in a slightly privileged app. And I think that's by design. Also, think about other manufacturers, like maybe Samsung or HTC. Other companies probably do not want to have a super high-privileged Google process on their phones. Now, it's just by design. That's the only thing I can think of. Yeah. Thank you. Next question from microphone number two, please. Hello. Can I hear you? Yeah. Thank you for your talk. First of all, it looks like safety net runs under a system user, right? Yeah. And it has way more privileges to check for a file system when ordinary application. Yes. Do you think it is still worth to do enough checks for things like root attack devices? I think that it really depends on your risk model. If you're very concerned about modified apps or modified devices, of course, it makes sense to add your own checks in addition. But I think if you're starting to develop a new app, you should first implement safety net at a station and get all of this right. And then you can start investing money to build your own. Because if you start rolling your own, basically you have to have a team that constantly keeps up to date with Android versions. Because if something changes in your app and your own detection has false positives, you will just disable your app for a lot of people. So yeah. It's like depending on what you want to do and how much you want to spend on that. Thank you very much. Unfortunately, time is up by now. So whoever else has questions, please find Colin after the talk. I know you probably all know that it's pretty nerve-wracking when you're on stage. And your demo or whatever you were planning in your presentation doesn't work as planned. So I hope that you're going to show a lot of empathy and give Colin another big round of applause. Thank you very much.