Chrome Browser for Android Reveals Sensitive Hardware Information (partial fix available)

[NOTE: This is an expanded version of an earlier post from 2015 with updated information and fix from the vendor]

Summary

Google’s Chrome browser, WebView and Chrome Tabs for Android discloses information about the hardware model, firmware version and security patch level of the device on which it is running.  This also affects any Android applications that are using Chrome to render web content.

This information can be used for track users and fingerprint devices. It can also be used to determine which vulnerabilities a particular device is vulnerable to in order to target exploits.

While the vendor (Google) rejected the initial bug report in 2015, they had issued a partial fix in October 2018 for Chrome v70. The fix hides the firmware information while retaining the hardware model identifier. All prior versions are believed to be affected. Users are encouraged to upgrade to version 70 or later. Since this fix doesn’t apply to WebView usage, app developers should manually override the User Agent configuration in their apps.

Both the vendor and MITRE refused to issue a CVE number to track this issue since they do not consider it to be security related.

Background — Chrome and Headers

The Chrome browser for Android is provided by Google as the default browser in the Android operating system for mobile devices. It is based on the Chromium open source project. It also provides the WebView and Custom Tabs APIs for other applications running on the Android platform, to be used for rendering web content within the apps themselves without opening a separate browser window.

As all browsers, Chrome sends a variety of headers as part of every request to the web servers it communicates with. These headers are defined in the HTTP protocol, latest standard of which can be found in RFCs 7230, 7231, 7232, 7233, 7234 and 7235. Among these is the User-Agent header which is the subject of this post.

The “User-Agent” header in HTTP is defined by RFC 7231, section 5.5.3 as follows:

The “User-Agent” header field contains information about the user agent originating the request, which is often used by servers to help identify the scope of reported interoperability problems, to work around or tailor responses to avoid particular user agent limitations, and for analytics regarding browser or operating system use.

Background — Android Model and Build ID

Android devices have a build-in MODEL and BUILD ID, identifying the phone model and Android build. They are defined in in android.os.Build.MODEL and android.os.Build.ID properties. These are further defined in the Android Compatibility Definition document (section 3.2.2) as follows:

MODEL — A value chosen by the device implementer containing the name of the device as known to the end user. This SHOULD be the same name under which the device is marketed and sold to end users. There are no requirements on the specific form

ID — An identifier chosen by the device implementer to refer to a specific release, in human-readable format. This field can be the same as android.os.Build.VERSION.INCREMENTAL, but SHOULD be a value sufficiently meaningful for end users to distinguish between software builds. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0–9._-]+$”.

An attempt to map models to more descriptive names can be found on GitHub. A list of known build IDs for Nexus devices can be found here and here. Software build information easily maps to the security patch levels for many devices as seen on this Google page (based on date).

Vulnerability Details

As per Chrome docs, the Chrome for Android User Agent string includes the Android version number and build tag information. This information by default is also sent when applications use Android’s WebView and Chrome Custom Tabs APIs to serve web content in their own applications. While Android does offer ability to override these (via WebSettings.setUserAgent() in WebView), most applications choose not to do that to assure compatibility by relying on the default header.

Aggravating this issue is that the user agent header is sent always, with both HTTP and HTTPS requests, often by processes running in background. Also, unlike the desktop Chrome, on Android no extensions or overrides are possible to change the header other than the “Request Desktop Site” option on the browser itself for the current session.

For example of a user-agent header for Chrome Beta, on Nexus 6, with Android v5.1.1:

Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.34 Mobile Safari/537.36

When a user chooses the “Request Desktop Site” option, the user agent header sent is a generic Linux header instead. Here is an example for Chrome Beta, on Nexus 6, with Android v5.1.1:

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.34 Safari/537.36

The difference is that on mobile mode, the following string is extra:

Android 5.1.1; Nexus 6 Build/LYZ28K

The fact that it identifies the operating system and its version is not unique. This follows generally what many other browsers have been doing on desktop and mobile. It is the build tag that is the problem. As described above, the build tag identifies both the device name and its firmware build. For many devices, this can be used to identify not only the device itself, but also the carrier on which it is running and from that the country. It can also be used to determine which security patch level is on the device and which vulnerabilities the device is vulnerable to.

An example can be easily seen from the above where build LYZ28K can be easily identified as Nexus 6 running on T-Mobile, implying a US presence. It would also be trivial to use the build information to figure out the carrier based on which carriers are known to be at what build number. Build numbers are easily obtainable from manufacturer and phone carrier websites such as this one.

Replication Instructions

To replicate this issue or to check if your device is affected, you can visit any website that shows the user agent headers being sent by your browser such as or you can type “view user agent” in Google search. Alternatively, you can use JavaScript as follows on a site like JsFiddle:

document.write(navigator.userAgent)

Vendor Response and Mitigation

