Getting Started Into Android Security Part 2

  • Home
  • Getting Started Into Android Security Part 2
Getting Started Into Android Security Part 2
Getting Started Into Android Security Part 2
Getting Started Into Android Security Part 2
Getting Started Into Android Security Part 2
Getting Started Into Android Security Part 2

Previously we discussed Android Basics, Reversing APK & LAB Setup for Android Security Testing. We are considering that you are aware of all the previous concepts. If you haven’t read it, check it out now, click here and get back to this.

Introduction

Static analysis is a process of testing applications without executing them; only the code is examined. In addition to predefined guidelines, code should be tested for technical & logical errors. During static analysis, we look for Permissions, Configurations, Cryptographic issues, Hardcoded sensitive data, and various things that will increase the attack surface for dynamic analysis.

Missing Security Controls

Lack of Code Obfuscation

Code obfuscation is modifying an executable to make it useless to hackers but still fully functional. The process can change the actual method statement or metadata, but it does not change the program’s output.
Here is a simple example of what code looks like after and before obfuscation –

Code Obfuscation & Deobfuscation
Code Obfuscation & Deobfuscation

When the APK has been de-compiled, we are ready to analyze the code, but first, check if the code is obfuscated or not. It is a security issue if the code is not obfuscated because anyone can read, manipulate, and reverse it. If the code is obfuscated, it becomes challenging to read; even if it is obfuscated, we can de-obfuscate it by using tools such as JADX, or we can perform Manual De-obfuscation

Developers can use the Proguard for obfuscation, ultimately a precaution against reverse engineering.

Missing Root Detection

It is essential for security teams and developers to enable apps to detect root detection. Hackers often root their devices or use their rooted devices to access sensitive user data and other secrets stored in the app’s source code. Detecting this vulnerability is essential to the security of your app, as it is challenging to ensure system security and various protections after gaining root privileges.
In the following example, you can see how apps implement root detection; this is not only the way to implement some apps, not even launch on a rooted device.

Root Detection Implementation
Root Detection Implementation

There are several methods of root detection, but these are some developers can use to implement root detection –

Methods of Root Detection

If the root detection has been implemented, we need to bypass it, there are several methods to bypass, including reverse engineering, Xpose framework, Frida and objection, etc. In this blog, we will bypass root detection using Frida Framework –

Quick Setup for Frida –

  1. Enter this command to install Frida – pip install Frida && pip install objection && pip install Frida-tools
  2. Identify device architecture using command – adb shell getprop ro.product.cpu.abi
  3. Once you have architecture, download the Frida server from here
  4. Extract using xz command – xz -d Frida-server-xxxx.android-arm.xz
  5. Rename it to Frida-server command – mv Frida-server-xxxx.android-arm.xz Frida-server
  6. Push Frida server into /data/local/tmp using command – adb push Frida-server /data/local/tmp
  7. Assign execute permission – adb shell "chmod 755 /data/local/tmp/frida-server"
  8. Start server using – adb shell "/data/local/tmp/frida-server &"
  9. Verify using Frida-ps -U

If you faced any errors while setting up Frida, you could just go through https://github.com/frida/frida/issues hope this will solve your problem.

Let’s try to bypass –

  1. Use Frida-ps -Ua to
Frida process list

2. frida -U -l frida-antiroot.js -f com.infrasoft.uboi --no-pause

you can download frida-antiroot.js from here

Root Detection Bypass Using Frida
Root Detection Bypass Using Frida

3. Check app we have successfully bypassed root detection –

Root Detection Bypassed
Root Detection Bypassed

Not every time will this script work for bypassing root detection bypass accordingly; how source code has implemented root detection technique you have to modify the script, or you can write your own. If you wish to learn more about Frida, please visit here

SSL Pinning does not implement

SSL certificate pinning is designed to prevent dangerous and complex security attacks. This security measure modifies the identity of the mobile app’s trusted certificate and blocks unknown documents from suspicious servers. Applications with fixed SSL certificates rely not on the CA’s storage license but on the stored credential. Using this technique, you can pin an SSL certificate host (a list of trusted certificates) to your application during development and compare the server certificate with the list at run time.

