Transcript
Page 1: How to reverse engineer Android applications

How to reverse engineer Android applications

Finding Vulnerabilities through Reverse Engineering

Hasso Plattner Institute, Potsdam

Hubert Hesse, Lukas Pirl,

Christoph Matthies, Conrad Calmez

using a popular word game as an example

??Images: “Freepik” on flaticon.com (CC BY 3.0), Google (CC BY 3.0)

Page 2: How to reverse engineer Android applications

1 Get the .apk

23 4Extract the .apk

5Decompilation to Smali

Debugging

6Putting it together7 8Automation

Proxy

Decompilation to Java

Page 3: How to reverse engineer Android applications

Our Example—a word game

● Top 10 word game in 145 countries (as of July 2014)

● More than 10.000.000 installs● Over 50 million players● Play online (with friends)● 14 languages● Free and premium version

Page 4: How to reverse engineer Android applications

1:58 0 points

S N B I

L U SF

E I T

T E RP

A

Page 5: How to reverse engineer Android applications

1:58 15 points

S N B I

L U SF

E I T

T E RP

A

FLUT +15

Page 6: How to reverse engineer Android applications

● APK (application package file), archive file, based on JAR format

● Similar to Deb packages (in Ubuntu) or MSI packages (in Windows)

● Contains program code, resources, assets, certificates, and manifest file

● Can’t be directly downloaded from App Store

1Get the .apk