Bug # 494452 has been filed for this bug in 2015 against Chromium, and was rejected by the vendor as “WAI” – “Working As Intended”. However, in 2018, a new bug # 860229 was filed by the vendor along with a feature request, and this was partially fixed in October 2018 in Chrome v70 for Android by removing the firmware build information from the header. The device model number remains.

The fix only applies to the Chrome application itself, and not to the WebView implementation used by application developers as per the following explanation:

Does not apply the change to Android Web View as mandated by the Android Compatibility Definition Document.

Users are encouraged to update to Chrome v70 or later to fix this issue. Application authors should use WebSettings.setUserAgent() method to set the override the user agent. While many are reluctant to do so in order to lose compatibility, we would like to suggest the following approach of using the default user agent and erasing the build and model information in it.

Both the vendor and MITRE refused to issue a CVE number to track this issue since they do not consider it to be security related.

References

Chromium bugs: 494452 and 860229
Chromium feature request # 4558585463832576
Our talk about abusing this: originally given at BSides Philly 2016 – see here
Original blog post from 2015: see here

Credits

This advisory was written by Yakov Shafranovich.

Timeline

2015-05-31: Initial report submitted to the vendor
2017-06-03: Bug rejected by the vendor as “WAI” – “Working As Intended”
2015-09-30: Initial public disclosure published
2016-12-06: Public talk at BSides Philly
2018-07-04: New Chromium bug filed directly by the vendor
2018-08-10: Fix merged for Chrome
2018-10-29: Fixed version released
2018-12-25: Updated disclosure published

Wickr Me for Android Allowed Screen Capture

Wickr offers a suite of applications which provide secure instant messaging, voice and audio calls. The Android version of Wickr Me Messenger allowed screenshots to be taken by other apps on the device because FLAG_SECURE option wasn’t used.

To replicate, try the following:

  1. Open the application.
  2. Press Power + Volume Down at any sensitive screen and observe a screenshot being taken.

The underlying reason is because the app is not using “FLAG_SECURE” for such screens (more information on FLAG_SECURE can be found in our earlier blog post). By contrast, many Android apps with higher security requirements use it.

Vendor Response and Mitigation

This issue was reported in May 2016 against version 2.6.4.1, and was fixed in September 2018 in version 4.55.1. A bounty has been paid.

References:

  • Google Play Link to the app – see here
  • Our earlier blogpost about FLAG_SECURE on Android – see here

 

Sensitive Data Exposure via RSSI Broadcasts in Android OS [CVE-2018-9581]

[NOTE: This bug is part of a series of three related Android bugs with the same root cause: CVE-2018-9489, CVE-2018-9581 and CVE-2018-15835. A presentation covering all three bugs was given at BSides DE in the fall of 2018.]

Summary

System broadcasts by the Android operating system expose WiFi signal strength information (RSSI). Any application on the device can capture this information without additional permissions. Rogue applications can potentially use this information for indoor positioning in order to locate or track users within a small area near the WiFi router. Same issue also applies to the underlying Android API, although an additional permission is required.

All versions of Android are believed to be affected. The vendor (Google) has not yet fixed this issue, The vendor (Google) has fixed this issue in Android 10 / Q, however on Android 9 / P one of the two broadcast types is no longer revealing sensitive data (as part of the fix for CVE-2018-9489). The vendor assigned CVE-2018-9581 to track this issue. Further research is also recommended to see whether this is being exploited in the wild.

Background

Android is an open source operating system developed by Google for mobile phones and tablets. It is estimated that over two billion devices exist worldwide running Android. Applications on Android are usually segregated by the OS from each other and the OS itself. However, interaction between processes and/or the OS is still possible via several mechanisms.

In particular, Android provides the use of “Intents” as one of the ways for inter-process communication. A broadcast using an “Intent” allows an application or the OS to send a message system-wide which can be listened to by other applications. While functionality exists to restrict who is allowed to read such messages, application developers often neglect to implement these restrictions properly or mask sensitive data. This leads to a common vulnerability within Android applications where a malicious application running on the same device can spy on and capture messages being broadcast by other applications.

Another security mechanism present in the Android is permissions. These are safeguards designed to protect the privacy of users. Applications must explicitly request access to certain information or features via a special “uses-permission” tag in the application manifest (“AndroidManifest.xml”). Depending on the type of permission (“normal”, “dangerous”, etc”) the OS may display the permission information to the user during installation, or may prompt again during run-time. Some permissions can only be used by system applications and cannot be used by regular developers.

Screenshots of application permissions in Google Play and at run-time:

pic3 pic4 pic6

Vulnerability Details

The Android OS broadcasts the WiFi strength value (RSSI) system-wide on a regular basis. No special permission is needed to access this information. The RSSI values represent the relative strength of the signal being received by the device (higher = stronger) but are not directly correlated to the actual physical signal strength (dBm). This is exposed via two separate intents (“android.net.wifi.STATE_CHANGE” prior to Android 9; and “android.net.wifi.RSSI_CHANGED” in all versions of Android).

