DID YOU KNOW? By 2016, 20% of enterprise BYOD programs will fail due to deployment of mobile device management (MDM) measures that are too restrictive.

Recently, I came across a bug in Android’s Device Administrator code and questioning whether it can be classified as a security vulnerability and if/how it can be exploited. This resulted in the CVE-2014-0900. Below (as promised in my OBAD analysis blog entry), I will share the vulnerability in Android OS code and describe how it can be exploited to give a false sense of control and authority to an affected MDM Android app.

What this means is that the MDM app on your Android device would have a false sense that it can wipe data, lock the device, enforce password quality policies and so on and will therefore let you access corporate email, data or intranet resources while in reality it would have no such control and you can continue to use your device without any of the corporate restrictions. We know you did not like to type those long passwords and would rather have no password and no lock screen. After all, don’t you want to share your personal data with everyone?

I have verified that two commercially used MDM solutions are affected by this. It is very likely that most MDM apps (if not all) are affected, too. Below, I will share the vulnerability and exploitation details. If you are not interested in technical details, you can jump to the end to read about the mitigation possibilities and lessons learned from this that will help you in your BYOD strategy as a solutions provider and as a buyer. If you are responsible for developing an MDM app, we recommend that you take a look under the section titled Mitigation to determine whether your product is affected by this and how to mitigate the risk.

Disclaimer: For your personal safety and job security, we strongly discourage trying this on your BYOD-approved device.

 

The Details

The vulnerability exists in private void handlePackagesChanged(int userHandle) methods of com.android.server.DevicePolicyManagerService for versions below android-4.4.1_r1.

DevicePolicyManagerService class maintains two data structures to track the active device admins on a device:

final HashMap mAdminMap = new HashMap(); final ArrayList mAdminList = new ArrayList();

However, in handlePackagesChanged mAdminList is updated, but mAdminMap is not updated to remove the admin from the hash map.

