Kryptowire Discloses (Un)protected Broadcast Vulnerability
Kryptowire Discloses (Un)protected Broadcast Vulnerability
Kryptowire discovered a vulnerability affecting Android versions 9, 10, and 11 (pre-release) that allowed third-party apps to spoof sensitive system broadcast messages that only the Android system should be authorized to send. The vulnerability occurs when a pre-installed app declares that a Broadcast Intent message should be “protected,” but the protection is not granted due to the declaring pre-installed app’s location on the file system. Kryptowire identified numerous Android vendors and devices that are impacted by this vulnerability where unauthorized apps can exploit vulnerable pre-installed apps to perform privileged functionalities such as arbitrary command execution and access to private logs. Google assigned CVE-2020-0391 to the vulnerability with High severity (CVSS3.x 7.8). In addition, a chipset manufacturer assigned CVE-2020-11164 (private) to a vulnerability that was enabled by sending these (un)protected broadcast messages.
Google security update for Sept 2020 includes fixes for Android 9 and Android 10. We urge all users to install security updates as soon as they are available and to only use and install apps from trusted sources. Android 11 has already been patched prior to release. Devices that use Android 8 or below are not affected.
Utilizing Kryptowire’s automated firmware scanning tools we are able to provide up to date detection of these vulnerabilities as new firmware and devices are introduced into your organization. To request more information about our firmware scanning service please click the link on the right.
What is a protected broadcast?
Android apps and the Android system can send messages to multiple receivers using a Broadcast Intent. An Intent is a message sent within or between processes that can contain embedded data. Broadcast Intent messages are heavily used by the Android system to notify apps of events so they can respond to them accordingly.
To prevent arbitrary processes from sending sensitive broadcast Intents, Android allows the declaration of sensitive broadcast actions as “protected” by using the ‘protected-broadcast’ element in an authorized app’s AndroidManifest.xml file. Listing 1 provides an illustrative example that protects the action string of android.generic.ACTION using a protected-broadcast element.
The declaration in Listing 1, when used by an app that is allowed to declare protected broadcasts, will prevent unauthorized processes from sending a broadcast Intent with the protected action.
Who can declare protected broadcasts?
Only apps that are pre-installed (e.g., apps that come with the device) on an Android device can successfully have their protected broadcast declarations recognized by the Android system, although which types of pre-installed apps can successfully declare a broadcast action depends on the major version of Android device. Third-party apps (e.g., those downloaded from Google Play) can declare a protected broadcast in their manifest file, but this declaration will be ignored by the Android system when its manifest is parsed and no protection will be granted.
Who can send protected broadcasts?
When the Android system grants protection to a broadcast action that an authorized pre-installed app has declared, the only processes that can send the protection broadcast action are the app that declared the broadcast action to be protected and certain critical system processes executing with known hard-coded User IDs (UIDs) and persistent pre-installed apps. When the protected broadcasts are declared and recognized by the Android system, it will prevent third-party apps from sending these messages (e.g., “spoofing” them to appear as though they come from the system). Third-party apps will receive a permission denial (via a java.lang.SecurityException) when they try to send a broadcast Intent with an broadcast action that is protected.
The cause of the vulnerability stems from a divergence in behavior after Android 8 with regard to which apps can use the “protected-broadcast” primitive. In Android 8 and below, any pre-installed app on the device could successfully register broadcast actions as protected. However, with the release of Android 9, changes in Android Open Source Project (AOSP) source code restricted the successful use of the protected-broadcast primitive to only pre-installed apps residing in specific directories on the system. In the general case, apps that reside in the /system/framework directory and the priv-app directories (e.g., /system/priv-app) are allowed to register protected-broadcast actions since they are scanned with the SCAN_AS_PRIVILEGED scan flag, whereas apps that reside elsewhere cannot since they are scanned with the SCAN_AS_SYSTEM scan flag. Listing 2 illustrates this behavior for the system partition where the /system/priv-app directory is scanned with the SCAN_AS_PRIVILEGED scan flag and the /system/app directory is scanned using the SCAN_AS_SYSTEM scan flag. The scanning of apps occurs at system startup for the system to gather data about the user-installed and pre-installed apps on the device.
LISTING 2: Snippet from com/android/server/pm/PackageManagerService (line 2664) in the AOSP Android 10 release code the showing scan flags for the /system/priv-app and /system/app directories.
The protected-broadcast declarations for these apps that are not in a covered location are silently ignored by the system at runtime, leaving the actions unexpectedly unprotected as shown in Listing 3.
LISTING 3: Snippet from com/android/server/pm/PackageManagerService (line 11623) in the AOSP Android 10 release code showing protected broadcasts being silently ignored for non-privileged apps.
It appears that this change in behavior was not communicated to vendors and app developers. Pre-installed apps developed by vendors — Google included — continued to place pre-installed apps in directories where no protection would be granted for protected broadcasts, leaving them vulnerable to spoofing. For example, we observed a pre-installed app on various vendor devices that will execute arbitrary commands in its context (i.e., system UID) when it receives a broadcast Intent message with an embedded command and an action string that it declared as protected but was not protected due to its file system location. The vulnerability impact varies depending on the behavior of the apps declaring protected broadcasts that will not be protected.
Sample Confirmed-Exploitable Instances
OS Command Injection (system privileges): Nokia, Xiaomi, Meizu, Fairphone
Data Corruption and DoS: Pixel 3, Pixel 4
Exposure of Unique Device Identifiers: Multiple Vendors (pre-installed app from a certain chipset manufacturer)
Exposure of Sensitive System Log Information: Fairphone
- 05/08/2020: Initial disclosure to Android Security Team and affected vendors.
- 06/08/2020: Submitted vulnerability report to Google’s IssueTracker.
- 06/09/2020: Submission acknowledged.
- 06/18/2020: Google finished their initial assessment and ranked the severity as “High”.
- 08/21/2020: Google assigned CVE-2020-0391 for the vulnerability.
- 09/08/2020: Google changed the vulnerability status to “fixed” and awarded $5,000.
Ryan Johnson and Mohamed Elsabagh