While applications can also access this information via the WifiManager, this normall requires the “ACCESS_WIFI_STATE” permission in the application manifest. For the WiFi RTT feature that is new to Android 9 and is used for similar geolocation, the “ACCESS_FINE_LOCATION” is required. But, when listening for system broadcasts, no such permissions are required allowing applications to capture this information without the knowledge of the user.

There are two separate security issues present:

  1. RSSI values are available via broadcasts, bypassing the permission check normally required (“ACCESS_WIFI_STATE”).
  2. RSSI values, via broadcasts or WifiManager can be used for indoor position without the special location permission.

Steps to Replicate by Regular Users

For Android device users, you can replicate these issues as follows:

  1. Install the “Internal Broadcasts Monitor” application developed by Vilius Kraujutis from Google Play.
  2.  Open the application and tap “Start” to monitor broadcasts.
  3.  Observe system broadcasts, specifically “android.net.wifi.STATE_CHANGE” (prior to Android 9) and “android.net.wifi.RSSI_CHANGED” (all versions).

Screenshot example:

screen1

Steps to Replicate by Developers via Code

To replicate this in code, create a Broadcast receiver and register it to receive the actions “android.net.wifi.STATE_CHANGE” (Android version v8.1 and below only) and “android.net.wifi.RSSI_CHANGED”.

Sample code appears below:

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle state) {
    IntentFilter filter = new IntentFilter();        
    filter.addAction(android.net.wifi.STATE_CHANGE);
    filter.addAction(android.net.wifi.RSSI_CHANGED);
    registerReceiver(receiver, filter);
}
    
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
    Log.d(intent.toString());
    ….
}
};

Testing Methodology

Our test used the following devices:

  • Pixel 2, running Android 8.1.0, patch level July 2018

  • Nexus 6P, running Android 8.1.0, patch level July 2018

  • Moto G4, running Android 7.0, patch level April 2018

  • Kindle Fire HD (8 gen), running Fire OS 5.6.10, which is forked from Android 5.1.1, updated April 2018

  • Router used was ASUS RT-N56U running the latest firmware

(We included the Kindle Fire to show that forks of Android inherit this functionality)

The following steps were performed:

  1. Install Broadcast Monitor app.
  2. Put the phone into airplane mode.
  3. Walk into the room.
  4. Turn off airplane mode (to trigger the RSSI broadcasts).
  5. Get the RSSI values from the following broadcasts:
    1. android.net.wifi.RSSI_CHANGE – newRssi value
    2. android.net.wifi.STATE_CHANGE – networkInfo / RSSI
  6. Repeat steps 3-4 for each room.

Results of the testing cleared showed that each room had a unique range of RSSI values when using a particular device.

Range of values collected during testing:

Room #

Pixel

Nexus

Moto G4

Kindle Fire

1

39 – 43

44

39 – 42

59 – 60

2

45 – 49

49 – 56

48 – 52

45 – 46

3

42 – 44

50

51 – 53

49 – 50

4

54 – 56

60 – 63

60 – 62

66

Vendor Response and Mitigation

The vendor (Google) classified this issue as Moderate and assigned CVE-2018-9581 to track this issue. No fix is available yet A fix is available on Android 10 / Q, however on Android 9 / P one of the two broadcast types (“android.net.wifi.STATE_CHANGE”) is no longer revealing sensitive data (as part of the fix for CVE-2018-9489). It is unknown if this issue is being exploited in the wild.

References

Android ID # 111698366
CVE ID: CVE-2018-9581
Google Bug # 111662293
GitHub: Internal Broadcasts Monitor
Presentation given at BSides DE: see here

Credits

We want to thank Vilius Kraujutis for developing the Internal Broadcasts Monitor application and making the source code available in GitHub.

We would like to thank multiple academic researchers who have previously published research locating users via RSSI values, including the following papers:

This advisory was written by Yakov Shafranovich.

Timeline

2018-03-28: Initial report submitted to the vendor re: CVE-2018-9489
2018-07-19: Separate report created for this issue as per vendor request; testing results provided
2018-07-20: Vendor response received – issue under investigation
2018-08-09: Provided results of Android 9 testing
2018-08-14: Draft advisory provided for review
2018-08-28: Asking about disclosure
2018-09-14: Vendor response receiving, still pending
2018-09-19: Pinged vendor
2018-09-21: Vendor response receiving, issue under investigation
2018-10-14: Notified vendor about upcoming talk
2018-10-15: Vendor response receiving, issue under investigation
2018-10-25: Asking for CVE assignment
2018-10-30: Asked again about CVE assignment
2018-11-01: Asked MITRE for CVE assigment
2018-11-05: CVE assigned by the vendor, notified MITRE
2018-11-06: Slides provided for review
2018-11-09: Public disclosure during a presentation at BSides DE
2018-11-11: Advisory published
2019-09-01: Fix listed as part of Android 10 fixes

Sensitive Data Exposure via Battery Information Broadcasts in Android OS [CVE-2018-15835]

[NOTE: This bug is part of a series of three related Android bugs with the same root cause: CVE-2018-9489, CVE-2018-9581 and CVE-2018-15835. A presentation covering all three bugs was given at BSides DE in the fall of 2018.]

Summary

System broadcasts by the Android operating system expose detailed information about the battery. Prior research has demonstrated that the same charging information – when exposed via browser battery status API – can be used to uniquely identify and track users. As the result, the battery API was removed from most browsers.

On Android however, this information is made available with high precision. Furthermore, no special permission is required by any application to access this information. As the result, this can be used to uniquely identify and track users across multiple apps. This was verified via limited testing to be possible within a short period of time.

Android versions 5.0 and later are affected. The vendor (Google) does not classify this bug as a security issue and has not released any fix plans. CVE-2018-15835 has been assigned by MITRE to track this issue. Further research is also recommended to see whether this is being exploited in the wild.

Background

Android is an open source operating system developed by Google for mobile phones and tablets. It is estimated that over two billion devices exist worldwide running Android. Applications on Android are usually segregated by the OS from each other and the OS itself. However, interaction between processes and/or the OS is still possible via several mechanisms.

In particular, Android provides the use of “Intents” as one of the ways for inter-process communication. A broadcast using an “Intent” allows an application or the OS to send a message system-wide which can be listened to by other applications. While functionality exists to restrict who is allowed to read such messages, application developers often neglect to implement these restrictions properly or mask sensitive data. This leads to a common vulnerability within Android applications where a malicious application running on the same device can spy on and capture messages being broadcast by other applications.

Another security mechanism present in the Android is permissions. These are safeguards designed to protect the privacy of users. Applications must explicitly request access to certain information or features via a special “uses-permission” tag in the application manifest (“AndroidManifest.xml”). Depending on the type of permission (“normal”, “dangerous”, etc”) the OS may display the permission information to the user during installation, or may prompt again during run-time. Some permissions can only be used by system applications and cannot be used by regular developers.

Screenshots of application permissions in Google Play and at run-time:

pic3 pic4 pic6

Vulnerability Details

The Android OS broadcasts information about the battery system-wide on a regular basis including charging level, voltage and temperature. No special permission is needed to access this information. This is exposed via the “android.intent.action.BATTERY_CHANGED” intent and is only available on Android 5.0 or later. The same information is also available via Android’s BatteryManager without a special permission.

A similar capability existed in browsers via W3C’s Battery Status API. However, extensive research by Łukasz Olejnik et al. showed that this API can be used to fingerprint devices, thus leading to tracking of users. Additional research revealed this being used in the wild by multiple websites, and the API was removed from most web browsers as the result.

In our limited testing we were able to distinguish devices located behind the same NAT device within a short period of time, thus leading to session re-spawning, but we were not yet able to replicate all the prior research regarding the HTML5 battery status API. This testing was based on the uniqueness of the current battery charging counter as being different across defines.

As the result, the same privacy issues that applied in the original Battery Status API should apply for Android applications resulting in applications being able to fingerprint and track users, and re-spawn session across multiple apps on the same device. Further research is needed to see if this is being actively exploited in the wild.

Steps to Replicate by Regular Users

For Android device users, you can replicate these issues as follows:

  1. Install the “Internal Broadcasts Monitor” application developed by Vilius Kraujutis from Google Play.
  2.  Open the application and tap “Start” to monitor broadcasts.
  3.  Observe system broadcasts, specifically “android.net.wifi.STATE_CHANGE” and “android.net.wifi.p2p.THIS_DEVICE_CHANGED”.

Screenshot example:

text

Steps to Replicate by Developers via Code

To replicate this in code, create a Broadcast receiver and register it to receive the action “android.intent.action.BATTERY_CHANGE”). Sample code appears below:

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle state) {
    IntentFilter filter = new IntentFilter();        
    filter.addAction(
	android.intent.action.BATTERY_CHANGE);
    registerReceiver(receiver, filter);
}
    
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
    Log.d(intent.toString());
    ….
}
};

Vendor Response and Mitigation

The vendor (Google) classified this issue as “NSBC” = “Not Security Bulletin Class” – meaning ““It was rated as not being a security vulnerability that would meet the severity bar for inclusion in an Android security bulletin.” CVE-2018-15835 was assigned by the vendor for tracking. No fix is yet available.

References

Android ID # 77286983
Android Power information: see here
CVE ID: CVE-2018-15835
Google Bug # 77236216
GitHub: Internal Broadcasts Monitor
Presentation given at BSides DE: see here

Credits

We want to thank Vilius Kraujutis for developing the Internal Broadcasts Monitor application and making the source code available in GitHub.

We would like to thank multiple academic researchers who have previously published research on the HTML5 Battery API including the following papers:

This advisory was written by Yakov Shafranovich.

Timeline

2018-03-28: Initial report submitted to the vendor
2018-03-29: Initial response from the vendor received – issue being investigated
2018-04-03: Vendor classified this as “NSBC”; follow-up communication
2018-04-04: Follow-up communication with the vendor
2018-05-02: Checking on status, response from vendor – issue still under investigation
2018-06-05: Checking status, no response from the vendor
2018-07-01: Checking status, no response from the vendor
2018-07-10: Response from vendor – issue still under investigation; pinged for a timeline
2018-07-12: Vendor still classifies this as “NSBC”; asking about disclosure
2018-08-09: Additional information sent to the vendor re: Android 9
2018-08-14: Draft advisory provided for review
2018-08-21: Vendor is looking in future improvements but the bug is still “NSBC”; communication regarding CVE assigned
2018-08-23: CVE assigned by MITRE
2018-08-28: Another draft of the advisory provided for review
2018-09-19: Pinged vendor for status
2018-10-14: Notified vendor regarding upcoming talk
2018-11-06: Slides provided for review
2018-11-09: Public disclosure during a presentation at BSides DE
2018-11-11: Advisory published

Microsoft Authenticator for Android Allows Screen Capture

Microsoft offers an application for Android called “Microsoft Authenticator” which is used to setup two-factor authentication (2FA). This application operates in two modes – one allows to generate standard OTP codes like many other apps (Google Authenticator, Authy, etc). The second mode allows a user to register with Azure’s Multi-Factor Authentication (MFA) service, and allows users to authenticate by tapping a prompt on their phone instead of entering an OTP code (similar to Google Prompt).

However, it looks like that the application still allows screenshots to be taken. This is true for setting up the OTP with a manual seed, viewing generated OTP codes, and entering a username + password when setting up Azure MFA. The implication is that if a user’s device ends up running a rogue app, that app can capture the initial OTP seed (if entered manually), the initial username and password for MFA, as well as all generated OTP codes as they are shown by the app, and thus break two factor authentication.

To replicate, try the following:

  1. Open the application.
  2. Setup a new OTP code by adding “other account” + a random seed, and view codes. Alternative, try to sign-up for MFA with a personal account.
  3. Press Power + Volume Down at any sensitive screen and observe a screenshot being taken.

The underlying reason is because the app is not using “FLAG_SECURE” for such screens (more information on FLAG_SECURE can be found in our earlier blog post). By contrast, many Android apps with higher security requirements use it.

Vendor Response

We filed a bug report with the vendor (Microsoft) and here is their response:

Our team assessed the issue, and this does not meet the bar for servicing. We have informed the product team about this issue. MSRC is closing the case.

As for CVE, since there is no fix going for this, we will not be assigning any CVE for this issue.

References:

  • Azure Multi-Factor Authentication – see docs here
  • Google Play Link to the app – see here
  • Google Prompt for Android – see here
  • MSRC Case # 46793
  • Our earlier blogpost about FLAG_SECURE on Android – see here

 

Sensitive Data Exposure via WiFi Broadcasts in Android OS [CVE-2018-9489]

[NOTE: This bug is part of a series of three related Android bugs with the same root cause: CVE-2018-9489, CVE-2018-9581 and CVE-2018-15835. A presentation covering all three bugs was given at BSides DE in the fall of 2018.]

Summary

System broadcasts by Android OS expose information about the user’s device to all applications running on the device. This includes the WiFi network name, BSSID, local IP addresses, DNS server information and the MAC address. Some of this information (MAC address) is no longer available via APIs on Android 6 and higher, and extra permissions are normally required to access the rest of this information. However, by listening to these broadcasts, any application on the device can capture this information thus bypassing any permission checks and existing mitigations.

Because MAC addresses do not change and are tied to hardware, this can be used to uniquely identify and track any Android device even when MAC address randomization is used. The network name and BSSID can be used to geolocate users via a lookup against a database of BSSID such as WiGLE or SkyHook. Other networking information can be used by rogue apps to further explore and attack the local WiFi network.

All versions of Android running on all devices are believed to be affected including forks (such as Amazon’s FireOS for the Kindle). The vendor (Google) fixed these issues in Android P / 9 but does not plan to fix older versions. Users are encouraged to upgrade to Android P / 9 or later. CVE-2018-9489 has been assigned by the vendor to track this issue. Further research is also recommended to determine whether this is being exploited in the wild.

Amazon plans to address this issue as their transition devices to a new version of FireOS.

