Upcoming Advisory for Apache Tomcat Vulnerability – CVE-2019-0232

We will be releasing an advisory on a security vulnerability that was reported to the Apache Software Foundation, specifically in Apache Tomcat. This issue is being tracked under CVE-2019-0232. The issue was discovered by Nightwatch Cybersecurity Research and reported to Apache via the EU FOSSA-2 project, hosted by Intrigri.

Related links:

  • Apache advisory – here
  • CVE entry – here

Third Party Android App Storing Facebook Data Insecurely (Facebook Data Abuse Program)

Summary

A third-party Android application with Facebook API access was found to be copying user data into storage outside of Facebook, and storing it insecurely in two separate locations. This issue was reported to Facebook via their Data Abuse Bounty program and the insecure storage locations have been secured on November 12th, 2018. The Facebook app associated with this application has been removed from the Facebook platform but the Android application remains available in Google’s Play Store. The number of affected users is unknown. [ADDED: 02/15/2019 – Google has been notified].

Background

In April 2018, FaceBook announced a new Data Abuse Bounty program that rewards “people with first-hand knowledge and proof of cases where a Facebook platform app collects and transfers people’s data to another party to be sold, stolen or used for scams or political influence“.

In September 2018, we found an Android application in the Google Play store that purports to provide additional functionality to Facebook users that is not available through the platform. At the time of writing, the application had more than 1,000,000 downloads. After downloading the application, and examining it using JADX, we found that the application was using Facebook APIs to access data for the logged in user and copying to several storage locations outside of Facebook. Upon further examination, it was clear that at least two of such locations (a Firebase database and an API server) were making this data available without any authentication and without HTTPS. This would allow an attacker to mass download the user data accumulated by the application from its users.

We do not know for sure how many users have been impacted or exposed, but one of the databases accessed contained over 1,000,000 records. [ADDED: 02/15/2019 – The application purported to provide additional statistical information about the logged-in user’s Facebook account. There is a privacy policy within the application but it is ambiguous about the transfer of data].

Issue #1 – Storing user data in an public Firebase database

During our examination of the application, we located a Firebase database that the application was communicating with. The database was configured in test mode, which allowed anonymous public access by visiting the URL of “https://DATABASE.firebaseio.com/.json“. As seen in the attached screenshot, the database contained data obtained from Facebook. Aside from confirming the initial permission issue, we did not access or explore this database any further.

Screenshot:

likulator1

Issue #2 – Storing user data in a non-SSL server without authentication

During our examination of application, it become clear that the server that the application was communicating with, did not use SSL and was being accessed without authentication. As seen below, this would allow an attacker to download the data collected by the application from Facebook via a regular browser as well as spy on any connections between the application and the server. Aside from confirming the initial permission issue, we did not access or explore this database any further.

likulator2

likulator3

Vendor Response and Mitigation

We contacted the Facebook Data Abuse Bounty program but did not contact the vendor directly. After Facebook completed its review, the two insecure locations have been secured on November 12th, 2018. The Facebook app associated with this application has been removed from the Facebook platform but the Android application remains available in Google’s Play Store. [ADDED: 02/15/2019 – Google has been notified].

This discovery qualified under the terms of the Facebook Data Abuse Bounty Program and a bounty payment has been received.

References

Facebook report # 10101718616795015
Google reference # 8-7487000025062

Credits

This advisory was written by Yakov Shafranovich.

Timeline

2018-09-17: Initial report submitted to Facebook, initial response received
2018-11-12: Issued fixed
2018-11-27: Bounty decision received; sent disclosure request
2018-11-30: Facebook asked for additional time before disclosure
2019-01-15: Investigation has been finalized, FaceBook asked for a copy of the disclosure
2019-02-03: Draft disclosure shared for review
2019-02-14: Public Disclosure
2019-02-15: Minor updates; notification sent to Google

Content Injection in Amazon Kindle’s FireOS [CVE-2019-7399]

Summary

The FireOS operating system provided by Amazon for Fire tablet devices can be injected with malicious content by an MITM attacker. An attacker can also capture the serial number of the device. The root cause is lack of HTTPS for legal content (terms of use and privacy policy) within the settings section.

