[Blog post here: https://wwws.nightwatchcybersecurity.com/2018/08/29/sensitive-data-exposure-via-wifi-broadcasts-in-android-os-cve-2018-9489/] TITLE Sensitive Data Exposure via WiFi Broadcasts in Android OS [CVE-2018-9489] SUMMARY System broadcasts by Android OS expose information about the users 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 Amazons 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. 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. VULNERABILITY DETAILS Android OS broadcasts information about the WiFi connection and the WiFi network interface on a regular basis using two intents: WifiManagers NETWORK_STATE_CHANGED_ACTION and WifiP2pManagers 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 users 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. 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 (Amazons 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 [https://play.google.com/store/apps/details?id=lt.andro.broadcastlogger]. 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. 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 fixed these issues 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. REFERENCES Android ID # 77286245 CVE ID: CVE-2018-9489 Google Bug # 77236217 GitHub: Internal Broadcasts Monitor [https://github.com/ViliusKraujutis/AndroidBroadcastsMonitor] 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