Introduction

The official ARC (App Runtime for Chrome) project, announced by Google in Google I/O 2014 enables running of Android apps on Chrome environment. The official ARC is available for Chrome OS only in the form of Extension. It is subsequently extended (or hacked, technically) by vladikoff and others into a general Chrome Extension ARChon that can be loaded onto a Chrome browser running on Windows, OS X and Linux. The ARChon is also complemented by a repackaging script, chromeos-apk which transforms an ordinary Android APK file into a loadable ARC app (also, a Chrome App).

Understanding ARC

Unlike the Android Emulator shipped with Android SDK or other commercial solutions (e.g. Genymotion), the goal of ARC is not to build another emulator that runs the full Android OS images and multiple apps. Instead, it aims at providing the minimum codebase to run a single app. Based on the analysis of files constitutes ARC implementation, it strips out all components unrelated to the Dalvik VM, and preserves the system libraries and the Android API framework. For example:

  • Most files in _platform_specific/nacl_${arch}/ should be in /system/lib/ on an Android image.
  • dalvikvm.so and dexopt.so should be wrappers for dalvikvm and dexopt.
  • There are also libraries used by Android Emulator from OpenGL ES hardware emulation, such as libEGL_translator.so, libOpenglSystemCommon.so, etc.
  • readonly_fs_image.img is the filesystem image for Android.

Source code of the ARC can be found at this link. However, this only allows you to build the .so libraries, a fully running system cannot currently be built. The following security evaluation work we have done is experimental and mainly for fun and learning. Source code for the experiments we conducted can be found on GitHub.

Permission Mismatch

Issues

Through our experiments, we observed that ARC does not respect Android permission model , i.e., a repackaged app has access to privileged operations even without declaring corresponding permissions. You can compile run the TestPermission app in the the above GitHub link to confirm this issue. When running on ARC, the app has Internet access even without declaring <uses-permission android:name="android.permission.INTERNET" /> in its manifest file.

Solutions

Given the issue, the first intuition is that ARC delegates permission checking to Chrome Runtime (together with permission enforcement for Chrome App). And I did found that the repackaging script adds every permission to the repackaged app, regardless of the actual permissions declared.

"permissions": [
    "gcm", {
       "socket": ["tcp-connect", "tcp-listen", "udp-bind", "udp-send-to", "resolve-host"]
    }, 
    "unlimitedStorage", 
    "notifications", 
    "clipboardRead", {
        "fileSystem": ["write"]
    }, 
    "https://clients2.google.com/", 
    "videoCapture", 
    "clipboardWrite", 
    "identity.email", 
    "alarms", 
    "storage", 
    "identity", 
    "audioCapture"
]

Therefore, the first solution is to build a map between Android app permissions to Chrome App permissions and instrument the repackaging script to scan for Android permissions first and declare only necessary Chrome permissions for the repackaged app.

Following this approach, there are two difficulties to be overcome:

1) Get the list of permissions honored by ARC

As the permissions declarable in the ARC environment might be different compared with the stock Android, we can not rely on the stock Android OS image for the permission list (plus there is no official document that provides an exhaustive permission list available for Android). This problem is tackled by dynamically probing PackageManager with the following code snippet:

getPackageManager().getPackageInfo("android", PackageManager.GET_PERMISSIONS);

This file lists the permissions available for ARC environment with protection level=dangerous, extracted by the app AndroidPermissionProber.

2) Manually map Android permissions to Chrome permissions

Unfortunately, this process cannot be automated because it requires a lot of domain knowledge. Although similar in nature, the two permission models are not designed the same way, by the same team, or to be used in the same scenarios, which creates a lot of mismatch between these two models. Based on my experiments and understanding, I finally ended up with the following mapping:

{
  "permission": {
    "android.permission.SYSTEM_ALERT_WINDOW": ["alarms", "notifications"],
    "android.permission.CAMERA": ["videoCapture"],
    "android.permission.INTERNET": [{"socket":["tcp-connect","tcp-listen","udp-bind",
                                               "udp-send-to","resolve-host"]}],
    "android.permission.NFC": ["copresence"],
    "android.permission.RECORD_AUDIO": ["audio", "audioCapture"],
    "android.permission.WRITE_EXTERNAL_STORAGE": ["storage", "unlimitedStorage"],
    "android.permission.ACCESS_FINE_LOCATION": ["location", "geolocation"],
    "android.permission.AUTHENTICATE_ACCOUNTS": ["identity"],
    "android.permission.USE_CREDENTIALS": ["identity"],
    "android.permission.MANAGE_ACCOUNTS": ["identity"]
  },
  "manifest": {
    "android.permission.BLUETOOTH": [{"bluetooth": {"socket": true, "low_energy": true}}],
    "android.permission.BLUETOOTH_ADMIN": [{"bluetooth": {"socket": true, "low_energy": true}}]
  }
}

