Wednesday, February 26, 2014

First steps performing penetration testing on an Android application

This article will list the first steps to perform a security review of an Android application. These steps will cover an initial information collection, APK decompilation for static analysis and APK modification to enable debugging and dynamic analysis.

If you feel that any of these steps can be improved or simplified through existing tools, please leave your comment and I will update the article.

The number of tools available to assist in understanding Android applications has significantly increased offering powerful and robust features to easily understand and review our target application.

For the initial assessment we will be using the following tools:
Drozer: https://www.mwrinfosecurity.com/products/drozer/
APKTool: https://code.google.com/p/android-apktool/
Androguard: http://code.google.com/p/androguard/
ApkAnalyser: http://developer.sonymobile.com/knowledge-base/tools/analyse-your-apks-with-apkanalyser/
Netbeans IDE: https://netbeans.org/downloads/
Android SDK: https://developer.android.com/sdk/index.html#ExistingIDE

 APK Downloader: http://www.01net.com/telecharger/windows/Internet/plugins/fiches/118788.html

1- APK Retrieval

To download the target APK, the easiest way is using APK downloader. The tool is a Chrome extension that add a download button at the address once an APK URL is detected.


 2- Android SDK Installation & Emulator Setup

The installation of Android SDK is very straightforward and available at the Android Developer portal.

To test our application we will be using the Android Emulator, which could be created using the AVD Manager. The rest of these steps can also be performed on a root'd phone.



To execute the Emulator we won't be using the start button as several options are only accessible from the command line. Among the interesting option is the http-proxy feature which allow proxification of HTTP/HTTPS.

./emulator -avd watchever -http-proxy http://127.0.0.1:8081 -scale 0.6

Other traffic will requirea slightly complex setup which is already covered in this blog post: https://intrepidusgroup.com/insight/2010/12/mallory-and-me-setting-up-a-mobile-mallory-gateway/

We can this way inspect the HTTP traffic using our favorite Proxy like ZAP or Burp.

3- Installation and Information Collection

APK should be installed using the following command:
 $ adb install uk.co.aifactory.chessfree.apk
1986 KB/s (7412910 bytes in 3.644s)
    pkg: /data/local/tmp/uk.co.aifactory.chessfree.apk
Success


Once the application is installed, we might want to identify its different feature like authentication which might trigger storage of password for instance, which will allow result in the creation of Data files . The location of these files will depend on your application, but the usual folders are /data/data/<APK_Name> and /sdcard/Android/data/<APK_Name>.

This is a sample of the files found at the data folder:
root@android:/data/data/uk.co.aifactory.chessfree # ls -lR

.:
drwxrwx--x u0_a46   u0_a46            2014-02-26 18:22 cache
drwxrwx--x u0_a46   u0_a46            2014-02-26 18:22 databases
drwxrwx--x u0_a46   u0_a46            2014-02-26 18:22 files
drwxr-xr-x system   system            2014-02-26 18:20 lib
drwxrwx--x u0_a46   u0_a46            2014-02-26 18:22 shared_prefs

./cache:
drwx------ u0_a46   u0_a46            2014-02-26 18:22 com.android.renderscript.cache
drwx------ u0_a46   u0_a46            2014-02-26 18:22 webviewCacheChromium
drwx------ u0_a46   u0_a46            2014-02-26 18:22 webviewCacheChromiumStaging

./cache/com.android.renderscript.cache:

./cache/webviewCacheChromium:
-rw------- u0_a46   u0_a46      45056 2014-02-26 18:25 data_0
-rw------- u0_a46   u0_a46     270336 2014-02-26 18:25 data_1
-rw------- u0_a46   u0_a46       8192 2014-02-26 18:22 data_2
-rw------- u0_a46   u0_a46       8192 2014-02-26 18:22 data_3
-rw------- u0_a46   u0_a46     262512 2014-02-26 18:25 index

./cache/webviewCacheChromiumStaging:

./databases:
-rw-rw---- u0_a46   u0_a46      61440 2014-02-26 18:22 google_analytics.db
-rw------- u0_a46   u0_a46       8720 2014-02-26 18:22 google_analytics.db-journal
-rw-rw---- u0_a46   u0_a46      40960 2014-02-26 18:22 webview.db
-rw------- u0_a46   u0_a46       8720 2014-02-26 18:22 webview.db-journal
-rw------- u0_a46   u0_a46       7168 2014-02-26 18:22 webviewCookiesChromium.db

./files:
-rw-rw---- u0_a46   u0_a46      12057 2014-02-26 18:25 chess-savegame.save
-rw-rw---- u0_a46   u0_a46        145 2014-02-26 18:25 chess-saverecords.save

./lib:
-rwxr-xr-x system   system     129736 2014-03-14 13:47 libchessfree-engine.so
-rwxr-xr-x system   system      36100 2014-02-08 14:34 libonlinepromo.so

./shared_prefs:
-rw-rw---- u0_a46   u0_a46        131 2014-02-26 18:22 HelperService.xml
-rw-rw---- u0_a46   u0_a46       1699 2014-02-26 18:22 chess-prefs.xml
-rw-rw---- u0_a46   u0_a46        132 2014-02-26 18:22 uk.co.aifactory.chessfree_preferences.xml






Some of the most intersting files are the databases, these are SQLite3 which can be retrieved and accessed using the sqlite3 tool. Commands like .schema and .dump allow easy exploration of the database to identify intersting tables:

$ adb pull /data/data/uk.co.aifactory.chessfree .
pull: building file list...
pull: /data/data/uk.co.aifactory.chessfree/shared_prefs/HelperService.xml -> ./shared_prefs/HelperService.xml
pull: /data/data/uk.co.aifactory.chessfree/shared_prefs/uk.co.aifactory.chessfree_preferences.xml -> ./shared_prefs/uk.co.aifactory.chessfree_preferences.xml
pull: /data/data/uk.co.aifactory.chessfree/shared_prefs/chess-prefs.xml -> ./shared_prefs/chess-prefs.xml
pull: /data/data/uk.co.aifactory.chessfree/databases/google_analytics.db -> ./databases/google_analytics.db
pull: /data/data/uk.co.aifactory.chessfree/databases/google_analytics.db-journal -> ./databases/google_analytics.db-journal
pull: /data/data/uk.co.aifactory.chessfree/databases/webview.db -> ./databases/webview.db
pull: /data/data/uk.co.aifactory.chessfree/databases/webview.db-journal -> ./databases/webview.db-journal
pull: /data/data/uk.co.aifactory.chessfree/databases/webviewCookiesChromium.db -> ./databases/webviewCookiesChromium.db
pull: /data/data/uk.co.aifactory.chessfree/databases/webviewCookiesChromiumPrivate.db -> ./databases/webviewCookiesChromiumPrivate.db
pull: /data/data/uk.co.aifactory.chessfree/files/chess-saverecords.save -> ./files/chess-saverecords.save
pull: /data/data/uk.co.aifactory.chessfree/files/chess-savegame.save -> ./files/chess-savegame.save
pull: /data/data/uk.co.aifactory.chessfree/cache/webviewCacheChromium/index -> ./cache/webviewCacheChromium/index
pull: /data/data/uk.co.aifactory.chessfree/cache/webviewCacheChromium/data_0 -> ./cache/webviewCacheChromium/data_0
pull: /data/data/uk.co.aifactory.chessfree/cache/webviewCacheChromium/data_1 -> ./cache/webviewCacheChromium/data_1
pull: /data/data/uk.co.aifactory.chessfree/cache/webviewCacheChromium/data_2 -> ./cache/webviewCacheChromium/data_2
pull: /data/data/uk.co.aifactory.chessfree/cache/webviewCacheChromium/data_3 -> ./cache/webviewCacheChromium/data_3
pull: /data/data/uk.co.aifactory.chessfree/lib/libchessfree-engine.so -> ./lib/libchessfree-engine.so