private void handlePackagesChanged(int userHandle) { ... for (int i = policy.mAdminList.size() - 1; i >= 0; i--) { ActiveAdmin aa = policy.mAdminList.get(i); try { if (pm.getPackageInfo(aa.info.getPackageName(), 0, userHandle) == null || pm.getReceiverInfo(aa.info.getComponent(), 0, userHandle) == null) { removed = true; policy.mAdminList.remove(i); }

Interesting. Let’s see where in code mAdminMap is consulted but mAdminList is not. We find that getActiveAdminUncheckedLocked and getActiveAdminForCallerLocked(ComponentName who, int reqPolicy) with “who” parameter being non null relies on mAdminMap only, and getActiveAdminUncheckedLocked is used by isAdminActive of android.app.admin.DevicePolicyManager. So an MDM app that uses this isAdminActive method to check whether its DeviceAdministrator is active can potentially be deceived. Here is how:

To demonstrate this, we will use Lookout’s free anti-virus as an example. Note that this is just for demonstration purposes since this is what I had on my phone. This is a benign bypass for demonstration/verification only, and this app is different from the commercial MDM solution from Lookout. The idea is that AV apps typically have features for extra protection (such as remote wiping of a device) if you allow them to enable their Device Administrator component. The AV app would check whether its device administrator is enabled and would show status on their dashboard. We will demonstrate how you can trick it into getting this wrong.

Step 1

The first step is to get hold of the apk package for Lookout anti-virus (hint: install on your phone, and get the apk using adb pull) and to extract the AndroidManifest.xml file. If you are not familiar with how to do this, you can find some hints in my earlier post, DIY: Android Malware Analysis – Taking Apart OBAD . Look at the AndroidManifest.xml file, and take note of two things: The package name for the app and the name of the DeviceAdministrator component. You can read up on the previously linked reference about DeviceAdministrator to learn how to create your own DeviceAdministrator.

Go ahead and create an Android project with the same package name and same name for the DeviceAdministrator component as the one you are trying to deceive. The special thing you need to do with your DeviceAdministrator is to execute the following code once it is enabled as a device administrator on the device:

pm.setComponentEnabledSetting(this.getWho(context), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

I added this in the onEnabled method of my DeviceAdministrator. What this will do is disable my DeviceAdministrator component after it has been given the rights of a DeviceAdministrator, resulting in the vulnerable code in handlePackagesChanged (mentioned above) being executed. Note that, after this, my device administrator component will still be in the mAdminMap even if I uninstall my app.

Once you have done this, go ahead and uninstall your app.

Step 2

Now install the anti-virus software that you are benignly trying to deceive. If you have done everything right, then you should be able to get something like the screen shots below, in which Lookout’s AV thinks that it has the feature requiring device administration privilege enabled. Note that, if you run into any unexpected results, you can try to debug by building your own Android image with debug log statements inserted in the code related to vulnerable code. You can find some hints for that as well in my earlier post on OBAD analysis.

Note: If you did not take my advice and, instead of trying it with an AV, you tried it on your corporate MDM app, it may not have worked because of what I will explain below.

The real list of device administrators as seen from Settings -> Security -> Device Administrators – showing none is enabled.

One More Obstacle

If you tried the above steps on an MDM app, it likely did not work. The reason is that MDM apps typically also use other methods to check whether the device is compliant with the security policies. One common way is to check for password strength compliance using isActivePasswordSufficient of DevicePolicyManager. Taking a look at its code, you will see:

 public boolean isActivePasswordSufficient(int userHandle) { enforceCrossUserPermission(userHandle); synchronized (this) { DevicePolicyData policy = getUserData(userHandle); // This API can only be called by an active device admin, // so try to retrieve it to check that the caller is one. getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);

As you can see in the highlighted code and comment above, it uses getActiveAdminForCallerLocked to ensure that the caller is an active device administrator who has permissions to use the password limiting policy. If the MDM uses this method and you have done what I have mentioned above, the reason it will not work is that, in getActiveAdminForCallerLocked when called with first parameter being null, we execute:

ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy) throws SecurityException { final int callingUid = Binder.getCallingUid(); final int userHandle = UserHandle.getUserId(callingUid); final DevicePolicyData policy = getUserData(userHandle); if (who != null) { ... } else { final int N = policy.mAdminList.size(); for (int i=0; i

This enumerates the admins in mAdminList, which is correctly updated when we disable or remove a Device Administrator. In the way we tried to exploit it above, this check will throw a security exception because the MDM’s Device Administrator would not be in mAdminList.

Note that the exception will not be thrown so long as there exists one enabled device administrator with the same policies as the MDM app that you are trying to bypass. It should have the same user ID (because of admin.getUid() == callingUid check) as that of the MDM to be bypassed. Now this is possible if you can use the android:sharedUserId attribute in Android manifest file. This is how you can exploit an MDM:

Perform Step 1 as mentioned above. Unpack the apk of the MDM you are trying to bypass, edit the AndroidManifest.xml file and add android:sharedUserId=, repackage it and generate a new apk signed with your own key .

Create a different app with a DeviceAdministrator component using same policies as the Device Administrator you are trying to bypass, this would be a simple and dumb app and would not enforce anything, use the same setting for android:sharedUserId= in its manifest file, sign it with same key, install it on your device and enable its device administrator. Install the repackaged apk for the MDM you are trying to bypass, and it should think that it has its Device Administrator enabled and that the password is compliant because the security exception will not be thrown by getActiveAdminForCallerLocked since there would be an active device administrator with the same UID as the one you are trying to bypass.

After all this, you can get your MDM to think that you are fully compliant with the corporate policies while your device does not even have a device administrator enabled except perhaps a self-signed, very user-laziness-friendly one that even allows the absence of a password when the unlock setting is enabled.

 

Mitigation and Responsible Disclosure

MDM apps should also check whether their DeviceAdministrator component is enabled by using getActiveAdmins() of DevicePolicyManager along with its isAdminActive method. Furthermore, to be safer, they should also look into using code protection techniques and verify the app signing certificate at run time.

The Android security team has been notified of this vulnerability, and it has already been fixed in the latest version of Android. However, earlier versions remain vulnerable, and the easiest thing here may be for the MDM apps to update themselves if they are affected; even if earlier versions of Android are patched, who knows when it will reach all the devices that an MDM supports. We have also informed some of the top MDM vendors who may be affected by this and have coordinated the release of this blog entry with them.

Conclusions

We hope this will emphasize the need for the following:

  • Well-balanced BYOD solutions that meet security needs while being user-friendly and not causing unnecessary trouble to users.
  • Emphasis on the importance of code protection for your apps and on verification of app signature at run time.

 

More from Endpoint

The Needs of a Modernized SOC for Hybrid Cloud

5 min read - Cybersecurity has made a lot of progress over the last ten years. Improved standards (e.g., MITRE), threat intelligence, processes and technology have significantly helped improve visibility, automate information gathering (SOAR) and many manual tasks. Additionally, new analytics (UEBA/SIEM) and endpoint (EDR) technologies can detect and often stop entire classes of threats. Now we are seeing the emergence of technologies such as attack surface management (ASM), which are starting to help organisations get more proactive and focus their efforts for maximum…

5 min read

X-Force Identifies Vulnerability in IoT Platform

4 min read - The last decade has seen an explosion of IoT devices across a multitude of industries. With that rise has come the need for centralized systems to perform data collection and device management, commonly called IoT Platforms. One such platform, ThingsBoard, was the recent subject of research by IBM Security X-Force. While there has been a lot of discussion around the security of IoT devices themselves, there is far less conversation around the security of the platforms these devices connect with.…

4 min read

X-Force Prevents Zero Day from Going Anywhere

8 min read - This blog was made possible through contributions from Fred Chidsey and Joseph Lozowski. The 2023 X-Force Threat Intelligence Index shows that vulnerability discovery has rapidly increased year-over-year and according to X-Force’s cumulative vulnerability and exploit database, only 3% of vulnerabilities are associated with a zero day. X-Force often observes zero-day exploitation on Internet-facing systems as a vector for initial access however, X-Force has also observed zero-day attacks leveraged by attackers to accomplish their goals and objectives after initial access was…

8 min read

Patch Tuesday -> Exploit Wednesday: Pwning Windows Ancillary Function Driver for WinSock (afd.sys) in 24 Hours

12 min read - ‘Patch Tuesday, Exploit Wednesday’ is an old hacker adage that refers to the weaponization of vulnerabilities the day after monthly security patches become publicly available. As security improves and exploit mitigations become more sophisticated, the amount of research and development required to craft a weaponized exploit has increased. This is especially relevant for memory corruption vulnerabilities.Figure 1 — Exploitation timelineHowever, with the addition of new features (and memory-unsafe C code) in the Windows 11 kernel, ripe new attack surfaces can…

12 min read