42
Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness © CCL Group Ltd. 2015-2016 1 Decompiling Android Crypto Apps For Fun and Evidence Alex Caithness OWASP/BCS Mobile & Malware Forensics Day 2016/01/22 Me (Briefly) Member of R&D team at CCL Background is mobile/embedded forensics Wrote Epilog, Dunk!, PIP, etc. Likes: Python Hex Editors Databases The command line Not a crypto expert But turns out you might not have to be…

Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

  • Upload
    vodiep

  • View
    232

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 1

Decompiling Android Crypto Apps For Fun and Evidence

Alex CaithnessOWASP/BCS Mobile & Malware Forensics Day

2016/01/22

Me (Briefly)• Member of R&D team at CCL• Background is mobile/embedded forensics• Wrote Epilog, Dunk!, PIP, etc.• Likes:

– Python– Hex Editors– Databases– The command line

• Not a crypto expert– But turns out you might not have to be…

Page 2: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 2

This Presentation (Briefly)• The problems posed by crypto apps• Why all may not be lost• Case studies of some apps we’ve worked on to suggest:

– Tools – Techniques– Skills to develop

The Problem• Cryptography

– Stops us from seeing data !– Users are increasingly paranoid about their data– Crypto/security becoming a selling point for the

average user– Increasingly common

Page 3: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 3

The Brightside• Decryption easier on the end-point than during transmission • If the device is able to view/access the data at least part of

the “keys” must be stored locally• Programmers can be lazy, stupid, greedy

– Doing crypto properly is hard– Only has to be “good enough” for most users– Or just has to look like it’s working

• We might be able to find a way in…

Types of Apps• App Lockers• File Lockers• Secure Messaging

– Secure always, or just during transmission?

Page 4: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 4

Decompiling• Reverse engineering based on observation of

behaviour alone is hard– Time consuming– Only ever going to be a really good guess

• Being able to read the code which does the work in the app gives a quicker, more definitive answer

Decompiling• Many programming languages are “compiled”

– The human readable/writable code is turned into instructions which a machine can execute more directly

• Decompiling takes the compiled instructions (eg. machine code, byte code) and turns it back into a (more) human readable form

Page 5: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 5

Decompiling• Compilation is usually not a reversible process

– What was originally written will not be recovered exactly

– Code layout, variable names can be lost– Optimisations performed by compiler may lead to a

set of instructions which are functionally similar but are performed in quite different ways

• Still requires interpretation and understanding

An Apology• This presentation will involve looking at and talking

about code (mostly Java)• Any important code snippets will be kept short and

explained• Besides, there’s never been a better time to learn to

program if you work in DF…

Page 6: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 6

Methodology• Acquire the APK• Decompile• Search code

– Hopeful searches and educated guesses– Based on stored data

• Navigate code to find key functional code • Reverse engineer

Getting the APK• .apk (Android Application Package) file • Installation package for an Android Application• Usually still resident on device under “data/app”• Can be acquired using a (rooted) test device or from a 3rd

party app store• Actually just a .zip archive with a particular file/folder

structure

Page 7: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 7

classes.dex• Compiled Dalvik Byte-

code– All non-processor-specific

functionality here– Not human readable (not a

normal human anyway)– Usually compiled from Java

code

Page 8: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 8

baksmali• Baksmali is a disassembler for .dex files

– By “Jesusfreke”– http://code.google.com/p/smali– Decompiles to a project folder structure

containing “.smali” files (human readable byte-code)

baksmalijava -jar baksmali-2.0.5.jar classes.dex

Page 9: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 9

baksmali# static fields.field private static final DEVICE_ID_HASH_PREFS_KEY:Ljava/lang/String; = "deviceIdHash"

.field private static final PREFS_NAME:Ljava/lang/String; = "FBAdPrefs"

.field public static final TAG:Ljava/lang/String;

.field private static childDirected:Z

.field private static deviceIdHash:Ljava/lang/String;

.field private static final emulatorProducts:Ljava/util/Collection;.annotation system Ldalvik/annotation/Signature;

value = {"Ljava/util/Collection","<","Ljava/lang/String;",">;"

}.end annotation

.end field

baksmali# static fields.field private static final DEVICE_ID_HASH_PREFS_KEY:Ljava/lang/String; = "deviceIdHash"

.field private static final PREFS_NAME:Ljava/lang/String; = "FBAdPrefs"