18 files pulled. 0 files skipped.
423 KB/s (901296 bytes in 2.077s)

                        
$ sqlite3 databases/webview.db
SQLite version 3.7.9 2011-11-01 00:52:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE formdata (_id INTEGER PRIMARY KEY, urlid INTEGER, name TEXT, value TEXT, UNIQUE (urlid, name, value) ON CONFLICT IGNORE);
CREATE TABLE formurl (_id INTEGER PRIMARY KEY, url TEXT);
CREATE TABLE httpauth (_id INTEGER PRIMARY KEY, host TEXT, realm TEXT, username TEXT, password TEXT, UNIQUE (host, realm) ON CONFLICT REPLACE);
CREATE TABLE password (_id INTEGER PRIMARY KEY, host TEXT, username TEXT, password TEXT, UNIQUE (host, username) ON CONFLICT REPLACE);


To collect other information about our target application, we will be using the drozer application. The application allows easy access to a mine of information using a client component that should be installed first.

$ ll
total 67036
drwxrwxr-x  2 asm asm     4096 févr. 25 15:52 ./
drwxrwxr-x 12 asm asm     4096 févr. 26 12:20 ../
-rw-rw-r--  1 asm asm   629950 janv.  8 11:07 agent.apk
-rw-rw-r--  1 asm asm      913 janv.  6 10:04 CONTRIBUTORS
-rw-r--r--  1 asm asm 22602838 févr. 25 15:48 drozer_2.3.3.deb
-rw-rw-r--  1 asm asm 22451580 janv.  8 11:07 drozer-2.3.3-py2.7.egg
-rw-r--r--  1 asm asm 22861897 févr. 25 15:50 drozer-2.3.3.tar.gz
-rw-rw-r--  1 asm asm     2769 janv.  8 11:07 INSTALLING
-rw-rw-r--  1 asm asm     2801 janv.  8 11:07 LICENSE
-rw-rw-r--  1 asm asm     1447 janv.  8 11:07 README.md

$ adb install agent.apk


And then executed by making sure it is ON.



To connect to the Drozer server, tcp forwarding should be enabled on the server port (31415 by default):

$ adb forward tcp:31415 tcp:31415
$ drozer console --server 127.0.0.1:31415 connect
Selecting 12b4e69719761c98 (unknown sdk 4.1.2)

            ..                    ..:.
           ..o..                  .r..
            ..a..  . ....... .  ..nd
              ro..idsnemesisand..pr
              .otectorandroidsneme.
           .,sisandprotectorandroids+.
         ..nemesisandprotectorandroidsn:.
        .emesisandprotectorandroidsnemes..
      ..isandp,..,rotectorandro,..,idsnem.
      .isisandp..rotectorandroid..snemisis.
      ,andprotectorandroidsnemisisandprotec.
     .torandroidsnemesisandprotectorandroid.
     .snemisisandprotectorandroidsnemesisan:
     .dprotectorandroidsnemesisandprotector.

drozer Console (v2.3.3)
dz>


Drozer user guide avilable here https://www.mwrinfosecurity.com/system/assets/559/original/mwri_drozer-users-guide_2013-09-11.pdf have good explanation of it's features, to cite a few:

-Collected APK information:
 dz> run app.package.info -a uk.co.aifactory.chessfree
Package: uk.co.aifactory.chessfree
  Application Label: Chess Free
  Process Name: uk.co.aifactory.chessfree
  Version: 1.81
  Data Directory: /data/data/uk.co.aifactory.chessfree
  APK Path: /data/app/uk.co.aifactory.chessfree-1.apk
  UID: 10046
  GID: [3003, 1015, 1028]
  Shared Libraries: null
  Shared User ID: null
  Uses Permissions:
  - android.permission.INTERNET
  - android.permission.READ_PHONE_STATE
  - android.permission.ACCESS_NETWORK_STATE
  - android.permission.WRITE_EXTERNAL_STORAGE
  - android.permission.READ_EXTERNAL_STORAGE
  Defines Permissions:
  - None


-Identify attack surface:
dz> run app.package.attacksurface uk.co.aifactory.chessfree
Attack Surface:
  1 activities exported
  1 broadcast receivers exported
  0 content providers exported
  1 services exported