Background

Android is an open source operating system developed by Google for mobile phones and tablets. It is estimated that over two billion devices exist worldwide running Android. Applications on Android are usually segregated by the OS from each other and the OS itself. However, interaction between processes and/or the OS is still possible via several mechanisms.

In particular, Android provides the use of “Intents” as one of the ways for inter-process communication. A broadcast using an “Intent” allows an application or the OS to send a message system-wide which can be listened to by other applications. While functionality exists to restrict who is allowed to read such messages, application developers often neglect to implement these restrictions properly or mask sensitive data. This leads to a common vulnerability within Android applications where a malicious application running on the same device can spy on and capture messages being broadcast by other applications.

Another security mechanism present in the Android is permissions. These are safeguards designed to protect the privacy of users. Applications must explicitly request access to certain information or features via a special “uses-permission” tag in the application manifest (“AndroidManifest.xml”). Depending on the type of permission (“normal”, “dangerous”, etc”) the OS may display the permission information to the user during installation, or may prompt again during run-time. Some permissions can only be used by system applications and cannot be used by regular developers.

Screenshots of application permissions in Google Play and at run-time:

pic3 pic4 pic6

Vulnerability Details

Android OS broadcasts information about the WiFi connection and the WiFi network interface on a regular basis using two intents: WifiManager’s NETWORK_STATE_CHANGED_ACTION and WifiP2pManager’s WIFI_P2P_THIS_DEVICE_CHANGED_ACTION. This information includes the MAC address of the device, the BSSID and network name of the WiFi access point, and various networking information such as the local IP range, gateway IP and DNS server addresses. This information is available to all applications running on the user’s device.

While applications can also access this information via the WifiManager, this normally requires the “ACCESS_WIFI_STATE” permission in the application manifest. Geolocation via WiFi normally requires the “ACCESS_FINE_LOCATION” or “ACCESS_COARSE_LOCATION” permissions. Also, on Android versions 6.0 and later, the real MAC address of the device is no longer available via APIs and will always return the address “02:00:00:00:00:00”. However, an application listening for system broadcasts does not need these permissions thus allowing this information to be captured without the knowledge of the user and the real MAC address being captured even on Android 6 or higher.

Screenshot of an app trying to obtain MAC address in Android 7.0:

pic7

We performed testing using a test farm of mobile device ranging across multiple types of hardware and Android versions. All devices and versions of Android tested confirmed this behavior, although some some devices do not display the real MAC address in the “NETWORK_STATE_CHANGED_ACTION” intent but they still do within the “WIFI_P2P_THIS_DEVICE_CHANGED_ACTION” intent. We also tested at least one fork (Amazon’s FireOS for the Kindle) and those devices displayed the same behavior.

Because MAC addresses do not change and are tied to hardware, this can be used to uniquely identify and track any Android device even when MAC address randomization is used. The network name and/or BSSID can be used to geolocate users via a lookup against a database like WiGLE or SkyHook. Other networking information can be used by rogue apps to further explore and attack the local WiFi network.

Steps to Replicate by Regular Users

For Android device users, you can replicate these issues as follows:

  1. Install the “Internal Broadcasts Monitor” application developed by Vilius Kraujutis from Google Play.
  2.  Open the application and tap “Start” to monitor broadcasts.
  3.  Observe system broadcasts, specifically “android.net.wifi.STATE_CHANGE” and “android.net.wifi.p2p.THIS_DEVICE_CHANGED”.

Screenshot examples:

pic1  pic2

Steps to Replicate by Developers via Code

To replicate this in code, create a Broadcast receiver and register it to receive these actions (“android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION” and “android.net.wifi.WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION”). Sample code appears below:

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle state) {
    IntentFilter filter = new IntentFilter();        
    filter.addAction(
	android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION);
    filter.addAction(
	android.net.wifi.WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
    registerReceiver(receiver, filter);
}
    
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
    Log.d(intent.toString());
    ….
}
};

Vendor Response and Mitigation

The vendor (Google) classified this issue as Moderate, and provided a fix in Android P / 9. Because this would be a breaking API change, the vendor does not plan to fix prior versions of Android. Users are encouraged to upgrade to Android P / 9 or later.

Amazon has responded regarding their Android fork (FireOS) as follows:

We are planning to address the issue as devices transition to the new version of Fire OS

References

Android ID # 77286245
CVE ID: CVE-2018-9489
Google Bug # 77236217
GitHub: Internal Broadcasts Monitor

Bounty Information

This bug qualified for a bounty under the terms of the Google’s Android Rewards bounty program, and a bounty payment has been received.

Credits

We want to thank Vilius Kraujutis for developing the Internal Broadcasts Monitor application and making the source code available in GitHub.

This advisory was written by Yakov Shafranovich.

Timeline