The issue was discovered in FireOS v5.3.6.3 and fixed by the vendor in v5.3.6.4 that was released in November 2018. Devices will automatically update to the latest version. CVE-2019-7399 has been assigned by MITRE to track this issue.

Vulnerability Details

FireOS is an operating system provided by Amazon for the Fire tablet devices.  It is a customized fork of Android. While monitoring network traffic on a test device, we observed that several calls from the settings section (terms of use and privacy policy) are done without HTTPS and can be injected with malicious content by an MITM attacker. It is also possible for the attacker to observe this traffic and capture the serial number (DSN) of the device.

Screenshots of the captured traffic:

Screenshot_2018-09-03-13-11-20 Screenshot_2018-09-03-13-11-26

Steps To Replicate (on Ubuntu 18.04)

1. Install the application on the Android device but do not start it.

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 the domain name to the Linux host:

192.168.1.x www.kindle.com
192.168.1.x kindle.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. Add a file with malicious content (you may need to use sudo):

cd /var/www/html
mkdir support
echo powned >support/privacy
echo powned >support/terms

6. Modify the settings on the Kindle device to static, set DNS to point to “192.168.1.x”. AT THIS POINT – the Kindle device will resolve DNS against the Linux computer and serve the large servers file

7. Tap “Settings”, “Legal and Compliance”, and tap either “Terms of Use” or “Privacy”. Observe injected content.

Vendor Response and Mitigation

The issue was discovered in FireOS v5.3.6.3 and fixed by the vendor in v5.3.6.4 that was released in November 2018. Devices will automatically update to the latest version. MITRE assigned CVE-2019-7399 to track this issue.

References

Amazon tracking # PO135449968
CVE-ID: CVE-2019-7399

Credits

Text of the advisory written by Yakov Shafranovich.

Timeline

2018-09-03: Initial report to the vendor
2018-09-04: Report triaged and being reviewed by the vendor
2018-09-17: Communication from the vendor, issue still being reviewed
2019-01-10: Fix confirmed, communication regarding disclosure
2019-01-30: Vendor pinged about CVE assignment
2019-02-03: Draft advisory sent for review
2019-02-04: CVE issued by MITRE
2019-02-07: Public disclosure; minor syntax updates

Thoughts on the MSI/JAR Authenticode Bypass

Earlier today, Google’s VirusTotal published a blog post about a new way to bypass code signing in Windows via JAR files:

Microsoft Windows keeps the Authenticode signature valid after appending any content to the end of Windows Installer (.MSI) files signed by any software developer. This behaviour can be exploited by attackers to bypass some security solutions that rely on Microsoft Windows code signing to decide if files are trusted. The scenario is especially dangerous when the appended code is a malicious JAR because the resulting file has a valid signature according to Microsoft Windows and the malware can be directly executed by Java.

In short, an attacker can append a malicious JAR to a MSI file signed by a trusted software developer (like Microsoft Corporation, Google Inc. or any other well-known developer), and the resulting file can be renamed with the .jar extension and will have a valid signature according Microsoft Windows. For example, via the command “copy /b signed.msi + malicious.jar signed_malicious.jar”. The victim can be infected with just a double-click in such a file.

Here are some quick thoughts from our research team – note that we were not involved in this effort and have no insider knowledge. This is entirely based on public sources.

How can ZIP and EXE files be combined?

First of all, how is it possible that the same exact file can be executable both by Windows and Java? The trick lies in how Windows executable files work – as described in Microsoft’s documentation. Basically, the OS reads the file from the beginning, looking at the magic value of “MZ” followed by headers, then followed by the file content. We are going to assume that there is a table in the file that tells the reader how long each segment is, and therefore it is possible to append arbitrary data to the end of the file without it breaking.

A JAR file, however, is essentially a ZIP file. ZIP files have their index or central directory in the end of the file, and it is possible to prepend data in the beginning of the file and that file still being valid. That means that you can combine a Windows executable that is read from the beginning and rely on its headers and tables to tell the reader where to stop, and do the same for the ZIP content in the end of the file. Both files remain valid, while combined together. Also, while the example provided by VirusTotal is a JAR file, the same trick would work for other ZIP-based formats like Microsoft Office (DOCX/XSLX/etc), OpenOffice (ODT/ODS/etc), etc. Of course, this assumes that the software reading these files goes to the central directory of the ZIP and doesn’t check the magic value in the beginning.