.field public static final TAG:Ljava/lang/String;

.field private static childDirected:Z

.field private static deviceIdHash:Ljava/lang/String;

.field private static final emulatorProducts:Ljava/util/Collection;.annotation system Ldalvik/annotation/Signature;

value = {"Ljava/util/Collection","<","Ljava/lang/String;",">;"

}.end annotation

.end field

Not too friendly for a non-programmer (and not that friendly for a programmer).

Can find constants being assigned with relative ease, which might be useful

Page 10: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 10

classes.dex• smali is useful, but can be a slog to work

through• Being able to view as Java would be preferable

Dalvik to Java• Option 1 (dex2jar + jd/cfr):

– dex2jar is a utility to convert a .dex file into a Java .jar archive

• http://github.com/pxb1988/dex2jar

• Creates a jar file in the same directory as the classes.dex file

d2j-dex2jar classes.dex

Page 11: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 11

Dalvik to Java• Option 1 (dex2jar + jd/cfr):

– jd is a utility which decompiles a .jar file to Java• There is also a GUI version (jd-gui)• http://jd.benow.ca• Just drag and drop .jar file in the window!

Page 12: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 12

Dalvik to Java• Option 1 (dex2jar + jd/cfr):

– cfr is another option for decompiling the .jar file• http://www.benf.org/other/cfr• No GUI here…

• Creates a folder structure of .java source files• Decompiles slightly differently to jd

java –jar cfr_0_97 classes-dex2jar.jar –outputdir cfr-output

Dalvik to Java• Option 2 (jadx):

– jadx is a utility which converts directly from a .dexfile to Java source code

• https://github.com/skylot/jadx• Also has a GUI version

Page 13: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 13

Dalvik to Java• Option 3 (JEB)

– JEB is a commercially available decompiler with many additional features

– GUI Based– Not free (subscription based)– www.pnfsoftware.com/jeb

Page 14: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 14

Dalvik to Java• The output from each process is slightly different • My preference is usually for Jadx as I find the output

to be more readable and complete in most areas –but it can sometimes be a “bit crashy”

• In both cases I prefer to read the code in a “proper” IDE…

Export the source…

Page 15: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 15

“A Proper IDE”• IDE: Integrated Development Environment

– We’re not doing development per se– However, IDEs tend to have advanced features for viewing, navigating,

searching and annotating the code– Very useful while reverse engineering

• For Java I use “InteliJ IDEA”– From Jet Brains– https://www.jetbrains.com/idea/download– Free “Community Edition” is more than enough for our needs

Page 16: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 16

Page 17: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 17

And then just click next a few times. The defaults work fine for our needs

“A Decent Search Tool”• The other tool I find essential is a tool that can run

regular expression searches over our source folder– I like dnGrep

• https://dngrep.github.io/• Very flexible• Text, Xpath, Regular Expressions and Fuzzy/Phonetic text searching

Page 18: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 18

Case Study: Clean Master• Clean Master Security Antivirus AppLock• Application which (amongst other functionality)

allowed locking of applications behind a pattern lock• NB: not the same as the Android Lock Screen

pattern, but still a 3 x 3 grid• Caused an issue during examination

Case Study: Clean Master

2 3 4

1

2 3 4

1

Page 19: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 19

2 3 4

1

2 3 4

1

Case Study: Clean Master

Decompiling• Jadx was refusing to play nicely (being “a bit

crashy”)• Used combination of dex2jar and jd• Exported the code and loaded into IntelliJ

IDEA

Page 20: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 20

Searching The Source• Began with some hopeful generic search terms:

– lock– pattern

• Too many hits and lots of “noise” due to the use of Regex in the code base itself

• Filtered out the most common useless matches using negative lookaround:(?<!regex\.)pattern(?!\.compile)

Very promising! Imports for a class called “LockPatternView”, with a qualified name

Page 21: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 21

Searching The Source• Gives us a place in the

source to start working from

• But there are other clues we can look for…

Searching The Source

• Finding where the pattern is stored is useful– Could possibly derive from the code…– …or do what I did and just dig around in the extracted files

• Above snippet is found in the application’s preferences file• Fair to guess this might be the encoded pattern?

Page 22: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 22

Searching The Source

• Field names in preferences files, keys in databases etc. make great search terms in the decompiled source