2018-03-28: Initial report submitted to the vendor
2018-03-29: Initial response from the vendor received – issue being investigated
2018-04-03: Follow-up communication with the vendor
2018-04-04: Follow-up communication with the vendor
2018-05-02: Checking on status, response from vendor – issue still under investigation
2018-06-05: Checking status, no response from the vendor
2018-07-01: Checking status, no response from the vendor
2018-07-10: Response from vendor – issue still under investigation; pinged for a timeline
2018-07-12: Pinged the vendor regarding CVE assignment and disclosure plans
2018-07-13: Information about the fix provided by the vendor; follow-up communication
2018-07-14: Additional information provided to the vendor
2018-07-17: Additional information provided to the vendor
2018-07-19: Additional information provided to the vendor, response received
2018-08-09: Fix confirmed
2018-08-16: Initial draft of the advisory provided to the vendor for review
2018-08-21: Follow-up communication with the vendor
2018-08-22: CVE assigned by the vendor, follow-up communication with the vendor
2018-08-23: Final version of the advisory provided to the vendor for review
2018-08-29: Public disclosure / advisory published; added information about Android forks
2018-09-05: Added Amazon’s response
2018-10-22: Added bounty information
2018-11-11: Added links to related bugs and presentation
2019-09-01: Fix listed as part of Android 10 fixes

Media Coverage

Advisory: Crashing Facebook Messenger for Android with an MITM attack

Summary

Facebook Messenger for Android can be crashed via the application’s status check. This can be exploited by an MITM attacker via intercepting that call and returning a large amount of data. This happens because this status check is not done over SSL and the application did not contain logic for checking if the returned data is very large.

The vendor has no immediate plans to fix this issue.

Vulnerability Details

Facebook Messenger for Android is a messaging application provided by Facebook. While monitoring network traffic of a test device running Android, we observed that the application made network calls for checking server status. This call was done over HTTP without the use of SSL / TLS. Example URL:

http://portal.fb.com/mobile/status.php

We were successful in crashing the application by injecting a large packet because the application doesn’t handle large data coming back correctly and doesn’t use SSL for this call.

It is also important to note this would allow someone to block Messenger from being used but without the users realizing they are being blocked, since they will attribute the app crashing to a bug rather than a block.

Captured traffic:

test_now

Steps To Replicate (on Ubuntu 18.04)

1. Install the application on the Android device.

2. Install dnsmasq and NGINX on the Linux host:

sudo apt-get install dnsmasq nginx

3. Modify the /etc/hosts file to add the following entry to map PIA’s domain name to the Linux host:

192.168.1.x portal.fb.com

4. Configure /etc/dnsmasq.conf file to listen on the IP and restart DNSMASQ

listen-address=192.168.1.x
sudo /etc/init.d/dnsmasq restart

5. Use mkdir and fallocate to create a large server file in “/var/www/html/” (you may need to use sudo):

cd /var/www/html
mkdir mobile
cd mobile
fallocate -l 2.5G status.php

6. Setup a WiFi access point and set the DNS server setting on the access point to the Linux computer (“192.168.1.x”)

6. Connect the test device to the access point – Android will resolve now DNS against the Linux computer.

7. Re-open the app and try to activate with a phone number. Observe the crash – note that the application and launcher crashes but not the device itself

All testing was done on v169.0.0.27.76 of the Android application using a Linux host running Ubuntu v18.04 and Android test devices running Android v7 and v8.1.

Vendor Response and Mitigation

The vendor doesn’t consider this to be a security issue and doesn’t have immediate plans to fix it:

After talking to the product team, we’ve determined that the crash is due to OOM and the security risk here is not significant enough to qualify for a bounty. The impact here is a denial of service on very specific users on the attacker’s wifi network, which arguably can be done via other local network attacks which we ultimately cannot control. While we agree that this is a software bug and we may consider making changes in the future to prevent this behavior, this issue does not qualify as a part of our bounty program.

References

CVE-ID: no CVE assigned
CWE: CWE-400 – Uncontrolled Resource Consumption (‘Resource Exhaustion’)

Credits

Text of the advisory written by Yakov Shafranovich.

Timeline

2018-06-05: Initial email to the vendor as part of another issue; POC sent
2018-06-12: Initial report triaged by vendor and sent to product team
2018-06-20: Vendor response received
2018-06-25: Draft advisory provided to vendor for review
2018-07-09: Public disclosure

Android OS Didn’t use FLAG_SECURE for Sensitive Settings [CVE-2017-13243]

Summary

Android OS did not use the FLAG_SECURE flag for sensitive settings, potentially exposing sensitive data to other applications on the same device with the screen capture permissions. The vendor (Google) fixed this issue in 2018-02-01 Pixel security update. Google has assigned CVE-2017-13243 to track this issue.

Details