If SSL pinning is not implemented, then all the communication between the application and the server could be intercepted by an attacker. Because of this, the attacker can craft malicious requests to the server and look for multiple vulnerabilities. Additionally, automated attacks can be mounted against the application with the help of a proxy tool. 

Ways to Implement Root Detection

By using two-way SSL authentication, SSL Pinning Bypass can be prevented. This technique allows the application to act as an SSL client and send its certificate after the SSL server has validated it. Due to the complexity of two-way SSL, if we can prevent the modification or reverse engineering of the android application, that will prevent SSL Pinning bypasses via reverse engineering or hooking.

If SSL pinning has been implemented, we can bypass it. There are several methods to bypass SSL pinning, but here we go with simply Frida. As we have set up Frida, we move on to the next part, how to bypass SSL pinning using Frida.

  1. Download Frida SSL pinning bypass script from here and save it to fridascript.js
  2. use frida -U -l fridascript.js -f com.package.name to start
SSL Pinning Bypass Using Frida
SSL Pinning Bypass Using Frida

3. Let’s Intercept the traffic –

Application for Test
Application for Test

4. Open burpsuite history and check request

Credential’s Sniffing

In this way, we can bypass the SSL pinning and intercept the traffic of android apps.

Lack of Integrity Check

Android apps are compressed, packaged, and distributed as .apk files that resemble .jar or .zip files. These typically include your app’s compiled resources (compiled code, images, layouts, XML files, databases, etc.). The APK can be extracted using simple archiving software, and the compiled source code can be easily decompiled using free, open-source tools such as APKTool and Dex2Jar. Attackers can exploit this vulnerability and reverse the app if there is no mechanism for checking the code integrity.  

This is a simple example to show how we can reverse apk –

Follow the steps to reverse apk:

  • Use APK tool to decompile APK – apktool d com.example.app.apk
Decompile APK using apktool
  • Locate smali code by using cd /com.example.app/smali
Locate smali code directory
smali files list
  • Choose the file you want to change and open it with any editor and modify it here; we are taking a simple example by changing the error warning.
Change error warning string
  • Now we need to build it again, so use apktool b [folder name] -o modifiedAPK.apk
Rebuild apk using apktool
  • If we directly try to install then we get a warning because our apk is not signed yet; let’s try
Install apk using adb
  • If we directly try to install, then we get a warning because our apk is not signed yet; let’s try
keytool -genkey -v -keystore my-release-key.keystore -keyalg RSA --alias demo
Generating key using keytool
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore modifiedAPK.apk demo
Sign APK using jarsigner
APK signed successfully
APK signed successfully
  • Now we are ready to install it
Install APK using adb
Install APK using adb
  • Check if we can use the app without interruption and the error warning we changed.
Output After Reversing
Output After Reversing

This is just a small example of reversing we can do a lots of things with reversing such as bypassing SSL Pinning, Root detection, Emulator detection bypass. Boolean strings change to get unintended results from app and many more things checkout

To avoid security risks, we can implement the following integrity checks.

Ways to check android app's integrity
Ways to check android app’s integrity

Digging Into source code for Hard-coded sensitive Information

It is now possible to search for Hardcoded Sensitive Information, either in Java source code or in XML files. Start by looking at Java source code, either by looking for sensitive components such as loginActivity or any component that could be interacting with sensitive data. You can also use the search option to search for sensitive words such as password, key, user, email, etc. 

JADX-GUI
JADX-GUI
grep for sensitive information
grep for sensitive information

Check for Filename].apk/res/values/strings.xml and [Filename].apk/res/values/Arrays.xml; these files are essential for sensitive information and also help in understanding the app.

Password, Keys, and Credentials are not the only sensitive information to check; we can look at API Endpoints, Hidden URLs, IP addresses, Cloud Buckets, and much more information that might take some time to unravel, such as API URLs or endpoints needing to be fuzz tested manually with some techniques, we can escalate that, but it’s worth doing.

Insecure Cryptographic Algorithms

MD5, MD4, SHA1, RC2, base64, etc., are the depreciated cryptographic algorithms, so if the app is using these algorithms for encryption purposes of sensitive information like passwords, then serious security might occur. That’s why we can’t neglect it. If we find any hardcoded key that the app uses, we can look in the code to see if it used symmetric cryptography. If so, both encryption and decryption keys will be the same, so that encryption will be useless. 

