Android’s permissions model controls which resources an app can access. Misused, over-privileged, or improperly enforced permissions lead to data leaks, privilege escalation, and remote attacks. This chapter focuses on practical pentesting, including permission extraction, abuse techniques, bypass tests, and real command-based workflows.
Extracting Permissions from an APK
Decode manifest:
apktool d app.apk -o decoded_app
List permissions:
grep -R "<uses-permission" -n decoded_app/AndroidManifest.xml
Extract only permission names:
grep -oP '(?<=uses-permission android:name=").*?(?=")' decoded_app/AndroidManifest.xml
Review permissions that directly increase risk:
-
READ_CONTACTS
-
READ_SMS
-
RECORD_AUDIO
-
CAMERA
-
READ_EXTERNAL_STORAGE
-
WRITE_EXTERNAL_STORAGE
-
ACCESS_FINE_LOCATION
-
ACCESS_COARSE_LOCATION
These permissions define what the app can do, and what you can target during pentesting.
Checking Permissions at Runtime (Dynamic Testing)
Check granted permissions:
adb shell pm list permissions -g
Check permissions for a specific app:
adb shell dumpsys package com.app | grep permission
Revoke a permission to see how the app behaves:
adb shell pm revoke com.app android.permission.CAMERA
Grant a dangerous permission:
adb shell pm grant com.app android.permission.RECORD_AUDIO
Testing app behavior under permission changes often exposes:
-
Missing error handling
-
Blind trust in permission availability
-
Crashes revealing internal logic
-
Potential bypass opportunities
Dangerous Permissions (Practical Abuse)
Dangerous permissions access sensitive user data. Pentesting requires verifying what happens after these permissions are granted.
READ_CONTACTS Abuse Test
adb shell content query --uri content://contacts/phones/
If the app exposes contacts through content providers → data leakage.
LOCATION Permission Test
Use Frida to hook GPS calls:
frida -U -f com.app -l gps_hook.js --no-pause
This intercepts:
-
getLastLocation
-
requestLocationUpdates
Testing allows simulating fake GPS data for exploitation.
CAMERA Permission Test
Try forcing camera activity:
adb shell am start -a android.media.action.IMAGE_CAPTURE
If the app takes actions without validation → vulnerable.
MICROPHONE Permission Test
Hook audio recording:
frida -U -f com.app -l audio.js --no-pause
Check if recordings trigger insecure logic.
Custom Permissions
Apps may define their own permissions:
grep -R "<permission" -n decoded_app
Example:
<permission android:name="com.app.ACCESS_PRIVATE"
android:protectionLevel="normal"/>
If protectionLevel is normal or dangerous, any app can request this permission.
Test with a malicious app:
<uses-permission android:name="com.app.ACCESS_PRIVATE" />
Then trigger the protected component:
adb shell am start -n com.app/.PrivateActivity
If it runs → privilege escalation.
Permission Protection Levels (Practical View)
Normal Permissions
No user approval required. Often misused by developers.
Check for unsafe use:
grep -R "protectionLevel=\"normal\"" -n decoded_app
Dangerous Permissions
Require user approval.
Pentesting focus:
-
What happens after approval?
-
Can values be manipulated?
-
Does app validate input?
Signature and SignatureOrSystem Permissions
Only apps signed with the same certificate can use these.
Test signature bypass:
keytool -printcert -file META-INF/CERT.RSA
If reused across apps, exploitation becomes easier.
Component-Level Permission Enforcement Testing
Activity Permission Testing
Launch activity with forged intent:
adb shell am start -n com.app/.SecureActivity
If it opens → missing permission enforcement.
Service Permission Testing
adb shell am startservice -n com.app/.SecureService
If allowed → vulnerability.
Receiver Permission Testing
adb shell am broadcast -a com.app.SECURE_ACTION
If the receiver processes the broadcast → misconfigured.
Provider Permission Testing
Check read/write permissions:
adb shell content query --uri content://com.app.provider/data
If accessible → data leak.
Bypassing Runtime Permission Checks (Practical)
Many apps check permissions manually in code. Use Frida to bypass:
frida -U -f com.app -l bypass_perm.js --no-pause
Example hook:
Java.perform(function() {
var pm = Java.use("android.app.Activity");
pm.checkSelfPermission.implementation = function() {
return 0; // PERMISSION_GRANTED
};
});
This allows:
-
Running privileged code
-
Triggering internal flows
-
Accessing restricted functions
Permission Misuse Vulnerabilities
Overprivileged Apps
App requests permissions it doesn’t need. This increases your attack surface.
Find suspicious ones:
grep -R "uses-permission" decoded_app
Compare to app functionality. If the app is a calculator requesting location → suspicious.
Broken Permission Validation
App checks permissions incorrectly:
if (checkSelfPermission(X) != 0) { /* allow */ }
Reverse engineer the flow to confirm.
Missing Permission Checks
An exported component uses sensitive APIs without verifying permissions.
Incorrectly Granted Permissions via Shared User ID
Search:
grep -R "sharedUserId" -n decoded_app/AndroidManifest.xml
Apps with sharedUserId share permissions. One vulnerable app compromises all others using same ID.
Full Permission Pentest Workflow
-
Extract and decode manifest
-
List all permissions
-
Identify dangerous and custom permissions
-
Map permissions to components (activities, services, providers)
-
Check runtime granted permissions
-
Revoke and re-grant permissions to test app behavior
-
Attempt to trigger privileged actions without permission
-
Query providers to check real data exposure
-
Use Frida to bypass permission checks
-
Map vulnerabilities to potential exploit chains
Intel Dump
-
Extract permissions via apktool and grep
-
Test dangerous permissions with ADB and Frida
-
Exploit exported components by triggering privileged actions
-
Analyze custom permissions and weak protection levels
-
Abuse content providers using content queries
-
Bypass runtime permission checks via Frida hooks
-
Test app behavior by revoking and adding permissions
-
Identify overprivileged apps and missing permission validation