Grab-n-Run


Source link: https://github.com/lukeFalsina/Grab-n-Run

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

  • 10/10/2015 - The repackaging tool is now online. Use it to patch automatically your applications to use Grab'n Run APIs.
  • 01/17/2015 - Grab'n Run is now available on JCenter
  • 01/16/2015 - Grab'n Run project migrates to Android Studio, the official IDE for Android application development. However, you can still use the library also with your ADT projects! ( see below the "Quick Setup" section for further details)
  • 11/26/2014 - Grab'n Run is on line!

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 [email protected] 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).

  • JAR and APK containers can be either already stored on the device or automatically fetched from remote locations by GNR.
  • Retrieved containers signatures are compared against a valid developer certificate. Only containers that are correctly signed are allowed to have their classes loaded dynamically. This ensures integrity and developer authentication on all the retrieved containers.
  • Developer certificates are retrieved from remote locations securely and cached on the mobile phone for future verifications.
  • Cached classes, containers and certificates used for the signature verification are stored into application-private folders. This prevents your application from code injection attacks at runtime.
  • GNR implements an effective caching system that speeds up its execution and at the same time enables it to work in most cases also when no connectivity is available.
  • Transition to GNR is smooth for the application developer since its API where thought to be as close as possible to the standard API provided by the Android framework.
  • When many containers are provided as sources for class loading, Grab'n Run performs a concurrent multi-thread signature verification in order to limit the performance overhead.
  • GNR helps the application developer to implement silent updating on remote third-party libraries in a secure and concise way.

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)
  • Modify the build.gradle file in the app module of your Android project by adding the following compile line in the dependencies body:
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' 
}
  • Resync your project to apply changes.
b. Android Development Tool (ADT)
  • Download JAR
  • Put the JAR in the libs subfolder of your Android project

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

  • Open a terminal and type the following command to generate a keystore and a keypair:
$  keytool -genkey -v -keystore my-tests-key.keystore -alias test_dev_key
-keyalg RSA -keysize 2048 -validity 10000
  • Next export the public key into a certificate that will be used to verify your library code before dynamically loading it:
$ keytool -exportcert -keystore my-tests-key.keystore -alias test_dev_key
-file certificate.pem
  • You should now see in the folder a certificate file called 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.

  • In the ADT Package Explorer right click on "LoaderApp" -> Android Tools -> Export Unsigned Application Package...
  • Next select the same folder where you have previously saved the keystore and the keypair as the destination folder and press OK.
  • Open a terminal which points to the destination folder and sign the apk container with the previously created key:
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1
-keystore my-tests-key.keystore LoaderApp.apk test_dev_key
  • Finally align the apk container to optimize access time to its resources:
$ <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 :)

  • If you want to learn how to use Grab'n Run I suggest to start from the tutorial and then moving on by analyzing the example application.
  • If you are interested in understanding what are the security threats of improper dynamic code loading fixed by GNR check out the security resume.
  • If you would like to implement cool features of GNR like silent updates, handling more containers, concurrent code loading or dynamically loading JAR libraries in your applications you should give a look at the complementary topics.
  • You may also need to consult the JavaDoc-like API documentation.
  • Finally, you may want to convert automatically your applications to use Grab'n Run APIs for secure dynamic code loading. Give a try at the repackaging tool.

License

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

Resources

A simple progress indicator (or chart widget) for Android.

Simple, Tiny, Extendable Android MVP library. No complex Base Activity, Base Fragment or Base View. Just base Presenters and View interface for you to extend from.

Extension of Android standard ImageView that lets the user scale the represented image and drag it around a pivot point defined as a fraction or a percentage.

A clean and easy to use Animated Progress View in a Square.

This project aims to implement FloatingActionButton's speed dial animation in material design guideline.

A tiny lib (Less than 10 methods) to store constants where attackers will have a harder time to find.

This library uses an annotationProcessor to store the constants in a new file (where the constants are encrypted), and via JNI it will later retrieve them decoding them inside the .so file.

This way the attackers cant know the encoding system (because its inside the annotation processor), neither the decoding.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes