Skip to content

Latest commit

 

History

History
410 lines (338 loc) · 16.4 KB

Lab-001.md

File metadata and controls

410 lines (338 loc) · 16.4 KB

Decompilation and Analysis

1.) - Download the APK

➜  ~  git clone https://github.com/VerSprite/BSidesSF-2015
Cloning into 'BSidesSF-2015'...
remote: Counting objects: 93, done.
remote: Compressing objects: 100% (38/38), done.
remote: Total 93 (delta 3), reused 0 (delta 0), pack-reused 37
Unpacking objects: 100% (93/93), done.
Checking connectivity... done.
➜  ~  cd BSidesSF-2015 
➜  BSidesSF-2015 git:(master) cd app/
➜  app git:(master) ls -la
total 3592
drwxr-xr-x  9 rotlogix  staff     306 Apr  7 10:52 .
drwxr-xr-x  7 rotlogix  staff     238 Apr  7 10:52 ..
-rw-r--r--  1 rotlogix  staff       7 Apr  7 10:52 .gitignore
-rw-r--r--  1 rotlogix  staff  907915 Apr  7 10:52 app-release.apk
-rw-r--r--  1 rotlogix  staff    7223 Apr  7 10:52 app.iml
-rw-r--r--  1 rotlogix  staff     587 Apr  7 10:52 build.gradle
-rw-r--r--  1 rotlogix  staff  907915 Apr  7 10:52 crackme.apk
-rw-r--r--  1 rotlogix  staff     666 Apr  7 10:52 proguard-rules.pro
drwxr-xr-x  4 rotlogix  staff     136 Apr  7 10:52 src
➜  app git:(master) 


2.) - Decompile the APK with apktool - http://ibotpeaches.github.io/Apktool/

➜  app git:(master) java -jar ~/Tools/mobile/android/apktool/apktool_2.0.0rc4.jar -r d crackme.apk 
I: Using Apktool 2.0.0-RC4 on crackme.apk
I: Loading resource table...
I: Copying raw resources...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...

-r disregards decoding resources

APK Directory Structure

/res - Directory containing resources that are not compiled

➜  crackme git:(master) ✗ ls -R | grep '/res'
./res:
./res/anim:
./res/color:
./res/drawable:
./res/drawable-hdpi-v4:
./res/drawable-ldrtl-hdpi-v17:
./res/drawable-ldrtl-mdpi-v17:
./res/drawable-ldrtl-xhdpi-v17:
./res/drawable-ldrtl-xxhdpi-v17:
./res/drawable-ldrtl-xxxhdpi-v17:
./res/drawable-mdpi-v4:
./res/drawable-v21:
./res/drawable-xhdpi-v4:
./res/drawable-xxhdpi-v4:
./res/drawable-xxxhdpi-v4:
./res/layout:
./res/layout-v11:
./res/layout-v21:
./res/menu:
./res/mipmap-hdpi-v4:
./res/mipmap-mdpi-v4:
./res/mipmap-xhdpi-v4:
./res/mipmap-xxhdpi-v4:
./smali/android/support/v4/content/res:

META-INF - Usually contains the Manifest, and Application Certifcate

➜  crackme git:(master) ✗ ls -R | grep '/META-INF'
./original/META-INF:

lib - Directory containing compiled shared objects broken down into their specific architecture - ex: armeabi, armeabi-v7a - armeabi - "ARM Embedded Application Binary Interface"

assets - Directory containing assets that can be accessed by the AssetManager

AndroidManifest.xml - Contains application, permission, and component definitions and declarations

classes.dex - Compiled DEX executable

resources.arsc - Precompiled resources


-- The output of apktool will breakout the APK structure a bit different --

➜  crackme git:(master) ✗ ls
AndroidManifest.xml apktool.yml         original            res                 resources.arsc      smali

/smali - Contains the disassembled format for the Dalvik bytecode

versprite

./com/versprite:
crackme

./com/versprite/crackme:
BuildConfig.smali   R$anim.smali        R$color.smali       R$id.smali          R$menu.smali        R$style.smali       emulator
KeyActivity$1.smali R$attr.smali        R$dimen.smali       R$integer.smali     R$mipmap.smali      R$styleable.smali   generate
KeyActivity.smali   R$bool.smali        R$drawable.smali    R$layout.smali      R$string.smali      R.smali