Android OS is a mobile operating systems for phones and tablets developed by Google. The OS has multiple screens where sensitive information maybe shown such as the device lock screen, passwords in the WiFi settings, pairing codes for Bluetooth, etc.

FLAG_SECURE is a special flag available to Android developers that prevents a particular screen within an application from being seen by other application with screen capture permissions, having screenshots taken by the user, or have the screen captured in the “Recent Apps” portion of Android OS. We have published an extensive post last year discussing this feature is and what it does.

During our testing of various Google mobile applications, we found that the lock screen, password entry screen for WiFi, and the screen for entering pairing codes for Bluetooth devices did not use FLAG_SECURE to prevent other applications for capturing that information. By contrast other Google applications like Android Pay and Google Wallet use this flag to prevent capture of sensitive information. Exploiting this bug requires user cooperation in installing a malicious app and activating the actual screen capture process, thus the likelihood of exploitation is low.

To reproduce:
1. Lock the device, OR go to WiFi settings and try to add a network, or try to pair a Bluetooth device.
2. Press Power and volume down to capture screenshot.
3. Confirm that a screenshot can be taken.

All testing was done on Android 7.1.2, security patch level of May 5th, 2017, on Nexus 6P. Vulnerable versions of Android include: 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2 and 8.0.

Vendor Response

This issue was responsibly reported to the vendor and was fixed in the 2018-02-01 Pixel bulletin. The vendor assigned CVE-2017-13243 to track this issue.

Bounty Information

This issue satisfied the requirements of the Android Security Rewards program and a bounty was paid.

References

Android ID # A-38258991
CVE ID: CVE-2017-13243
CVSS scores: 7.5 (CVSS v3.0) / 5.0 (CVSS v2.0)
Google Bug # 38254822
Google Pixel Bulletin: 2018-02-1

Credits

Advisory written by Yakov Shafranovich.

Timeline

2017-05-12: Initial report to the vendor
2017-06-15: Follow-up information sent to the vendor
2017-06-19: Follow-up communication with the vendor
2018-01-02: Vendor communicates plan to patch this issue
2018-01-29: Bounty reward issued
2018-02-01: Vendor publishes a patch for this issue
2018-05-24: Public disclosure / advisory published

Content Injection in Samsung Display Solutions Application for Android [CVE-2018-6019]

Summary

Samsung Display Solutions App for Android did not use encryption (SSL) for information transmission, thus allowing an MITM attacker to inject their own content into the app. The vendor fixed this issue and users should install the latest version (3.02 or above). MITRE has assigned CVE-2018-6019 to track this issue.

Details

Samsung makes an Android application that allows users to browse B2B content related to Samsung’s display products. While performing network level testing, we discovered that the content shown in the app was loaded via server calls made by the application without any kind of encryption (SSL). This allowed an MITM attacker to inject their own content into the app.

To observe the issue on v3.01:

  1. Install the application on the device.
  2. Setup an MITM proxy but do not install the SSL certificate on the device (we used PacketCapture).
  3. Start the proxy. At this point all network traffic will be going through the proxy with the SSL traffic being encrypted by a self-signed certificate which is not trusted by the device.
  4. Open the app.
  5. Go back to the proxy and observe captured traffic.

All testing was done on Android 7 and application version 3.01. Network captures were performed using an on-device proxy (PacketCapture) without a trusted SSL certificate.

Screenshots of captured traffic attached:

Screenshot_20171210-193610 Screenshot_20171210-193622 Screenshot_20171210-193627 Screenshot_20171210-193633

Vendor Response

The vendor fixed this issue and users should install the latest version (3.02 or above).

References

CVE ID: CVE-2018-6019
Google Play Link: Google Play Store

Bounty Information

This issue was originally reported to the Samsung Mobile Security Bounty Program but was deemed to be out of scope. However, after being transferred to the Display Solutions team, this issue qualified for the Samsung TV Bounty Program.

Credits

Advisory written by Yakov Shafranovich.

Timeline

2017-09-09: Reported to Samsung Mobile Security bounty program
2017-09-09: Automated response from the vendor received
2017-10-18: Engineer assigned to the issue
2017-11-19: Deemed out of scope; reply sent
2017-11-25: Vendor requests additional information; reply sent
2017-11-27: Issue rejected, public disclosure requested
2017-12-06: Reply from vendor received, additional information requested; reply sent
2017-12-07: Additional information requested by the vendor
2017-12-09: Reply sent with screenshots
2018-01-08: Vendor accepts the issue as in scope, and plans remediation
2018-01-11: Issue transferred to the Samsung TV bounty program
2018-01-14: Fixed version released
2018-01-22: CVE requested and received from MITRE
2018-02-14: Vendor requests confirmation of the fix, fix confirmed and reply sent
2018-02-25: Draft advisory sent to vendor for review; bounty payment received
2018-03-01: Public disclosure