Download using online “APK Downloader” (http://apps.evozi.com/apk-downloader/)

- or -

Install on device and download using SDK tools(adb pull <app_path> downloaded.apk)

Page 7: How to reverse engineer Android applications

2Extract the .apk

● Normal decompression using unzip fails● Special tool: APKTool

○ Standard is APKTool 1.5.2. (not able to recompress correctly) (https:

//code.google.com/p/android-apktool/downloads/list)

○ APKTool 2.0.0 Beta 9 works(http://connortumbleson.com/2014/02/apktool-2-0-0-beta-9-released/)

Decrompressing:

apktool d -d game.apk -o outdir

Page 8: How to reverse engineer Android applications

2Extract the .apk

Page 9: How to reverse engineer Android applications

2Modifying resources

● Change arbitrary resources● Repack into .apk file and install

Recrompressing:

apktool b -d outdir -o com.company.game.free_patch.apk

● Recompression works, Android fails with “can’t install”, wrong certificate○ APKTool tries to reuse as much as possible, doesn’t

recompute signature

Page 10: How to reverse engineer Android applications

2Manually sign repacked apk:

● Create custom CA● Java JAR Signing and Verification Tool

(http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html)

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore com.company.game.free_patch.apk alias_name

Modifying resources

Page 11: How to reverse engineer Android applications
Page 12: How to reverse engineer Android applications

.apk contains compiled code

● Dalvik bytecode interpreted by the Dalvik Process virtual machine

● Stored in .dex (Dalvik EXecutable) files

APKTool translates this to “smali” (https://code.google.com/p/smali/)

● Abstraction of bytecode, closer to Java● Dalvik opcodes (http://s.android.com/tech/dalvik/dalvik-bytecode.html)

● Can be edited directly

3Decompilation to Smali

Page 13: How to reverse engineer Android applications

.class public LHelloWorld;

.super Ljava/lang/Object;

.method public static main([Ljava/lang/String;)V

.registers 2

sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

const-string v1, "Hello World!"

invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

return-void

.end method

3Smali Hello World

Page 14: How to reverse engineer Android applications

Interactive debugging

● Set debuggable=”true” in AndroidManifest.xml○ Repack using APKTool

● Need to connect smali sources to binary● Workaround: pretend we have valid Java code

4Debugging

<application android:allowBackup="true" android:hardwareAccelerated="true"

android:icon="@drawable/launcher_icon" android:label="@string/app_name"

android:name="com.company.game.core.GameApplication" android:theme="

@style/Theme.GameTheme" android:debuggable="true">

Page 15: How to reverse engineer Android applications

a=0;// .class public abstract La;a=0;// .super Ljava/lang/Object;a=0;// a=0;// a=0;// # instance fieldsa=0;// .field protected final a:Ljava/lang/Object;a=0;// a=0;// .field private final b:Landroid/os/Handler;a=0;//

4Debugging

Smali code in commentsPlaceholder

Java

Page 16: How to reverse engineer Android applications

Two ways to obtain java code

● Convert .dex files to .jar○ Use standard java bytecode decompilers

● Disassemble .dex directly to .java

5Decompilation to Java

Page 17: How to reverse engineer Android applications

Using dex files

● Androguard (https://code.google.com/p/androguard/)

○ Maps DEX format into full Python objects○ Works in memory (My 4GB machine wasn’t enough)

○ Doesn’t immediately dump code into Java files

5Decompilation to Java

Page 18: How to reverse engineer Android applications

Using jar files

● dex2jar (https://code.google.com/p/dex2jar/)

○ dex2jar, jar2dex, apk-sign○ Supports recreating .dex from Java

● JD-GUI (http://jd.benow.ca/)

○ Popular jar-decompiler○ Works 100% with “Hello World” app

5Decompilation to Java

Page 19: How to reverse engineer Android applications

Combining Java decompilation and Smali

● Java more readable than Smali● Unfortunately Java decompilation not

100% perfect

○ Invalid Java constructs or only

method signatures○ Cannot recompile from Java sources

6Putting it together

Page 20: How to reverse engineer Android applications

private void fixSpecialChars() { int i; char ac[]; int j; int k; i = 0; ac = tiles; j = ac.length; k = 0;_L9: if(k >= j) break MISSING_BLOCK_LABEL_161; ac[k]; JVM INSTR lookupswitch 6: default 80 // 40: 125 // 41: 137 // 47: 149 // 91: 89 // 92: 101 // 93: 113; goto _L1 _L2 _L3 _L4 _L5 _L6 _L7_L4: break MISSING_BLOCK_LABEL_149;_L1: break; /* Loop/switch isn't completed */_L5: break; /* Loop/switch isn't completed */_L10: i++; k++; if(true) goto _L9; else goto _L8_L8:

6When Decompilation failsan example

Goto not supported in Java

Bare JVM instructions

Page 21: How to reverse engineer Android applications

Combining Java decompilation and Smali

● Approach: Use multiple Java decompilers○ They tend to fail in different places

6Putting it together

1. Find interesting parts in Java source2. Check corresponding smali sources3. Edit those

Page 22: How to reverse engineer Android applications

protected void roundEnd(boolean paramBoolean){// …this.resultData.setTotalScore(this.totalScore);// … startRoundSummary(); if (!this.isPractice) { this.currentRound.setWordsInRound(this.resultData.getMoves().size()); // … this.currentRound.setPlayer1Moves(GameHelper.encodeMoves(this.resultData.getMoves())); this.currentRound.setPlayer1Score(this.totalScore); // …

6Manipulating the score

Opportunities for manipulation

● Server validation disallows this

Page 23: How to reverse engineer Android applications

a=0;// sget-boolean v0, Lcom/company/game/core/statics/Statics;->DEBUGGING:Z a=0;// a=0;// #v0=(Boolean);-a=0;// if-eqz v0, :cond_0+a=0;// #if-eqz v0, :cond_0 a=0;//

6Enable Loggingpublic class Toolkit{ // …

public static void Logw(String s, String s1) { if(Statics.DEBUGGING) Log.w(s, s1); } // …

Page 24: How to reverse engineer Android applications

a=0;// # static fields a=0;// .field public static ROUND_DURATION_IN_SECONDS_FOR_NORMAL_GAME:I a=0;// .field public static ROUND_DURATION_IN_SECONDS_FOR_TUTORIAL:I a=0;// a=0;// .method static constructor <clinit>()V a=0;// .locals 1 …-a=0;// const/16 v0, 0x78+a=0;// const/16 v0, 0x12c a=0;// a=0;// #v0=(PosByte); a=0;// sput v0, Lcom/company/game/core/statics/GameStatics;->ROUND_DURATION_IN_SECONDS_FOR_NORMAL_GAME:I

6More time per round

120s

300s

Page 25: How to reverse engineer Android applications

public static boolean allowPremiumContent(PremiumType premiumtype, Context context){ if(premiumIsPurchased(context)) return true; synchronized(lock) { if(!isLicensed(context)) break MISSING_BLOCK_LABEL_31; } return true;

6Getting Premium

a=0;// .line 129-a=0;// invoke-static {p0}, Lcom/company/game/util/PremiumCampaignHelper;->premiumIsPurchased(…;)Z+a=0;// # invoke-static {p0}, Lcom/company/game/util/PremiumCampaignHelper;->premiumIsPurchased(…;)Z a=0;// -a=0;// move-result v0+a=0;// # move-result v0 a=0;// -a=0;// #v0=(Boolean);-a=0;// if-eqz v0, :cond_0+a=0;// #v0=(One);+a=0;// # if-eqz v0, :cond_0

Page 26: How to reverse engineer Android applications

6Getting Premium

free version premium (stats unlocked, no ads)

Page 27: How to reverse engineer Android applications

7Proxy

Route all app traffic through custom proxy

● Used MitMProxy (https://github.com/mitmproxy/mitmproxy)

● Retrieve real server URL via Wireshark● Redirect app traffic via /etc/hosts on device● Custom SSL certificate

○ Install own CA in device○ No certificate pinning

● Avoid compressed responses via HTTP header○ Accept-Encoding: gzip;q=0,deflate,sdch

Page 28: How to reverse engineer Android applications

7Proxy

AES encryption

● Shared key in decompiled code● No key derivation function● AES initialization vector in HTTP header

○ Payload-session: 2e2f6a61642f7372…○ Unencrypted// file APIConnector.javaprivate static byte sharedKey[] = { 57, -116, 126, 39, 116, -25, -95, -106, -81, 48, -33, -19, 120, 118, 35, 40, 66, 126, 31, 30, -83, 76, 31, 93, 13, -122, -50, 68, -108, -114, 28, -80};

Page 29: How to reverse engineer Android applications

SSLMitMProxy SSLHTTP

Server by “aLf “, thenounproject.com (CC BY 3.0 US)Spy by “Hopstarter ”, iconarchive.com (CC BY-NC-ND 4.0)

#! python

#decrypt AES#using IV

7ProxyHeader: AES IV

AES payload

HTTP

# /etc/hosts

# redirect# to proxy

Page 30: How to reverse engineer Android applications

7Proxy{ "cacheTimestamp": "1405377910521", "userId": "0", "conversationId": "-1", "player1MostWordsInRound": "32", "id": "6602198229545556683", "player1Score": "214", "player1LongestWord": "HEAPS", "player1User": { "username": "username", "ranking": "0", "premium": "false", "recruits": "0", "deleted": "false", "newUser": "false", "bestScoreInMatch": "0", "userId": "3005807464", "bestScoreInRound": "0", "online": "false", "facebookConnected": "false", "avatarId": "0", "matchesPlayed": "0", "useFacebookImage": "false", "mostWordsInRound": "0" },

{"rounds": [ { "seed3": "14657688", "player2MoveErrors": "0", "gameId": "6602198229545556683", "player2SwipeDistance": "681", "player2Moves": "1AB2BAE2EAB216227612AEF2DA73840127652567354013DAB723673B7654EAB72", "player1MoveErrors": "19", "player2Done": "true", "seed1": "2073207065", "seed2": "680974433", "player1SwipeDistance": "1608", "board": { "bonus": [" ", " ", " ", " ", " ", " ", "D", " ", " ", " ", " ", " ", " ", " ", " ", "T" ], "board": ["A", "T", "E", "H", "E", "P", "O", "T", "H", "S", "A", "S", "T", "F", "T", "E" ], "words": [ "TATE", "SOTS", "HOST", "SAPS", "FATSOS", …

Server responserequest size up to 100kB

Page 31: How to reverse engineer Android applications

8Automation

Play the game automatically

● Generic external approach○ No modification of binary necessary○ Works for any app

Monkeyrunner (http://developer.android.com/tools/help/monkeyrunner_concepts.html)

● Test apps at the functional/framework level● Able to simulate keystrokes, take screenshots● Python bindings

Page 32: How to reverse engineer Android applications

8Obtain all possible words to play correctly

● apk contains .jet “dictionary” for each language

● Btw, also a wordlist (probably) used to check for cheaters

Automation

Page 33: How to reverse engineer Android applications

8Automation

Ruzzle .jet files

● Binary files● Trie / Radix tree structure● Optimal for the way the game

is played● No duplicate encoding

of characters● List of all excepted

words constructable

G

GA

GAM

GAME

GO

GOD GOT

G

O

D T

A

M

E

Page 34: How to reverse engineer Android applications

8Automation

Achieving the highscore

● Get all 16 letters○ Input by hand / screenshot + OCR

● Find all valid words using the extracted dictionary

● Simulate keystrokes for found words

○ Actually not enough time to enter all

valid words

Page 35: How to reverse engineer Android applications

8Automation

DEMO

Page 36: How to reverse engineer Android applications

Achievements

Found possibilities to:

✓ Enable logging✓ Unlock premium features✓ Achieve insanely high score through automation✓ Extract protocol via man-in-the-middle attack

Page 37: How to reverse engineer Android applications

Backup slides

Page 38: How to reverse engineer Android applications

Pinned certificate(installed at dev. time)

AppServer

Get current server certificate

1

Compare current and pinned certificates

2

if identical: establishconnectionelse: reject

3

Certificate Pinning


Top Related