• They will often be near to, or referenced by code which populates that field

Searching The Source• Search term:

– “lock_pattern”– (With the quotes; we’re searching for a string

literal, not just these words)

Page 23: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 23

Searching The Source

This looks really good – two functions, referencing that key in the preferences; one appears to set that value, the other gets it.

public void a(String paramString){

GlobalPref.a().b("lock_pattern", paramString);}

public String b(){

return GlobalPref.a().a("lock_pattern", "");}

The code which generates the encoded pattern must ultimately call this code

This could be our gateway into the code!

Page 24: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 24

public void a(String paramString){

GlobalPref.a().b("lock_pattern", paramString);}

public String b(){

return GlobalPref.a().a("lock_pattern", "");}

NB we will see a lot of things called a, b, c, d etc.When the code was compiled, many “symbols” (names of things) will have been stripped out.The de-compilation will give things simple names when nothing is found.

Right clicking the name of a function/method and selecting “Find Usages” should highlight all occurrences of this code being called in the codebase.

Page 25: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 25

This should work, and usually does… but due to the way the code was decompiled the IDE couldn’t resolve the search

So I used dnGrep in that folder:

public static void b(List<LockPatternView$Cell> paramList){

if (paramList == null);while (paramList.size() == 0)

return;String str1 = a(paramList);String str2 = d(str1);com.ijinshan.c.a.a.a("LockPattern", "save pattern, " + str1 + ", " + str2);d.a().a(str2);

}

This is where the search led.

A method which takes in a list of “LockPatternView Cells” and ends up setting the lock_pattern value using the method we saw previously.

Page 26: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 26

Reverse Engineering The Algorithm

public static void b(List<LockPatternView$Cell> paramList){

if (paramList == null);while (paramList.size() == 0)

return;String str1 = a(paramList);String str2 = d(str1);com.ijinshan.c.a.a.a("LockPattern", "save pattern, " + str1 + ", " + str2);d.a().a(str2);

}

This code is just checking that the list of “LockPatternView Cells” isn’t empty.

Not interesting, let’s ignore it!

Reverse Engineering The Algorithm

public static void b(List<LockPatternView$Cell> paramList){

String str1 = a(paramList);String str2 = d(str1);com.ijinshan.c.a.a.a("LockPattern", "save pattern, " + str1 + ", " + str2);d.a().a(str2);

}This code is just performing some logging.

Not interesting, let’s ignore it!

Page 27: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 27

Reverse Engineering The Algorithmpublic static void b(List<LockPatternView$Cell> paramList){String str1 = a(paramList);String str2 = d(str1);d.a().a(str2);

}

This is the interesting functional code…

1. A list of “LockPatternView Cells” comes in.2. We do “a” to it, which gives us a string.3. We do “d” to that string, which turns it into another string.4. We store that string using the method we originally found.

Along with “Find Usages”, “Go To Declaration” are your best friends.

Page 28: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 28

public static String a(List<LockPatternView$Cell> paramList){

if (paramList == null)return "";

int n = paramList.size();String str = "";

for (int i = 0; i < n; i++){

LockPatternView$Cell localCell = paramList.get(i);str = str + String.valueOf(3 * localCell.a() + localCell.b());

}return str;

}

Most of this code is setting up a loop to get each “LockPatternView Cell” in the list.For every item in the list, a calculation is being performed on that item, and the result is added to a string.

Reverse Engineering The Algorithmstr = str + String.valueOf(3 * localCell.a() + localCell.b());

This is the calculation:Each “LockPatternView Cell” has a value “a” and a value “b”“a” is multiplied by 3“b” is added to the result

Looking in the code for LockPatternView$Cell we find the following, which makes the meaning of “a” and “b” clear:

public String toString(){return "(ROW=" + a() + ",COL=" + b() + ")";

}

Page 29: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 29

Reverse Engineering The Algorithm

2 3 4

1

0 1 2

0

1

2

(Row x 3) + Col

(2 x 3) + 0 = 6(1 x 3) + 0 = 3(1 x 3) + 1 = 4(1 x 3) + 2 = 5

"6345"

Reverse Engineering The Algorithmpublic static void b(List<LockPatternView$Cell> paramList){String str1 = a(paramList); // string of number (3row+col)String str2 = d(str1);d.a().a(str2);

}

This is the interesting functional code…