Let’s see one simple example,

Here is one hard-coded string with base64 in /res/values/strings.xml

base64 encoded string
base64 encoded string

Try to decode it

  1. Visit https://www.dcode.fr/base-64-encoding or any preferred base64 decoder
  2. Enter our string and click on decode
  3. In the following image you can see string successfully decoded.
decode string using base64 decoder
decode string using base64 decoder

In hardcoded strings and app flow, the app should not use any insecure cryptographic algorithms. If possible, avoid storing any sensitive data on your mobile device. According to OWASP minimum requirement for cryptography should be as follows –

Key exchange: Diffie–Hellman key exchange with minimum 2048 bits
Message Integrity: HMAC-SHA2
Message Hash: SHA2 256 bits
Asymmetric encryption: RSA 2048 bits
Symmetric-key algorithm: AES 128 bits
Password Hashing: PBKDF2, Scrypt, Bcrypt
ECDH, ECDSA: 256 bits

Here is something interesting we want to include –

AES Killer, decrypt AES traffic on the fly –

What it does

  • The IProxyListener decrypt requests and encrypt responses, and an IHttpListener then encrypts requests and decrypts responses.
  • Burp sees the decrypted traffic, including Repeater, Intruder and Scanner, but the client/mobile app and server see the encrypted version.

NOTE: Currently support AES/CBC/PKCS5Padding and AES/ECB/PKCS5Padding encryption/decryption.

Check it out now; click here

Unintended Data Leakages

An unintended data leak occurs when a developer places sensitive data or information in an area that other apps can easily access on a mobile device.

Insecure Logging

Log.v() (Verbose logs), Log.d() (debug logs), Log.i() (informational logs), Log.w() (Warning Logs), and Log.e() (Error Logs) these are the functions commonly used for writing logs, so if an app is using any of these functions, look at the code to see if there is any sensitive information is written logs; if so, it is vulnerable for insecure logging. Logs should not be written with sensitive information because up to Android API 20 (android version 4), they are accessible by other apps as well, so there is a possibility of potential theft.

JADX
JADX

Check logs by using adb logcat; you can monitor all the logs; to sort specific records, you can use “grep”

e.g. adb logcat | grep “com.example.app” will go to grep all the logs which involved our package name.

ADB Logcat

Copy/Paste buffer Caching:

In the android system, a single clipboard is accessible by all the applications. Therefore, if the application has been enabled, copy and paste on sensitive functions such as email, password, and credit card, so it may be possible that the other application might access that information. Therefore, to avoid any security risk, it is necessary to disable the clipboard on sensitive functions.

Here is an example of how to check if the clipboard is enabled or not –

copy-paste buffer
copy-paste buffer

Application backgrounding:

Android apps take screenshots of their current activity in the background and display them for aesthetic purposes when they emerge from the background. However, this may leak sensitive information.

File-based encryption (FBE) devices store snapshots in the following location – /data/system_ce/<USER_ID>/<IMAGE_FOLDER_NAME> folder. The name of the image folder depends on the vendor, but snapshots and recent_images are the most common names. If the device does not support FBE, the /data/system/<IMAGE_FOLDER_NAME> folder is used.

Here is the example that the app is not hiding the information when it sends to background and activity captured the screenshot and saved in the following location –

/data/system_ce/0/recent_images/648_task_thumbnail

Now we need to pull the file using adb –

$ adb shell

# mv /data/system_ce/0/recent_images/648_task_thumbnail /data/local/tmp
# exit
$ adb pull /data/local/tmp/648_task_thumbnail

Once you have pulled the file, you can open it using any available software, and here is the file –

Application backgrounding
Application backgrounding

There are other vulnerabilities you can check for related to unintended data leakage; some of them are mentioned below –

  • URL Caching (Both request and response) 
  • HTML5 data storage 
  • Browser cookie objects 
  • Analytics data sent to 3rd parties 

Input validation Issue

android.database.sqlite.* These are the libraries for SQLite databases, and now we can identify where SQLite is used, how it’s configured, and if we can break a query that may lead to SQL injections. As an example, here is a query designed to show user details 

"SELECT * FROM sqliuser WHERE user = '" + srchtxt.getText().toString() + "'", null