./com/versprite/crackme/emulator:
Detect.smali

./com/versprite/crackme/generate:
Generate.smali         GenerateReceiver.smali

apktool leverages - https://code.google.com/p/smali/ - for this task

Getting Dirty

03.) Using Androguard for Analysis

Documentation: http://doc.androguard.re/html/index.html

Androguard is a great tool to automate APK analysis. We will be using 'Androlyze' for most of the labs, which provides interactive analysis.

➜  app git:(master) ✗ python ~/Tools/mobile/android/androguard/androlyze.py -s
Androlyze version 2.0
In [1]: 

-- We can use AnalyzeAPK() to perform all of heavy lifting for us --

In [1]: a,d,dx = AnalyzeAPK("crackme.apk")
In [2]:

This returns the APK, DalvikVMFormat, and VMAnalysis objects.

APK - has access to all elements in an APK file

DalvikVMFormat - can parse a classes.dex file fo an APK

VMAnalysis - analyses a dex file

-- We can now use the class methods from the APK object to perform basic enumeration over permissions and components --

Activities

In [2]: a.get_activities()
Out[2]: ['com.versprite.crackme.KeyActivity']

-- If you type a. [tab] -> androlyze will display a list of available methods --

In [3]: a.get
a.get_AndroidManifest        a.get_certificate            a.get_files                  a.get_max_sdk_version        a.get_services
a.get_activities             a.get_details_permissions    a.get_files_crc32            a.get_min_sdk_version        a.get_signature
a.get_android_manifest_axml  a.get_dex                    a.get_files_information      a.get_package                a.get_signature_name
a.get_android_manifest_xml   a.get_element                a.get_files_types            a.get_permissions            a.get_target_sdk_version
a.get_android_resources      a.get_elements               a.get_intent_filters         a.get_providers              
a.get_androidversion_code    a.get_file                   a.get_libraries              a.get_raw                    
a.get_androidversion_name    a.get_filename               a.get_main_activity          a.get_receivers  

We are not requesting any special permissions in this application or have any other component besides the declared activity, but here are methods you will care about with a much larger application.

a.get_services() -> Services

a.get_receivers() -> Broadcast Receivers

a.get_providers() -> Content Providers

a.get_permissions() -> Permissions


-- Let's find out what the Main Activity is for this application --

In [6]: a.get_main_activity()
Out[6]: u'com.versprite.crackme.KeyActivity'

This Activity will be the main entry point into the application.

4.) - Using Dex2Jar

Takes an APK as input, does some magic and converts the class.dex back into Java .class files, which subsequently viewed with something like JD-GUI.

➜  app git:(master) ✗ ~/Tools/mobile/android/dex2jar/d2j-dex2jar.sh crackme.apk
dex2jar crackme.apk -> crackme-dex2jar.jar

-- Output will look something like this --

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.versprite.crackme.emulator.Detect;

public class KeyActivity extends Activity
{
  private EditText key;
  private Button submitbtn;

  public void addListenerOnButton()
  {
    this.key = ((EditText)findViewById(2131296320));
    this.submitbtn = ((Button)findViewById(2131296321));
    this.submitbtn.setOnClickListener(new View.OnClickListener()
    {
      public void onClick(View paramAnonymousView)
      {
        String str = String.valueOf(KeyActivity.this.key.getText());
        Intent localIntent = new Intent();
        localIntent.setAction("com.versprite.crackme.GENERATE");
        localIntent.putExtra("key", str);
        KeyActivity.this.sendBroadcast(localIntent);
        Toast.makeText(KeyActivity.this.getApplicationContext(), "Checking Key ...", 0).show();
      }
    });
  }

This will get you the closest to 'source'.

Wax On Wax Off

5.) - Putting It All Together - Analyzing Contacts.apk

-- Pull the Contacts.apk off your emulator --