1. A list of “LockPatternView Cells” comes in. 2. We do “a” to it, which gives us a string of numbers (3 x row) + col3. We do “d” to that string, which turns it into another string.4. We store that string using the method we originally found.

Page 30: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 30

Reverse Engineering The Algorithmprivate static String d(String paramString){

if (TextUtils.isEmpty(paramString))return "";

return b(paramString);}

More mostly boring code, checking if the string is empty

If it’s not we do “b” to the string…

Reverse Engineering The Algorithmpublic static final String b(String paramString){

if (paramString == null)return "";

if (paramString.length() == 0)return "";

BigInteger localBigInt1 = new BigInteger(paramString.getBytes());BigInteger localBigInt2 = new BigInteger("011100100010101001110101110110");

return localBigInt2.xor(localBigInt1).toString(16);}

Again, more boring “is the string empty?” code…

Ignore it!

Page 31: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 31

Reverse Engineering The Algorithmpublic static final String b(String paramString){

BigInteger localBigInt1 = new BigInteger(paramString.getBytes());BigInteger localBigInt2 = new BigInteger("011100100010101001110101110110");

return localBigInt2.xor(localBigInt1).toString(16);}

Two “BigIntegers” (just big numbers) are created:• One is generated by converting the pattern string into the underlying

bytes (encoded as UTF-8)• The other is the number: 011100100010101001110101110110 (that’s

not binary, just a really big number with only 1’s and 0’s in)

Reverse Engineering The Algorithm

These two big numbers are XOR’d together, and the result is converted to its hexadecimal representation.

NB. The presence of big numbers and “XOR” operations is a dead giveaway that some form of encryption/encoding is going on

public static final String b(String paramString){

BigInteger localBigInt1 = new BigInteger(paramString.getBytes());BigInteger localBigInt2 = new BigInteger("011100100010101001110101110110");

return localBigInt2.xor(localBigInt1).toString(16);}

Page 32: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 32

Reverse Engineering The Algorithmpublic static void b(List<LockPatternView$Cell> paramList){String str1 = a(paramList); // string of number (3row+col)String str2 = d(str1); // encrypted using xord.a().a(str2); // store in preferences file

}

This is the interesting functional code…

1. A list of “LockPatternView Cells” comes in. 2. We do “a” to it, which gives us a string of numbers (3 x row) + col3. We do “d” to that string, which turns it into another string (encoded by

XOR’ing the bytes against a big long number)4. We store that string using the method we originally found.

Reverse Engineering The Algorithm

• And that is how this value ends up here• To decrypt it we reverse the algorithm:

– Read the value as an integer– XOR it with 011100100010101001110101110110– Convert the result into bytes– Convert bytes into a string (should be a string of numbers)– Divide each number by 3 (discarding the remainder) to get the row – The remainder gives us the column

Page 33: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 33

Case Study: Photo Locker• App by “HandyApps” which protects photos

– Actually uses encryption, which is a surprise!– A Video Locker application is also available (which appears

to work identically)

• Jadx worked best for decompiling this app – Other methods worked (insofar as they didn’t crash) but

output was ugly

Encrypted files are usually found on the shared media partition in a folder called “.PL”

Encrypted files are given a “.pl” extension at the end of their file name.

Curiously, only the start of the file is encrypted (confirmed by entropy analysis, presence of expected JPEG file footer FFD9, and later by inspecting the code)

Page 34: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 34

Case Study: Photo locker

Case Study: Photo Locker• A cursory glance in the preferences file also reveals

this promising looking string to search the code for:

Page 35: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 35

Searching The Code• The regex search along with a number of

“Find Usage” + “Go To Declaration” led to two files

• “KeyEncryption” governs the encryption/decryption the Secret Key

• “Encryption” governs the encryption and decryption of the photos– The key used is derived from the decrypted Secret

key

Searching The Code

Page 36: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 36

Searching The Code

This is where we confirmed that only the first 2KB of the file is actually encrypted.

Searching The Code

The header of the file gives us details of the encryption scheme:• AES• Counter Mode• No Padding• Counter initial value: 0xfedcba9876543210

We do not have the block size (but we can work that out when we know the key size)

Page 37: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 37

