Posted by John Kozyrakis on October 9, 2015
The SafetyNet attestation API is a Google Play Services API that any developer can use in order to gain a degree of assurance that the device their application is running on is “CTS compatible.” CTS stands for Compatibility Test Suite, which is a suite of tests a device must pass, prior to release, to be allowed to include Google Play Services. Traditionally, it was used by device manufacturers to ensure that their devices met Google’s requirements. The term is now overloaded with more meanings, like ‘the device is in a non-tampered state’ after release. Tampered state has multiple definitions and includes ‘being rooted,’ ‘being monitored’ and ‘being infected with malware’.
SafetyNet is a tamper-detection framework that is part of recent versions of Google Play Services. All Play-enabled Android devices using Android 2.3 and above already use SafetyNet as long as the Play Services package is updated. Among other things, this service informs Google about the ‘safety’ status of each device, providing indicators related to rooting, tampering, active man-in-the-attacks and others.
Learn more about the developer instructions on how to use this service.
As is evident from the instructions, there is a lot of flexibility in the ways a developer can use the service.
Imagine that you, as a developer, have an application that communicates with a remote web service endpoint to fetch some important data.
Now, imagine that you want to ensure that the device your application is running on is not rooted or tampered with in some other way. The application may choose to do client-side checks, implementing SafetyNet attest() insecurely, as in the following sequence diagram:
This basic client-only implementation flow can leave your application vulnerable to trivial hooking attacks that manipulate the attestation responses. Xposed modules bypassing this basic implementation of SafetyNet have already been published. One such attack, used in this particular Xposed module, is returning True in all calls to getBoolean for variables named ctsProfileMatch or isValidSignature. We would expect such check to exist inside the code of the mobile app so that it can validate the AttestationResult.
A more secure way to implement the SafetyNet attest() API is by utilizing a client-server architecture, as described in the following sequence diagram:
In this implementation, the WebService will get Google’s CTS compatibility response in a way that cannot be tampered with by other application running on the device. The WebService can then react appropriately based on the device state.
In order for this implementation to work, your web service needs be configured with 3 things:
The workflow is described below.
Developers should be aware that a local attacker with root privileges will always be able to defeat ‘tamper-detection’ checks on the client side, via tampering with the data Google Service feed to the SafetyNet service.
The advantage of using SafetyNet over conventional root-detection and tamper-detection approaches seem to be that it shifts the workload of attackers as follows: When attacking conventional root-detection mechanisms, an attacker can examine how the protection mechanism’s controls are designed and disable these controls or feed them with manipulated data in ways they know the checks will be bypassed. On the contrary, SafetyNet is implemented in such way that only the data collection part of the system can be observed; not the implementation of most checks. For example, SafetyNet has the capability to retrieve a list of all files in the filesystem. An attacker attempting to defeat the system would need to examine all gathered data and make educated guesses over what Google would consider a sign of tampering. Note that the attacker wouldn’t be able to observe what the data sent to Google from a non-rooted device looks like; so the attacker cannot simply use that data.
In practice though, it seems that the current SafetyNet implementation can be easily defeated via moving the su binary to a different location and hooking a call that reads a file with information about the selinux status of the device.
We expect that in the future, Google will implement more checks like verification of the integrity of the /system partition, turn on some checks that are not currently enabled and do a better job in data correlation.
Developers that are already using a different system of rooting or tamper detection can include SafetyNet attestation results as an additional mechanism in their existing implementation.
Synopsys consultants created a sample application, Safety Playground, which makes use of the attestation API in the secure way described above, utilizing a client-server architecture.
SafetyNet Playground consists of an Android application and an associated web service that can be used as a sample for developers attempting to use Google’s SafetyNet attestation API securely.
This sample app will attempt to make a REST request to a sample web service. The server will return a “success” response only if the SafetyNet service attests that your device passes CTS compatibility checks.
All Android application developers can use SafetyNet in the way we demonstrate in our proof of concept code to ensure that the checks cannot be bypassed easily. Of course, with enough effort, all client-side code is by-passable by attackers with higher privileges.
Caveat: SafetyNet attestation is a Google Play service – it may not be the best approach for your application if you want your app to run on non-Google Play devices (e.g. Amazon).
SafetyNet research: John Kozyrakis, Technical Strategist at Synopsys.
SafetyNet Playground app and web service development: Georgi Boiko, Security Consultant at Synopsys.
Google Play is a trademark of Google Inc.