Let’s start things off with a question; what does the TV show Black Mirror, the series Person of Interest, and Android Google Play devices all have in common? Well it’s not the fact that they all involve technology, nor is it the fact that they all include mobile devices, instead it’s the fact that they all include elements of using machine learning and AI to detect malicious activity. In the case of Android Google Play devices this is via the Safety Net APIs – and it’s this we’ll be talking about today. By the end of this article we’ll have answered the bellow, by reverse engineering the Android SafetyNet Attestation API and framework.
How do app developers identify if a device an application is running on is legitimate?
Google Play Safety Net Attestation API
What is SafetyNet?
Google SafetyNet (also known as SNet) is a suite and umbrella of functionality available on Android devices that have Google Play Services available. Google Play Services comes with most Android devices and allows devices to have applications such as the Google Play Store installed on them. Some devices, such as a selection of Huawei devices, do not have Google Play Services available, and so SNet is not available on these devices.
The SNet umbrella is broken down into the following:
SNet Safe Browsing API
The SNet Browsing API provides services to application developers, running application’s on device’s with Google Play Services, the ability to check a given URL for if it has been identified as a known threat by Google. For example a web browsing application could use this API to identify if the URL a user was visiting was malicious and in turn the URL could be blocked.
SNet Verify Apps API
The SNet Browsing API provides services to application developers, running application’s on device’s with Google Play Services, the ability to check if there are any malicious or harmful applications running on the same devices as the application. For example a banking application could use this API to ensure it is not used on the same device as malware.
SNet reCAPTCHA API
This API extends the Google reCAPTCHA framework and allows application developers to use reCAPTCHA checks inside of their application. For example these reCAPTCHA checks could be used to validate user requests or form submissions.
SNet Attestation API
The SNet attestation API is one of the most interesting of these APIs and the one that we’ll be focusing on moving forward. The Attestation API is an anti-abuse API that allows application developers to assess the Android device their application is running on – in turn being able to identify if the application the device is running on is rooted or compromised in some way. As an example, banking applications can use this API to ensure they’re not running on a rooted device.
Rooting and Root Detection
Both Android and other mobile operating systems have a concept of privileged control on a device. Here, when talking about privileged control, it refers to providing a user with extensive controls over the device, which the manufacturer did not intend for the end-user to have and can normally allow for actions such as breaking application sandboxing, accessing and modifying system actions, and accessing the underlying kernel. For Android this is commonly referred to as rooting. From the above it can been seen why some applications would not want to run on rooted devices, including user security, intellectual property controls, and it leading to future exploitation or control of an application. Below can be seen a sample of application’s on Android that implement root detection – this comes in many forms; from instructing the user the device is rooted, closing the application completely, or silently logging that the device is rooted.
One of the most common root detection mechanisms in place in Android applications is the Google Play SNet API. Later on this article will dive into the internals on how the SNet API operates, however, for now the below demonstrates a sample wrapper application (an application that’s sole purpose is to call the API and display the results to the screen) using the API on both a standard and rooted Android device.
How Developers get Attestation data from SNet
Now that we can see that applications using the SNet API are magically able to identify if a device is rooted or not, the next question is, how? The process for a developer is a fairly simple one. At first Google Play Services periodically runs on the device and downloads a jar file (Java archive), this code is then dynamically run and aggregates an assortment of data (Described later) on the device. This information is then sent to an unknown Google server for analysis. After this point third party applications running on the device can then call the API and will receive several variables in response.
The variables received by the application from the API include:
ctsProfileMatch: The strictest identifier on the device’s integrity. If false then the device has failed Android compatibility testing and is not a Google-certified Android device.
basicIntegrity: The more lenient identifier of device integrity. If false then it is likely that the device has been tampered with in some way.
There are also several optional variables that can be returned:
error: Error information relating to the current API request.
advice: Recommendations for fixing the device state.
evaluationType: How the device evaluation was performed, i.e. is it backed by hardware?
Taking apart the mystery Jar file
As previously mentioned, Google Play Services periodically aggregates data from an Android device and sends it to a server for analysis. While the decision making, on if a device is tampered with or not, is performed on the server the data aggregation occurs on the device. This means that by reverse engineering the Jar file that is downloaded by SNet a picture can be put together of what data goes into identifying the integrity of a device.
Timeframe of SNet Attestation versions
There have been many versions of SNet over the years, and with each new version comes new forms of data aggregation that occur on the device. Below shows an incomplete timeframe of SNet versions (put together in part by the research from Collin Mulliner & John Kozyrakis) up to 2019, however, there have been many more versions both between these dates and after.
SNet Attestation Modules
The data aggregation performed by the SNet Jar file is broken down into several categories based on their functionality. From this point I’ll walk through a handful of the modules available in SNet version 10000700.
Device State Checker
DeviceStateChecker.java | SNet Version: 10000700
Including variables: the verify boot state, verifying mode, security patch level, and if OEM unlock is supported on the device.
SettingsFinder.java | SNet Version: 10000700
Including variables: if ADB is enabled, the device fingerprint status, the lock screen timeout, lock screen type, if non-market apps are enabled, notification visibility at lock screen, Android smart lock, and the storage encryption status.
SD Card Analyzer
SdCardAnalyzer.java | SNet Version: 10000700
Process: this module saves a JPG file to the external storage of the device and periodically checks in on it. If the image has been altered, removed, or changed in any way it’s reported as a indicator or compromise.
Rooting File Finder
RootingFileFinder.java | SNet Version: 10000700
Process: this module looks for the presence of several files and file paths on the device, including: “/system/bin”, “/dev/block/loop”, “/system/xbin”, “/bin”, “/xbin”, “/proc/self/mountinfo”, and more.
Preferred Package Finder
PreferredPackageFinder.java | SNet Version: 10000700
Process: this module aggregates the set default installer and web browser on the device (i.e. Google Play Store and Chrome).
Captive Portal Detector
CaptivePortalDetector.java | SNet Version: 10000700
Process: this module sends a request to a hardcoded Google server and saved the IP address, response body, and response code. Presumably this is compared with the known response by the integrity check on the server to identify if a captive portal or man-in-the-middle was present on the device.
In addition to the above sampled aggregated variables, there are many more that SNet aggregates and sends to the Google server for integrity reviews. In late 2019 the version of SNet I reviewed included approximately 55 variables that it was aggregating.
In past research I’ve previously developed a tool called Tamper, which seeks to replicate some of the key functionality of SNet. I may write a follow on article on this process, however, for now you can see it’s development over on GitHub.
Develop Your Reverse Engineering Skills
I’ve released an Android reverse engineering course inspired by my interest in game design. This course walks through the fundamentals of reverse engineering and uses Android games as a fun and practical starting point.
Learn More On Android Internals
In 2021 I released my first book with Apress publishing, Android Software Internals Quick Reference. If you work with or find programming and Android interesting please consider picking the book up for yourself!
ANDROID CHEAT SHEETS AND STUDY GUIDES
Free and premium resources, available on everything from Android and iOS security fundamentals, reverse engineering basics, and study guides for my Udemy courses.