After reading this, we can try to break this query such as “ ‘ OR ‘1=1” In this case, we break the query using a single quote then we start writing our query. OR is the operator that executes the query in case one of both conditions is matched. Now, as we don’t know which usernames exist, we pass 1=1, which is always true, so as our one condition is true query will execute.
Both conditions are matched. Now, as we don’t know which usernames exist, we go through 1=1, which is always true, so as our one condition is true query will execute.

Input validation issue

Insecure Communication

Most of the time, mobile phones are connected to public WIFI, which increases the chances of traffic interception. Uses of SSL/TSL Might helps in protecting information. Session Tokens, Passwords or any personal information of often transmitted, so it is necessary to keep an eye on data transmission protocols and cryptography; however, it does not guarantee that the information can’t be decrypted, so better to follow the best practices to encrypt data with solid algorithms use a secure protocol such as TSL/ SSL.
We can look for this kind of discrepancy in Androidmanifest.xml as best practice.

<base-config cleartextTrafficPermitted="true">

If the android manifest has not declared anything about it must have another look into com.example.app/res/xml/network_security_config.xml, you might find any misconfiguration

<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">192.168.1.1</domain>
  </domain-config>
</network-security-config>

Here is the another best example of wrong implementation –

sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

The above code will accept any CA certificate issued to any domain, which is a wrong implementation.

According you can look for this type of security risk.

Let’s see one example for HTTP Traffic, We have hpandro ctf application, and in the app, we have found a flag by intercepting http traffic; you can get the app from here.

Hope you have already set up the lab as per our previous blog; if you haven’t set it up yet, please look at ‘How to Intercept Android Traffic.’

  1. Start application and open ‘HTTP Traffic Task’
HTTP Traffic Task hpandroid CTF

2. Start your burp suite and configure for traffic interception

3. Open hpandro app and click on reload

4. Open burpsuite Proxy > HTTP history > /task/http.android

HTTP Request in burpsuite
HTTP Request in burpsuite

In the previous example, we successfully got the flag in response. Still, there can be other scenarios such as credit card details, user credentials and other things depending on functionality; sensitive information can leak.

Insecure Data Storage’s

When a developer assumes that a user or malicious app cannot access sensitive information on the mobile device, they might store it in plain text. We can easily access the file system & look for any sensitive data stores. In an earlier version of android, another app is not allowed to interfere with internal storage, which increases security. Still, most of the time, developers leave the files or directories with word_readable and word_writeable so anyone can access and modify the data and then any malicious user or application can access those files.

Some sensitive directories to look for  

/mnt/sdcard/[filename]

/data/data/com.example/shared_pref/[filename] 

/data/data/com.example/Databases/ [filename] 

/data/data/com.example/[.temp files]

Example,

Here is the one best example of how android app is storing data in shared preferences without any encryption. you can download the DIVA from here.

  1. Open DIVA application > Insecure Data Storage Part – 1
  2. Enter the credentials and click on save
Insecure data storage - Shared Preferences
Insecure data storage – Shared Preferences

4. Once credentials successfully saved enter into adb shell as per following command.

$adb shell
#cat /data/data/jakhar.aseem.diva/shared_prefs/jakhar.aseem.diva_preferences.xml
Shared Preferences Directory
Shared Preferences Directory

we able to see that the app stored the credentials in plain text.

Take one more example of insecure data storage in databases

  1. Open DIVA app > Insecure data storage Part – 2
  2. Enter credentials and hit save button.
Insecure data storage – Databases

3. Enter into adb shell and use following commands to check databases

$adb shell 
#sqlite3 /data/data/jakhar.aseem.diva/databases/ids2
sqlite> .tables
sqlite> select * from myuser;
SQLite Database
SQLite Database

In the above image, we can see that the data is stored in plaintext. It is always recommended to store data using hashes or encryption; other than this, we have the choice to encrypt the database file by using SQL cipher.

Understanding Android Manifest File

The most crucial part of Android is its manifest file. It might store sensitive information, but more than that, it contains all the configuration information of the app, and here we find most of the attack surface. 

Let’s understand AndroidManifest.xml File, 

All information about the application configuration can be found here, such as which components are used, which permissions are available, etc. 

Let’s start with package detailspackage="com.example.app" 