-List activities:
dz> run app.activity.info -a uk.co.aifactory.chessfree
Package: uk.co.aifactory.chessfree
  uk.co.aifactory.chessfree.ChessFreeActivity


Scan providers:
run scanner.provider.finduris -a uk.co.aifactory.chessfree
Scanning uk.co.aifactory.chessfree...
Unable to Query  content://com.google.plus.platform/token
Unable to Query  content://com.facebook.katana.provider.AttributionIdProvider/
Unable to Query  content://com.google.plus.platform/token/
Unable to Query  content://com.facebook.katana.provider.AttributionIdProvider

No accessible content URIs found.

4- Static Analysis and Decompilation

Java language bytecode decompiles well if not obfuscated, there are several open-source tools available to perform this task.
Androguard has proven to be very efficient in correctly decompiling and analysing APK using DAD engine, which is specialised in Dalvik bytecode.
Androguard could be used simultaneously with ApkAnalyser to easily navigate the application and identify key components, in addition both of these tools offer great features to help understand the application, like APK diffing and CFG visualization.



$ ./androlyze.py --shell
Androlyze version 2.0
In [1]: a, d, dx = AnalyzeAPK("/home/asm/Images/android/uk.co.aifactory.chessfree.apk", decompiler="dad")

In [2]: d.CLASS_Luk_co_aifactory_onlinepromo_HelperService_1.source()
package uk.co.aifactory.onlinepromo;
 class HelperService$1 implements java.io.FilenameFilter {
    final synthetic uk.co.aifactory.onlinepromo.HelperService this$0;
     HelperService$1(uk.co.aifactory.onlinepromo.HelperService p1)
    {
        this.this$0 = p1;
        return;
    }
    public boolean accept(java.io.File p3, String p4)
    {
        v0 = p4.toLowerCase();
        if ((v0.endsWith(".jpg") == 0) && ((v0.endsWith(".jpeg") == 0) && ((v0.endsWith(".gif") == 0) && (v0.endsWith(".png") == 0)))) {
            v1 = 0;
        } else {
            v1 = 1;
        }
        return v1;
    }
}




The Secure Coding CERT have a good list of issues to look for while inspecting the decompiled source code: https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=111509535

5- Dynamic Analysis and Debugging

Having the possibility to dynamicly debug an APK makes it a lot easier to understand the application logic; to do so, the APK must be disassembled to smali and rebuilt with debug mode using APKTool:

 $ java -jar apktool_2.0.0b7.jar d /home/asm/Images/android/uk.co.aifactory.chessfree.apk
I: Using Apktool 2.0.0-Beta7 on uk.co.aifactory.chessfree.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/asm/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Loading resource table...
I: Baksmaling...
I: Copying assets and libs...
I: Copying unknown files/dir...
I: Copying original files...

$ java -jar apktool_2.0.0b7.jar b uk.co.aifactory.chessfree/ -o chess_d.apk
I: Using Apktool 2.0.0-Beta7 on uk.co.aifactory.chessfree
I: Checking whether sources has changed...
I: Smaling...
I: Checking whether resources has changed...
I: Building resources...
aapt: warning: string 'blurb_1' has no default translation in /home/asm/exp/m.mobile/android/apktool/uk.co.aifactory.chessfree/res; found: da es fi it nb nl ru sv
aapt: warning: string 'blurb_2' has no default translation in /home/asm/exp/m.mobile/android/apktool/uk.co.aifactory.chessfree/res; found: da es fi it nb nl ru sv
aapt: warning: string 'blurb_3' has no default translation in /home/asm/exp/m.mobile/android/apktool/uk.co.aifactory.chessfree/res; found: da es fi it nb nl ru sv
aapt: warning: string 'blurb_4' has no default translation in /home/asm/exp/m.mobile/android/apktool/uk.co.aifactory.chessfree/res; found: da es fi it nb nl ru sv
aapt: warning: string 'blurb_5' has no default translation in /home/asm/exp/m.mobile/android/apktool/uk.co.aifactory.chessfree/res; found: da es fi it nb nl ru sv
aapt: warning: string 'blurb_6' has no default translation in /home/asm/exp/m.mobile/android/apktool/uk.co.aifactory.chessfree/res; found: da es fi it nb nl ru sv
aapt: warning: string 'blurb_7' has no default translation in /home/asm/exp/m.mobile/android/apktool/uk.co.aifactory.chessfree/res; found: da es fi it nb nl ru sv
aapt: warning: string 'blurb_8' has no default translation in /home/asm/exp/m.mobile/android/apktool/uk.co.aifactory.chessfree/res; found: da es fi it nb nl ru sv
aapt: warning: string 'blurb_9' has no default translation in /home/asm/exp/m.mobile/android/apktool/uk.co.aifactory.chessfree/res; found: da es fi it nb nl ru sv
I: Copying libs...
I: Building apk file...
I: Copying unknown files/dir...