public static String generateKey(String userEmail) throws ResultErrorException {try {

byte[] keySpec = (Salt + userEmail + password).getBytes("UTF-8");MessageDigest sha = MessageDigest.getInstance("SHA-1");Log.d("ENC", sha.getProvider().getName());byte[] bytes = Arrays2.copyOf(sha.digest(keySpec), (int)Response.BYE);return Base64.encodeToString(bytes, false);

} catch (UnsupportedEncodingException e) {e.printStackTrace();throw new ResultErrorException();

} catch (NoSuchAlgorithmException e2) {e2.printStackTrace();throw new ResultErrorException();

}}

This function (defined in Encryption): • Takes in the user’s email (which is what the SECRET_KEY turns out to be!) • Returns the key for the file encryption.

public static String generateKey(String userEmail) throws ResultErrorException {try {

byte[] keySpec = (Salt + userEmail + password).getBytes("UTF-8");MessageDigest sha = MessageDigest.getInstance("SHA-1");Log.d("ENC", sha.getProvider().getName());byte[] bytes = Arrays2.copyOf(sha.digest(keySpec), (int)Response.BYE);return Base64.encodeToString(bytes, false);

} catch (UnsupportedEncodingException e) {e.printStackTrace();throw new ResultErrorException();

} catch (NoSuchAlgorithmException e2) {e2.printStackTrace();throw new ResultErrorException();

}}

Lots of boring error handling and logging code - let’s ignore it!

Page 38: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 38

Reverse Engineering The Algorithm

byte[] keySpec = (Salt + userEmail + password).getBytes("UTF-8");MessageDigest sha = MessageDigest.getInstance("SHA-1");byte[] bytes = Arrays2.copyOf(sha.digest(keySpec), (int)Response.BYE);return Base64.encodeToString(bytes, false);

private static final String Salt = "HANDY_APPS";private static final String password = "secure locker";

Reverse Engineering The Algorithm

byte[] keySpec = (Salt + userEmail + password).getBytes("UTF-8");MessageDigest sha = MessageDigest.getInstance("SHA-1");byte[] bytes = Arrays2.copyOf(sha.digest(keySpec), (int)Response.BYE);return Base64.encodeToString(bytes, false);

• Combine the salt, user’s email and password• eg. “[email protected] locker”

• Get the bytes that make up this string (encoded as UTF-8)

private static final String Salt = "HANDY_APPS";private static final String password = "secure locker";

Page 39: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 39

Reverse Engineering The Algorithm

byte[] keySpec = (Salt + userEmail + password).getBytes("UTF-8");MessageDigest sha = MessageDigest.getInstance("SHA-1");byte[] bytes = Arrays2.copyOf(sha.digest(keySpec), (int)Response.BYE);return Base64.encodeToString(bytes, false);

• Create a SHA-1 Algorithm

private static final String Salt = "HANDY_APPS";private static final String password = "secure locker";

Reverse Engineering The Algorithmbyte[] keySpec = (Salt + userEmail + password).getBytes("UTF-8");MessageDigest sha = MessageDigest.getInstance("SHA-1");byte[] bytes = Arrays2.copyOf(sha.digest(keySpec), (int)Response.BYE);return Base64.encodeToString(bytes, false);

• Get the digest (the hash) of the keyspec• Copy only the first 16 bytes (also tells us the block size)

• “Response.BYE” is a constant from a standard email library, the value it represents is 16.

• This appears to be an attempt to obfuscate the code (not a very good attempt)

• (The key is then converted to Base64, but will be converted back for use)

Page 40: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 40

Decrypting the Files• With the derived key and encryption settings

we are able decrypt the files– (Well the first 2048 bytes anyway…)

Decrypting the Files

Page 41: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 41

Summary• Encryption can make you feel sad• But programmers are lazy and often don’t

know how to use encryption properly• And even if they do, breaking encryption at an

end point is much easier than in transmission

Summary• Decompiling Apps is sometimes an “inexact science”

– use the tool which works best each time• Make searches based upon observed data • Or just guess, that works sometimes too• Working in a proper IDE is much easier than fumbling

around in a text editor• Learning to program is a good idea (and fun)

Page 42: Decompiling Android Crypto Apps For Fun And Evidence - OWASP · Getting the APK • .apk(Android Application Package) file • Installation package for an Android Application •

Decompiling Android Crypto Apps for Fun and Evidence – Alex Caithness

© CCL Group Ltd. 2015-2016 42

Contact• Alex Caithness• [email protected]• 01789 261 200