Here is an modified example of PE files from Wikipedia, and a ZIP file example from OASIS, showing the direction in which file content is read:

revengpefile                  zip

Combined together:

revengpefile

zip

What is Microsoft Code Signing / Authenticode?

As per the original blog post and other technical documentation from Microsoft, the code signing in question is Authenticode which is used by Microsoft for Windows executables, drivers, and other files. The purpose it to make sure the file originated from a trusted publisher. There is also a command line tool included in Windows called “SignTool” which is used for signing and verifying files.

The way code signing works is described in a Microsoft technical document here. It is essentially a digital signature using PCKS7 and special X.509 certificates (code signing certificates issued by CAs). It is connected to the same PKI infrastructure as SSL certificates with some additional checks by CAs when issuing the certificate (not at sign time). Like all other digital signatures, it is essentially some sort of a hash signed by a private key of the holder of the certificate which is then verified by the public key in the X.509 certificate. The certificate itself is verified against public PKI infrastructure just like SSL.

Example appears below (from Microsoft documentation):screen shot 2019-01-16 at 8.00.15 pm

Bypassing Code Signing

In a standard digital signature scenario such as PGP or S/MIME, the entire content of the message is hashed to produce a message digest using a function like SHA. That hash is then digitally signed using the sender’s private key. Note that the entire message is hashed – this allowing the receiver to check if it was modified or not, not just bits and pieces.

One of the common refrains in security is “never roll your own crypto”, which in this case includes choosing what to hash. In the case of Authenticate, it appears that the file hash does not cover the entire file. As described in this document, information in the end of the file (after the second “remaining content” above) ARE NOT included in the hash (emphasis added):

Information past of the end of the last section. The area past the last section (defined by highest offset) is not hashed. This area commonly contains debug information. Debug information can generally be considered advisory to debuggers; it does not affect the actual integrity of the executable program. It is quite literally possible to remove debug information from an image after a product has been delivered and not affect the functionality of the program. In fact, this is sometimes done as a disk-saving measure. It is worth noting that debug information contained within the specified sections of the PE Image cannot be removed without invaliding the Authenticode signature.

Implications

This means that it is trivial to simply append another file like a JAR to the end of another digitally signed file, then rename it a JAR and have the resulting file look valid in Windows since the digital signature check will stop before reading the content of the JAR file. At the same time, the file will be executable by Java since it will read from the end ignoring any of the signed content appearing in the beginning. The same would apply for other ZIP based formats like Microsoft Word and this may allow an attacker to send a malicious document while masquerading it as a legit one. Additionally it appears from the blog post that some A/V and security products use the Authenticode signature as a shortcut to validate files so they don’t need to scan them.

Another possible use of this technique is to make attribution murky since some analysts may take the Authenticode signature at face value and not realize that the malware inside may not be from the publisher that signed the file.

An additional idea would be to use this trick to exfiltrate data out of an organization by putting the extra data in the end of the file. This assumes that the DLP and similar tools monitoring outbound traffic rely on the Authenticode signature as well.

Microsoft’s code signing method isn’t the only one that exists. Similar methods exists for Java, Adobe AIR, Android, MacOS, Debian, etc. Further research is needed to see if similar issues exist in other code signing schemes.

(Written by Yakov Shafranovich)

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, 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, 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

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

Speaking @BSidesDE This Friday on Android Privacy Bugs (CVE-2018-9489, CVE-2018-9581 and CVE-2018-15835)

We will be giving a talk this Friday (11/09/2018) at 10:30 am at BSides Delaware conference in Newark, Delaware. The talk will be given in Room A112 (Track 2). The talk is titled “A Tale of Three Brothers: Three Android Privacy Bugs”, and will cover three bugs in Android OS listed below. Two of them will be disclosed publicly for the first time during the talk. Slides, videos and full advisories should be posted next week.

Bugs covered:

UPDATED: Slides and video added: