Press enter or click to view image in full size
Hello Hackers, I hope you guys are doing well and hunting lots of bugs and dollars!
Android is everywhere. Billions of devices, millions of apps, and a massive attack surface that keeps growing every single day. So of course, we should focus on its security. So today I’m going to talk about my android pentesting methodology which I follow from years. This will be going to useful to the new folks and some experienced too.
But yeah, the truth is this checklist or methodology is gonna be too long maybe. And it’s not always recommended to follow each and every step. But yes, keep this checklist in your mind.
lets start…
I assume you already have a setup for Android pentesting. You have your rooted device and other basic requirements fulfilled. We’re not going to cover those up.
Also, for this methodology, I’m focused on a rooted device approach, which will give you freedom for multiple things, which we’re gonna utilize in our pentesting.
Okay ! Now let’s get into the actual pentesting stuff. We’ll start with basic information gathering first.
Which files are included in the package?
Extract the APK and examine its structure. you can use apktool for this. or just rename the test.apk to test.zip and extract it.
which native library the app is using ?
Although we can fetch this information later after decompiling, but here you can check the `lib/` folder for the native libraries. Some custom `.so` files can be seen sometimes too.
If you’re performing white box pentesting, ask these details from the developer itself.
Now it’s necessary to understand that we have two parts here in Android pentesting: Static analysis and Dynamic analysis.
Static analysis involves examining the app’s code without executing it. This is where we find hardcoded secrets, API keys, and logic flaws.
lets deep dive into static first.
First step is to decompile the app. You can use either apktool or JADX GUI. I prefer JADX GUI, which is really helpful and easy to understand as compared to apktool. Although you can find apktool GUI also.
Using apktool
apktool d app.apk -o decompiledFor opening in JADX GUI, just open the .apk file, which is way better readable.
Then let’s directly start with AndroidManifest.xml.
Think of AndroidManifest.xml as the blueprint of the entire app. It’s like a map that tells you everything about the app’s structure, permissions, components, and security settings - all in one place. This single file can reveal lots of attack surface.
I’ve found so many vulnerabilities just by reading this file. Exported activities without auth, debuggable production apps, backup enabled with sensitive data - all visible in plain XML. That’s why I always start here. It’s the fastest way to find low-hanging fruits.
App permission : check what permission is app requesting, look for dangerous permission that require. why does app need those permission ? Are they required ?
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />Backup Enabled : check for <application android:allowBackup=”true”>, if this is enabled , then an adversary users can use ADB tool to access app backup data. which can expose shared preferences, databases, and internal files.
If this whole flag is missing from the manifest, it’s still defined as `true` by default. So if you don’t see `allowBackup` attribute at all, the backup is still enabled. Confirm it with the below command.
adb backup -f backup.ab com.example.appDebuggable flag : check for <application android:debuggable=true> if this flags sets to true. An adversary users can attach debugger, read process memory, and modify variables at runtime.
Unlike allowBackup, this flag is NOT enabled by default. It defaults to `false`. However, sometimes developers accidentally leave it enabled in production builds, or it gets set to true during development.
Network Security Configuration : Check if certificate pinning is implemented or if cleartext traffic is allowed. If cleartext traffic is permitted, that’s a vulnerability.
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>If cleartextTrafficPermitted=true is set, the app allows HTTP connections, which means traffic can be intercepted and modified. This is a vulnerability.
Min, Max, and Target SDK Versions : Lower SDK version have weaker security. if app is having older SDKs , it will lack support for modern security feature.
App should target recent SDK version.
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" />Exported App Components : Look for exported components. There are four components (activities, services, providers, and receivers). If android:exported = true is there, that means it can be called independently, which can be used for malicious purpose or bypassing some security features. We will talk more on this later.
Activities : These are basically the UI screens. Like login page, home screen, etc. If exported, other apps can launch them directly. So you can bypass login screen and go straight to home page.
Services : These run in background, doing some work without showing UI. If exported, other apps can start or stop them. Can be used to trigger some actions without user knowing.
Content Providers : These share data between apps. If exported, other apps can query them and read data. Like user info, tokens, database stuff. This is where you find data leaks.
Broadcast Receivers : These listen for system messages. Like when phone boots up, or SMS received, etc. If exported, malicious apps can trigger them. Can be used to perform actions without user interaction.
Search for interesting strings : This is where you find the low-hanging fruits. Search for interesting strings like passwords, URLs, API keys, encryption keys, backdoors, tokens, and UUIDs.
Sometime you can get hardcoded secrets embedded in the application. Which you can utilise later maybe exploiting some API keys leaks (take a look keyhacks) or some logical findings.
Personally I don’t look manually everything here, i use automation, which apkurlgrep or string utility, regex enabled search via jadx gui.
Firebase Misconfiguration : when analysing interesting string, you might endup with a firebase url like https://xyz.firebaseio.com/, generally you will find this at res/values/strings.xml.
So its really worth checking firebase misconfiguration issues. Just go to the browser and navigate to the found URL https://xyz.firebaseio.com/.json.
you will observe two types of response :-
If you got the second response, don’t just stay there, check if you have more than access to read, that means can you write something there, if yes then its jackpot !
curl -X PUT "https://xyz.firebaseio.com/test.json" -d '{"test":"data"}'# If successful, check for delete access (be careful!)
curl -X DELETE "https://xyz.firebaseio.com/test.json"
Okay, so we’ve covered static analysis basics. Now let’s talk about where apps store sensitive data. This is where you find a lot of vulnerabilities.
Sensitive Data Stored in Clear-Text : This is the very common vulnerability in mobile apps. Android provides several ways for app to store, which handle very sensitive data, context to the application you are assessing; maybe authentication token, user credential, scores, payment details etc.
You can find the /data/data/com.example.app/ directory. You should explore here. You will get shared_prefs, logs, sql db, and other files.
Analyse the source code : When you decompile APK, you have the source code, you can analyse it. But nowadays most of the apps protected it with the help of some obfuscation, which prevents an adversary to understand the logic.
I personally look at few files to get ideas about what logic is written, like root detection, SSL pinning, debugger check, client-side check or etc. Analysing source code will give you idea to understand to make your dynamic analysis good, attacks like webview or deeplinks, injections.
I do look at it manually, only if time allows. Or you can directly analyse the code with the help of semgrep or MobSF. This will give you a very quick idea of the security posture. Below is the repo semgrep-rules-android-security which can help.
What to look in source code manually :-
APK Signature - Janus Vulnerability
APK signature verification is important for app integrity. However, there’s a vulnerability called Janus (CVE-2017–13156) that allows attackers to modify APK files without invalidating the signature.
apksigner verify --verbose app.apkAnti-Tampering (Integrity) Check : Decompile the APK using apktool, then change some files like modify a manifest.xml file, change a string true to false. Recompile the APK using apktool, sign it with your own key, and install and run the app.
If the app detects tampering, it should refuse to run or show an error. If it runs normally, then the app doesn’t have proper tamper detection. This is a vulnerability.
Okay, so we’ve covered the static analysis part. Now let’s talk about one of the important security measures that is root detection and SSL pinning.
Generally modern app is having these all security in place, so to perform the dynamic assessment and some other security checks you need to bypass these checks. Let’s have a look of quick overview of them, we will not deep dive into this, I will just give you an overview for the same!
Root detection is basically the app checking whether your device is rooted or not. If the app finds out your device is rooted, it might refuse to run, or show some error, or restrict certain features.
Apps use multiple techniques to detect root. Let’s look at the most common ones which you will find during assessment:
Using Root Detection Libraries: Many developers don’t write custom root detection code. They just use ready-made libraries that do all the root detection checks, such as RootBeer, RootCloak & RootInspector.
Checking for su binary: The app looks for the su binary in common paths like /system/bin/su, /system/xbin/su, or /sbin/su. If found, it knows the device is rooted.
Looking for root management apps: Apps check for Magisk, SuperSU, or other root management apps installed on the device. They look for package names like com.topjohnwu.magisk or eu.chainfire.supersu.
Checking system properties: Apps read properties like ro.debuggable, ro.secure, or ro.build.tags to detect root or test builds.
Google SafetyNet / Play Integrity API: Google’s official solution for device integrity checking. It’s cloud-based and checks for root, unlocked bootloader, and system tampering. This is harder to bypass than custom root checks.
Checking for writable system partitions: Rooted devices usually have /system mounted as read-write, which apps can detect.
Detecting Magisk or Zygisk: Some apps specifically look for Magisk-related files, processes, or mount points like /sbin/.magisk/, /data/adb/magisk, etc.
There are multiple ways to bypass root detection. Here are the most common methods:
Magisk Hide / Zygisk DenyList: Enable DenyList in Magisk settings and add your target app.
Frida Scripts: Use Frida to hook root detection functions and make them return false. You can explore more custom Frida scripts on GitHub, or write your own if you understand the detection logic. Or of course, use AI to generate one for you!
Objection: Built on top of Frida, provides easy command-line interface to disable root checks.
Patching the APK: Decompile, find the root detection logic, patch it, recompile, and sign.
Magisk/LSposed Modules: Use modules like Hide My Applist, Shamiko, LSPosed with RootCloak, or Zygisk-Assistant to hide root from apps. These work at a system level.
Remember, bypassing is easier once you understand how the app detects root in the first place. Read the code, identify the checks, then choose your bypass method accordingly!
SSL Pinning (also known as Certificate Pinning) is a security mechanism where the app validates the server’s SSL certificate against a pre-defined certificate or public key embedded in the app. This prevents man-in-the-middle (MITM) attacks, even if you install a custom CA certificate on the device.
When SSL pinning is implemented, you can’t intercept the app’s traffic with Burp Suite or any other proxy, because the app will reject your proxy’s certificate.
Developers can implement SSL pinning in multiple ways. Let’s look at the most common ways you’ll observe during assessment :
Network Security Configuration (XML-based): The app defines trusted certificates in an XML file, usually at res/xml/network_security _config.xml.
Custom TrustManager: Some developers write their own TrustManager to validate certificates manually.
Third-party Libraries: Libraries like OkHttp, TrustKit provide ready-made SSL pinning implementations that developers can integrate easily.
We need to bypass this SSL pinning check, as you are aware now that you can’t intercept the request and response. But to complete the assessment you need to analyze that areas as well. Most of the time you may ask developer to remove these security checks like root detection and SSL pinning checks, but in black box scenario this access is not possible.
lets see few common bypasses :
Objection : Disables SSL pinning with a single command.
Frida Scripts: Use universal SSL pinning bypass scripts. You can find ready made scripts on GitHub, write your own if you understand the implementation, or use AI to generate them.
HTTP Toolkit: A GUI tool that automatically handles certificate installation and SSL pinning bypass. Just install it on your computer and the target app on your device.
Manual Patching: Decompile the app, find the pinning implementation (search for CertificatePinner, TrustManager, etc.), modify or remove it, recompile, and sign. Time-consuming but works 100% of the time.
Alright, so we’ve covered a lot in this article, from static analysis basics to bypassing root detection and SSL pinning. This should give you a solid foundation to start your Android pentesting journey.
But yeah, Android pentesting is way more than just this. There are still many areas we didn’t deep dive into here. For examples WebView, Deeplinks, Memory related Issues, and Cryptography issues etc.
I’ll be covering these topics in detail in future articles, so stay tuned !!
I hope this is informative to you, and if you have any doubts or suggestions, reach out to me over Twitter; I’ll be happy to assist or learn from you.
Happy Hacking !
Twitter handle :- https://x.com/Xch_eater