Home

Awesome

Logo

Research paper

We present the findings of this work in a research paper:

Grab'n Run: Secure and Practical Dynamic Code Loading for Android Applications
Luca Falsina, Yanick Fratantonio, Stefano Zanero, Christopher Kruegel, Giovanni Vigna, Federico Maggi.
In Proceedings of the Annual Computer Security Applications Conference (ACSAC). Los Angeles, CA December, 2015 [PDF] [Bibtex]

If you use Grab'n Run in a scientific publication, we would appreciate citations to the previous paper.
Please use this Bibtex entry:

@InProceedings{falsina15:grabandrun,
  author = {Luca Falsina and Yanick Fratantonio and Stefano Zanero and Christopher Kruegel and Giovanni Vigna and Federico Maggi},
  title = {{Grab'n Run: Secure and Practical Dynamic Code Loading for Android Applications}},
  booktitle = {Proceedings of the Annual Computer Security Applications Conference (ACSAC)},
  month = {December},
  year = {2015},
  address = {Los Angeles, CA}
}

News

Introduction

Grab’n Run (aka GNR) is a simple and effective Java Library that you can easily add to your Android projects to perform secure dynamic class loading operations over standard DexClassLoader.

Previous research has shown that many applications often need to perform dynamic class loading to implement, for example, non-invasive self-update features. However, research has also shown that it is really challenging to safely implement these features. This is of particular importance as, in this context, one single mistake could open the application (and, therefore, the entire device) to serious security vulnerabilities, such as remote code execution.

The main goal of Grab's Run is to offer an alternative to the native Android APIs, and its design enforces that even the most inexperienced developer cannot perform well-known, serious mistakes.

For a brief presentation of the library and some of its features you can give a look at these slides, while if you prefer a more structured and complete description with set up information, tutorials, examples, tips&tricks, and a full presentation of the API you should definitely check the documentation.

If you desire to suggest new features, improvements, criticisms or whatever, I would be more than glad to hear any kind of constructive feedback :D
You can contact me either by dropping an email at lfalsina@gmail.com or by pinging me on Twitter @lfalsina.

Main features

Securely load code dynamically into your Android application from APK containers or JAR libraries translated to be executable by both the Dalvik Virtual Machine (DVM) and the Android Runtime (ART) (don't worry a section of the docs explains step-by-step how to do it).

Quick Setup

This section explains how to setup Grab'n Run as a library for your Android applications.

1. Include library

a. Android Studio (AS)
dependencies {
    // Grab'n Run will be imported from JCenter.
    // Verify that the string "jcenter()" is included in your repositories block!
    compile 'it.necst.grabnrun:grabnrun:1.0.4'
}
b. Android Development Tool (ADT)

2. Android Manifest

Modify the Android Manifest of your application by adding a couple of required permissions:

<manifest>
	<!-- 	Include following permission to be able to download remote resources 
			like containers and certificates -->
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
	<!-- 	Include following permission to be able to download remote resources 
			like containers and certificates -->
	<uses-permission android:name="android.permission.INTERNET" />
	<!-- 	Include following permission to be able to import local containers 
			on SD card -->
	<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
	...
</manifest>

Quick example of use

This quick use case gives you a taste on how to use GNR once you have added it to your project.

1. Create a key pair to sign your code and export your developer certificate

$ 	keytool -genkey -v -keystore my-tests-key.keystore -alias test_dev_key 
	-keyalg RSA -keysize 2048 -validity 10000
$	keytool -exportcert -keystore my-tests-key.keystore -alias test_dev_key 
	-file certificate.pem

2. Publish your developer certificate on line at a remote location which uses HTTPS protocol

You can publish the certificate wherever you like as long as HTTPS protocol is used and everyone can access this location from the web. As a test example you could store the certificate.pem in your "Public" Dropbox folder and then retrieve the associated public link, which could be for example something like "https://dl.dropboxusercontent.com/u/00000000/certificate.pem". Note this URL down, you will need it soon.

3. Export an unsigned container and sign it with your developer key

Let's say that in your IDE (i.e., the Android Development Tools (ADT)) you have an Android project called "LoaderApp" from which you want to load some of its classes dynamically in another project.

$	jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 
	-keystore my-tests-key.keystore LoaderApp.apk test_dev_key
$	<path_to_your_sdk>/sdk/build-tools/<sdk_version_number>/zipalign -v 4 
	LoaderApp.apk LoaderAppAligned.apk

P.S. Step 3 can also be directly performed by means of your favorite IDE. In ADT you would have to select the option "Android Tools -> Export Signed Application Package..." and, when it is required, navigate to the location of your keystore and inserting its password, the key id and the key password. On the other hand in Android Studio the signature process can be automatized by setting up a proper signing configuration as described here.

4. Publish the signed and aligned version of the source container

Once you have obtained LoaderAppAligned.apk, you need to make also this resource available on line. Notice that, in this case, both remote locations that use HTTP or HTTPS protocols are fine as long as they are accessible from the web. Again, as an example, you can store the container in your "Public" Dropbox folder and get back a public URL like "https://dl.dropboxusercontent.com/u/00000000/LoaderAppAligned.apk".

5. Set up dynamic code loading with GNR in the application

In the end, it is time to set up a SecureDexClassLoader instance to fetch your remote container and developer certificate, store it in a safe place and perform a signature verification before dynamically loading your code.

Copy and paste the code below in one of the Activity in your target Android project, where you have already imported GNR, to dynamically and securely load an instance of the class "com.example.MyClass":


MyClass myClassInstance = null;
jarContainerPath = "https://dl.dropboxusercontent.com/u/00000000/LoaderAppAligned.apk";

try {
	Map<String, URL> packageNamesToCertMap = new HashMap<String, URL>();
	packageNamesToCertMap.put("com.example", new URL("https://dl.dropboxusercontent.com/u/00000000/certificate.pem"));

	SecureLoaderFactory mSecureLoaderFactory = new SecureLoaderFactory(this);
	SecureDexClassLoader mSecureDexClassLoader = mSecureLoaderFactory.createDexClassLoader(	jarContainerPath, 
												null, 
												getClass().getClassLoader(),
												packageNamesToCertMap);
		
	Class<?> loadedClass = mSecureDexClassLoader.loadClass("com.example.MyClass");

	// Check whether the signature verification process succeeded
	if (loadedClass != null) {

		// No security constraints were violated and so
		// class loading was successful.
		myClassInstance = (MyClass) loadedClass.newInstance();
				
		// Do something with the loaded object myClassInstance
		// i.e. myClassInstance.doSomething();
	}

} catch (ClassNotFoundException e) {
	// This exception will be raised when the container of the target class
	// is genuine but this class file is missing..
	e.printStackTrace();
} catch (InstantiationException e) {
	e.printStackTrace();
} catch (IllegalAccessException e) {
	e.printStackTrace();
} catch (MalformedURLException e) {
	// The previous URL used for the packageNamesToCertMap entry was a malformed one.
	Log.e("Error", "A malformed URL was provided for a remote certificate location");
}

Et voilà.. now you have an instance of "MyClass" loaded in a secure way at run time!

Next steps :)

License

Grab'n Run is released under the Apache license. Check the COPYRIGHT file for further details.

Android Arsenal