➜  app git:(master) ✗ adb shell                                                
root@vbox86p:/ # cd /system/app/                                               
root@vbox86p:/system/app # ls -la | grep Contacts
-rw-r--r-- root     root      2285951 2015-02-16 11:10 Contacts.apk
-rw-r--r-- root     root       372792 2015-02-16 11:06 ContactsProvider.apk
root@vbox86p:/system/app # 
➜  app git:(master) ✗ adb pull /system/app/Contacts.apk
6145 KB/s (2285951 bytes in 0.363s)
➜  app git:(master) ✗ ls
Contacts.apk        app.iml             crackme             crackme.apk         src
app-release.apk     build.gradle        crackme-dex2jar.jar proguard-rules.pro

-- Decompile! --

➜  app git:(master) ✗ java -jar ~/Tools/mobile/android/apktool/apktool_2.0.0rc4.jar d Contacts.apk 
I: Using Apktool 2.0.0-RC4 on Contacts.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /Users/rotlogix/Library/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...

-- Androlyze! --

➜  app git:(master) ✗ python ~/Tools/mobile/android/androguard/androlyze.py -s
In [1]: a,d,dx = AnalyzeAPK("Contacts.apk")

-- We can leverage Androlyze's interfactive perspective to do some light scripting for even more automation! --

In [3]: for activity in a.get_activities(): print(activity)
com.android.contacts.activities.PeopleActivity
com.android.contacts.activities.ContactSelectionActivity
com.android.contacts.activities.JoinContactActivity
com.android.contacts.preference.ContactsPreferenceActivity
com.android.contacts.common.list.AccountFilterActivity
com.android.contacts.common.list.CustomContactListFilterActivity
com.android.contacts.activities.ShowOrCreateActivity
com.android.contacts.activities.GroupDetailActivity
com.android.contacts.activities.GroupEditorActivity
com.android.contacts.quickcontact.QuickContactActivity
com.android.contacts.activities.ContactDetailActivity
com.android.contacts.activities.ConfirmAddDetailActivity
com.android.contacts.activities.ContactEditorAccountsChangedActivity
com.android.contacts.activities.ContactEditorActivity
com.android.contacts.common.test.FragmentTestActivity
com.android.contacts.activities.AttachPhotoActivity
com.android.contacts.activities.PhotoSelectionActivity
com.android.contacts.common.vcard.ImportVCardActivity
com.android.contacts.common.vcard.NfcImportVCardActivity
com.android.contacts.common.vcard.CancelActivity
com.android.contacts.common.vcard.SelectAccountActivity
com.android.contacts.common.vcard.ExportVCardActivity
com.android.contacts.widget.PinnedHeaderListDemoActivity
com.android.contacts.socialwidget.SocialWidgetConfigureActivity
com.android.contacts.NonPhoneActivity

In [5]: for service in a.get_services(): print(service)
com.android.contacts.common.util.EmptyService
com.android.contacts.ContactSaveService
com.android.contacts.common.vcard.VCardService
com.android.contacts.ViewNotificationService

In [6]: for receiver in a.get_receivers(): print(receiver)
com.android.contacts.quickcontact.QuickContactBroadcastReceiver
com.android.contacts.socialwidget.SocialWidgetProvider

-- What About Permissions? --

In [9]: for permission in a.get_permissions(): print(permission)
android.permission.CALL_PRIVILEGED
android.permission.READ_CONTACTS
android.permission.WRITE_CONTACTS
android.permission.READ_CALL_LOG
android.permission.WRITE_CALL_LOG
android.permission.MANAGE_ACCOUNTS
android.permission.GET_ACCOUNTS
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_COARSE_LOCATION
android.permission.READ_PROFILE
android.permission.WRITE_PROFILE
android.permission.READ_SOCIAL_STREAM
android.permission.INTERNET
android.permission.NFC
android.permission.READ_PHONE_STATE
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.MODIFY_PHONE_STATE
android.permission.WAKE_LOCK
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.WRITE_SETTINGS
android.permission.USE_CREDENTIALS
android.permission.VIBRATE
android.permission.READ_SYNC_SETTINGS
com.android.voicemail.permission.ADD_VOICEMAIL
com.android.voicemail.permission.READ_WRITE_ALL_VOICEMAIL
android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK
com.android.launcher.permission.INSTALL_SHORTCUT
android.permission.REBOOT
android.permission.RECEIVE_BOOT_COMPLETED

