Reverse engineering refers to the process of taking something apart to see how it works, whether it’s a physical object such as a lock or in this case, a mobile application. Decompiling is a form of reverse engineering in which a mobile app is analyzed by looking at its source code. A decompiler program examines the binary and translates its contents from a low-level abstraction to a higher-level abstraction.

The NowSecure services team frequently performs reverse engineering on mobile apps to uncover security vulnerabilities and privacy flaws. We rely on a mix of custom and open-source tools in our pen testing, including decompilers. This tutorial will help you master the basics of analyzing an Android app and what to look for.

An Android binary is called an APK, which stands for Android Package Kit. The APK contains application data in the form of zipped Dalvik Executable (.dex) files. DEX files consist of the following components:

  • File Header
  • String Table
  • Class List
  • Field Table
  • Method Table
  • Class Definition Table
  • Field List
  • Method List
  • Code Header
  • Local Variable List

For further information on .dex files, refer to the official Android documentation.

A decompiler is a tool that takes the contents of the APK and attempts to show the original code that was used to build the different functionalities of the app. Although this process is fairly consistent, in some special cases the decompiler might fail to reverse a small part of the application.

There are far more aspects of reverse engineering than can be covered here, so this blog will zero in on some of the most common issues we find in production Android apps when we dig in with a decompiler. While there are many decompilers to choose from, I prefer jadx-gui because it’s a simple yet effective tool that has a user-friendly interface. We will use it to analyze the “InsecureBankv2.apk”, an open-source Android application that purposefully contains many vulnerabilities.

Getting Started Analyzing the APK

Open the APK using jadx-gui and you’ll notice a menu on the left hand side of the screen containing some dropdown sub-menus. This is common across all Android applications.

 

 
Each dropdown menu is mostly self explanatory.The “Source code” section contains the different files that make up the application’s code. The “com” usually contains the main part of the application code, including core functionalities, while other sections include supportive/complementary components such as libraries, frameworks and other resources utilized to create the application. The “Resources” section contains app assets, versions, certificates, properties, the Android Manifest, APK signature info, etc.

Exploring the Android Manifest

Let’s start by analyzing the app’s manifest, AndroidManifest.xml. This file is an important part of the application because it provides data about the application structure and metadata, its components and the requirements. This is done by establishing user permissions, app activities, intents, actions, etc. Double clicking on the AndroidManifest.xml file in the left hand side menu opens the following file:

Notice how it’s segmented into different sections. The first few lines contain the different user permissions declared by the application. These will always be variable and dependent of the app that you’re trying to reverse engineer but it’s always good practice to make sure the app isn’t requesting more permissions than it should have or needs to use. For example, we’ve seen many apps request location permissions without even having a feature that requires the user’s location. This usually ends up in some kind of user personal information being disclosed and, in most cases, is not even done intentionally by the developer.

Other important things to look out for in the manifest are the debuggable and the allowBackup flags. As the name suggests, the first one refers to the app being in debug mode, meaning it’s possible to attach a debugger to the application’s process and execute arbitrary code. For the last few years, Google has not allowed apps that have this flag enabled to be published in the Play Store. However, it’s still important to take this into account when developing an application, especially since builds are often exchanged between developers. If one falls into the wrong hands, it could have negative consequences. The second flag, allowBackup, defines whether application data can be backed up and restored by a user who has enabled USB debugging. This means that hackers connecting to a device via adb can easily obtain any application data that is stored on the device, including personal data on private storage.

As you see in the screenshot below, the Android Manifest shows that the InsecureBankv2 app has both of these flags enabled.

The Manifest may also include exported activities and content providers. These allow external applications to access data in the application, which is why it’s always important to check for activities listed as true because these can potentially leak user data to other applications. Activities that are not intended to be accessed by other applications must always be set to false. In the sample application in question, we can see that multiple activities are exportable:

Searching for Hardcoded Values

Next, look for hardcoded credentials — that is, anything hardcoded in an app such as usernames, session tokens, secret keys, et). Attackers can often easily access this information and this app is no exception.

Hardcoded credentials can be found most anywhere within the app so we recommend using jadx’s search function to look for these values. I usually start by looking for hardcoded secret keys. These can be somewhat easy to recognize as they will usually be stored in an array of bytes. In this case, searching for the word ‘secret’ reveals a glimpse of what we might find in the app.

 

 
Be sure to go over every result especially when searching for a term like ‘secret’ because it likely reveals sensitive values. Navigating to com.android.InsecureBankv2.CryptoClass shows some valuable information, including an initialization vector for one of the utilized cryptography methods and the crypto key.

 

 
Cool! We have a bad crypto practice finding. While many other crypto-related findings here could capture our attention, we’ll move along now to cover other things.

Cracking Fun with Frida & Radare: Mobile App & IoT Edition

Cracking Fun with Frida & Radare

Analyzing WebViews in an App

WebViews are an embeddable browser that a native application can use to display web content. They might not be implemented in every application but when they are, they can provide a risky attack vector. Some important parameters/flags to test on WebViews are setWebContentsDebuggingEnabled(true), clearCache(true), and EnableSafeBrowsing. The first one allows inspections of WebView content from a remote browser, so it must always be set to false. Searching for this returns no results so we don’t see this being utilized in this test application, but don’t forget to take it into account when reversing other apps. The second one clears the WebView caches from the client device. This can mitigate issues relating to sensitive data stored on the local file system. We actually do see this one used by one Google library imported by the application — not bad!

 

 

Finally, EnableSafeBrowsing displays warnings when a compromised or known phishing website is loaded in the WebView. We don’t see this one utilized in the application either. By further analyzing WebViews in this app, we find that the com.android.insecurebankv2.ViewStatement class makes heavy use of WebViews. One thing that captures our attention is the file loading mechanism, which doesn’t seem to be very secure due to lack of proper checks and validations. This class also enables JavaScript, meaning that a potentially vulnerable script could be uploaded into the app for exploitation.

Conclusion

Exploring the app will definitely yield many other related findings. However, we won’t go into too much further detail because this is an intentionally vulnerable app and we could spend a lot of time just playing around with terms and analyzing different classes for vulnerabilities. Other than searching for hardcoded data, you could also search for vulnerable functions being utilized, such as bad network functionalities, JavaScript interfaces, bad device memory management, lack of input validation on certain functions, and bad cryptography, to name a few.

Use the ‘@’ character in the search function to search for all the places where a certain function of interest is called. Repeat the process until you’re satisfied with your results. Keep in mind this will depend on the application that you’re trying to reverse engineer. Remember to always be a critical thinker and evaluate the situation based on the app you’re reverse engineering. The possibilities are endless!

For those who lack the time or expertise to reverse engineer a mobile app to pinpoint mobile app vulnerabilities to remediate, NowSecure has solutions and services that can help. The NowSecure Platform automated mobile appsec testing solution reduces the labor entailed in assessing apps and provides consistency. Our professional services team offers mobile application security training and is available to conduct comprehensive mobile penetration testing. Consult this useful checklist for evaluating mobile application security companies to perform mobile application penetration tests.

What to read next:

Jorge Damian

linkedin icon twitter icon

Application Security Analyst

Jorge Damian is an Application Security Analyst at NowSecure. He conducts penetration testing of mobile apps on Android and iOS and he enjoys breaking things in them and explaining how he did it to customers. Jorge holds a Master's Degree in Cybersecurity from the University of Maryland.