And then sign the APK to push it for install:

$ keytool -genkey -v -keystore key.keystore -alias sign -keyalg RSA -keysize 2048 -validity 10000
Entrez le mot de passe du fichier de clés : 
Ressaisissez le nouveau mot de passe :
Quels sont vos nom et prénom ?
  [Unknown]:  T
Quel est le nom de votre unité organisationnelle ?
  [Unknown]:  T
Quel est le nom de votre entreprise ?
  [Unknown]:  T
Quel est le nom de votre ville de résidence ?
  [Unknown]:  T
Quel est le nom de votre état ou province ?
  [Unknown]:  T
Quel est le code pays à deux lettres pour cette unité ?
  [Unknown]:  T
Est-ce CN=T, OU=T, O=T, L=T, ST=T, C=T ?
  [non]:  oui

Génération d'une paire de clés RSA de 2 048 bits et d'un certificat auto-signé (SHA256withRSA) d'une validité de 10 000 jours
    pour : CN=T, OU=T, O=T, L=T, ST=T, C=T
Entrez le mot de passe de la clé pour <sign>
    (appuyez sur Entrée s'il s'agit du mot de passe du fichier de clés) : 
Ressaisissez le nouveau mot de passe :
[Stockage de key.keystore]



$ jarsigner -verbose  -sigalg SHA1withRSA -digestalg SHA1 -keystore key.keystore chess_d.apk sign
 ...
 signing: res/menu/menu_full_paid.xml
  signing: res/menu/menu_review.xml
  signing: res/menu/menu_subset_free.xml
  signing: res/menu/menu_subset_paid.xml
  signing: res/raw/piecedrop.ogg
  signing: res/raw/select.ogg
  signing: res/raw/voicecheckmate.ogg
  signing: res/xml/wallpaper_1.xml
  signing: res/xml/widget_1.xml
  signing: AndroidManifest.xml
  signing: classes.dex
  signing: resources.arsc
   adding: jsr305_annotations/
  signing: jsr305_annotations/Jsr305_annotations.gwt.xml
   adding: jsr305_annotations/v0_r47/
  signing: jsr305_annotations/v0_r47/V0_r47.gwt.xml
jar signed.

Warning:
No -tsa or -tsacert is provided and this jar is not timestamped. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (2041-07-15) or after any future revocation date.

$ jarsigner -verify chess_d.apk
jar verified.

Warning:
This jar contains entries whose certificate chain is not validated.
This jar contains signatures that does not include a timestamp. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (2041-07-15) or after any future revocation date.

Re-run with the -verbose and -certs options for more details.


Finally install the new APK after removing the old one.

To debug the application you will need to use and IDE that supports JPDA, like NetBeans, all you have to do is create a new project using the APKTool generated folder and point the source to smali.

Then execute the  Android Debug Monitor and identify the port of your target application:




And finally attach the debugger at Debuger > Attach Debbuger, fill the port with the port number of our target application and hit OK.



You can now set breakpoints, step through the code and inspect variables and objects.

If you have any other ideas on other first steps that should be performed to assist in understanding the APK , please share them in the comment section and I'll update the article.


2 comments:

  1. Ever wondered how to make your app outshine the dozens of Android apps already available on the Android market?
    http://www.showboxdownloadsapp.com/

    ReplyDelete