-- What Are The Intent Filters? --

In [47]: activites = a.get_activities()  
In [48]: for activity in activites: 
    filters = a.get_intent_filters('activity', activity)
    for k,v in filters.items(): 
        print(activity, k,v)
   ....:         
('com.android.contacts.activities.PeopleActivity', 'action', [u'android.intent.action.MAIN', u'com.android.contacts.action.LIST_DEFAULT', u'com.android.contacts.action.LIST_CONTACTS', u'com.android.contacts.action.LIST_ALL_CONTACTS', u'com.android.contacts.action.LIST_CONTACTS_WITH_PHONES', u'com.android.contacts.action.LIST_STARRED', u'com.android.contacts.action.LIST_FREQUENT', u'com.android.contacts.action.LIST_STREQUENT', u'android.intent.action.SEARCH', u'com.android.contacts.action.FILTER_CONTACTS', u'android.intent.action.VIEW'])
('com.android.contacts.activities.PeopleActivity', 'category', [u'android.intent.category.DEFAULT', u'android.intent.category.LAUNCHER', u'android.intent.category.BROWSABLE', u'android.intent.category.APP_CONTACTS', u'android.intent.category.TAB'])
('com.android.contacts.activities.ContactSelectionActivity', 'action', [u'android.intent.action.INSERT_OR_EDIT', u'android.intent.action.PICK', u'android.intent.action.GET_CONTENT'])
('com.android.contacts.activities.ContactSelectionActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.activities.JoinContactActivity', 'action', [u'com.android.contacts.action.JOIN_CONTACT'])
('com.android.contacts.activities.JoinContactActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.activities.ShowOrCreateActivity', 'action', [u'com.android.contacts.action.SHOW_OR_CREATE_CONTACT'])
('com.android.contacts.activities.ShowOrCreateActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.quickcontact.QuickContactActivity', 'action', [u'com.android.contacts.action.QUICK_CONTACT'])
('com.android.contacts.quickcontact.QuickContactActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.activities.ContactDetailActivity', 'action', [u'android.intent.action.VIEW'])
('com.android.contacts.activities.ContactDetailActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.activities.ContactEditorActivity', 'action', [u'android.intent.action.EDIT', u'android.intent.action.INSERT'])
('com.android.contacts.activities.ContactEditorActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.common.test.FragmentTestActivity', 'category', [u'android.intent.category.TEST'])
('com.android.contacts.activities.AttachPhotoActivity', 'action', [u'android.intent.action.ATTACH_DATA'])
('com.android.contacts.activities.AttachPhotoActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.common.vcard.ImportVCardActivity', 'action', [u'android.intent.action.VIEW'])
('com.android.contacts.common.vcard.ImportVCardActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.common.vcard.NfcImportVCardActivity', 'action', [u'android.nfc.action.NDEF_DISCOVERED'])
('com.android.contacts.common.vcard.NfcImportVCardActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.widget.PinnedHeaderListDemoActivity', 'action', [u'android.intent.action.MAIN'])
('com.android.contacts.widget.PinnedHeaderListDemoActivity', 'category', [u'android.intent.category.DEFAULT'])
('com.android.contacts.socialwidget.SocialWidgetConfigureActivity', 'action', [u'android.intent.action.APPWIDGET_PICK'])
('com.android.contacts.NonPhoneActivity', 'action', [u'android.intent.action.DIAL', u'android.intent.action.MAIN', u'android.intent.action.VIEW', u'android.intent.action.CALL_BUTTON'])
('com.android.contacts.NonPhoneActivity', 'category', [u'android.intent.category.DEFAULT', u'android.intent.category.BROWSABLE'])

-- Wrapping Up with Dex2Jar --

➜  app git:(master) ✗ ~/Tools/mobile/android/dex2jar/d2j-dex2jar.sh Contacts.apk
dex2jar Contacts.apk -> Contacts-dex2jar.jar