Instrumenting the repackaging script to scan for Android permissions is trivial given the adbkit-apkreader library.

Future work

The above solution, although works in practice, might not be the best solution as it totally abandoned the GID/UID based permission model in Android OS. For example, an app with INTERNET permission is effectively being assigned with GID 3003. However, when we try to find the assigned GIDs for a no-permission app in ARC environment, we found that ARC assigns a lot more GIDs than necessary to the app!

aid

Assigned GID in ARC environment (left) and assigned GID in stock Android OS (right).

For example, the same app TestAppID (without any permissions declared) is tested in ARC (left) as well as Android Emulator in Android SDK (right). It has normal GIDs in the Emulator but ARC assigns more GIDs (including GID 3003 representing INTERNET permission) to the app, which essentially allows the app to have INTERNET permission (as long as the outer Chrome permission allows).

I am currently unclear of the cause of this issue. I suspect that these GIDs are hard-coded into the ARC so that each app is automatically granted with these permissions. Such a design choice enables quick development and testing of core functions of ARC and reduces app crashes caused permission enforcement issues. However, this loophole, if not fixed, might grow to a more serious security issue once ARC gets popular. I believe it is worthwhile to have more investigations on this matter and fix it as soon as possible.

Inter-"Component" Interaction

Inter-"component" interaction here refers to the potential interactions between ARC app and (1) other ARC apps, (2) other Chrome extensions and apps, (3) webpages, and (4) the underlying OS.

I have been trying to launch attacks against ARC app from outside of ARC environment but encountered little successes. Therefore, I came to the general conclusion that there is no particular advantage gained by attacking the ARC model, because of ARC being heavily sandboxed.

arc-sandbox

Sandboxes of ARC environment

The intuition is that: in order for an ARC app to do any harm to other Chrome components (apps, extensions or webpages), it must break the NaCl sandbox and the Chrome app (renderer) sandbox. In other word, if there is a way that ARC app can leverage to break these sandboxes (for example, through JNI), it can always be translated to a break of Chrome app sandbox. Hence, there is no additional advantage gained by attacking Chrome from the ARC app.

In addition, following is a list of findings I have gained by experimenting with the ARC.

  • There is no app-to-app interaction on ARC. This implies that if an Android app is malicious on Android without cooperation from other apps, then when ported to ARC, the app is still malicious. And, if an Android app is malicious on Android but does requires cooperation from other apps (i.e., one can exploit vulnerabilities in ContentProvider of SMS app to steal messages). The app will not work on ARC because ARC is designed for single app settings and there will not be another SMS app installed.

  • Android rooting does not make much sense. Rooting or in broader term, system privilege escalation attack generally has two purposes: (1) extract hidden information (like information of other apps) or (2) gain additional capabilities (like networking). However, in ARC, (1) is not possible. And protected by Chrome permission model, (2) is not possible.

  • Chrome extension may cause launch of a DoS attack against ARC app, leveraging the chrome.processes API and repeatedly killing the NaCl process that hosts ARC. However, this feature can be used to kill any other processes (including webpages) and are not specific to ARC. One can play with this feature with the processes program in crx folder.

  • The system default browser will have the cookies generated and consumed by the ARC app if the ARC app uses WebView to browse for web contents. You can play with this feature with the cookies program in crx folder and the TestIntentBrowser app.

  • Data stored in both "internal" storage (phone storage) or "external" storage (SD card) are not safe. ARC will store these data in an obfuscated (but still understandable) filesystem and one may find these items in path {Chrome support folder}/Default/Storage/ext/{app id}/def/File System/ (For Mac OS).

  • ARC app may have access to OS Filesystem (via browser file chooser), but will not be able to modify them, i.e. ARC will first copy these items to a different location and feed the app with the copy instead of the original file.

Proofread by Sanidhya Kashyap and Taesoo Kim.