It might be hard to decide what to do with the package name, but later on, while doing tests, it will be beneficial. The package name is different from the app name used by the system to analyze operations. The directory where most of the app’s data is stored has the name /data/data/com.example.app.

Next is API Information,  

<uses-sdk android:minSdkVersion="19" 

android:targetSdkVersion="21" 

android:maxSdkVersion="22"/> 

The SDK version and Android version are different; for example, the SDK version of android 4.4 (KitKat) is 19. So what does API information tell us? minSdkVersion says it will not work below SDK 19; max version means it will not work above SDK 22, and targetSdkVersion that the app is built for that particular SDK version.

After that there are flags in file  

<application... android: allow Backup:"true"></app> 

The first flag is Backup, which is true, and the app can take a backup automatically or manually. It is possible that the attacker can Backup the app with sensitive information such as credit card numbers, usernames, passwords, etc. and restore it on his app, thus posing a threat to user privacy. 

<application... android: allow debuggable:"true"></app> 

Secondly, the debuggable mode is true, which should not be the case. Due to the staging environment, attackers can execute runtime code injections and gather plenty of information if it is true. So, setting false is crucial for preventing security risks. 

<uses-permission android:name”android.permission.CAMERA”/>  

Whenever an app uses permissions, it must be listed in the AndroidManifest.xml file; as in the above example, it requests approval for the camera, which is not owned by the app. WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE Writing to External Storage and Reading from External Storage indicate something is interacting with External Storage, so we can look into external storage to see if it might be storing any sensitive information.

<activity android:exported="true" android:name:".activities.example"/> 

The above code describes the activity. In this case, com.example.app/com.example.app.activities.example is the same as com.example.app/.activities.example. While decompiling the code, simply look in the folder com > example > app > activities > example.class

Similarly, other components of Android are declared in a file. 

  • <service> for each subclass of Service. 
  • <receiver> for each subclass of BroadcastReceiver. 
  • <provider> for each subclass of Content Provider 

Another thing to notice is exported=”true” – what does it mean? If an app needs to access an external app or interfere with the activity of any other app during this time, it is allowed. Still, now that it is accessible by other apps, any malicious app can do some malicious activities with the app. Still, there is a condition that the permissions should be missing, such as if the developer configures the permissions, then the app can only run if granted.

<intent-filter> 

<action android:name="android.action.intent.MAIN" /> 

<category android:name:"android.intent.category.LAUNCHER"/> 

<intent-filter>

Any component, such as an activity, service, or broadcast, must intend to start. When there is explicit intent, everything knows what to do next. However, implicit intent filters exist when many choices are available, such as the share function.
Activities that is declared under an intent filter are exported by default.

Tool which will help in Static Analysis

MobSF:

Mobile Security Framework (MobSF) is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing, malware analysis and security assessment framework capable of performing static and dynamic analysis. MobSF supports mobile app binaries (APK, XAPK, IPA & APPX) along with zipped source code and provides REST APIs for seamless integration with your CI/CD or DevSecOps pipeline. In addition, the Dynamic Analyzer helps you to perform runtime security assessment and interactive instrumented testing.

Either we host locally or use directly hosted from https://mobsf.live/

MobSF apk upload
MobSF apk upload

Once the app has been successfully uploaded, it will be automatic scan for every possibility and generate the report.

Static Analysis
Static Analysis

Before assuming anything, it is essential that you need to confirm issues manually. However, MobSF simplifies everything, saving lots of time and giving detailed reports.

Hope you enjoyed it, In this blog we have discussed most of the static analysis of android, and we will cover the rest of the part in our next blog; stay tuned!

References:

  1. https://owasp.org/www-project-mobile-top-10/
  2. https://book.hacktricks.xyz/mobile-pentesting/android-app-pentesting
  3. https://mobile-security.gitbook.io/mobile-security-testing-guide/

When You Need Us

Android apps are utilized nowadays for various purposes, including mobile banking, shopping, sharing personal information, social networking, and entertainment. Unfortunately, android devices are vulnerable to threats from multiple hacking techniques, including malware, code injection, buffer overflow, and reverse engineering. No matter how big or small your business is, security should always come first. Connect with us to do penetration testing to keep your apps safe and secure.

Find more about us here.