Android Application Pentesting: Lab Setup and APK Internals

Mobile API OSINT
Time it takes to read this article 5 minutes.

Legal & ethical disclaimer. Everything in this article is for education and authorized testing only. Only analyze applications you own, have written permission to test, or that are explicitly in scope of a signed engagement. Decompiling and redistributing third-party software may violate license agreements and local law. Use a disposable emulator or a dedicated test device — never your daily phone.

Introduction / Overview

Most Android assessments start the same way: get the APK, understand what it is, instrument a device, and only then attack the interesting bits (auth, IPC, network, storage). Before you can do dynamic analysis with Frida or intercept traffic with Burp, you need a working lab and a solid grasp of how an APK is built. This article focuses on that foundation: the APK structure, the AndroidManifest, the Android Debug Bridge (adb), the emulator, and a first static triage pass with MobSF.

Get this right and the rest of the kill chain — hooking, SSL pinning bypass, deep-link abuse — becomes mechanical.

How it works / Background

An APK (.apk) is just a ZIP archive with a defined layout. The components you will touch constantly:

Path Purpose
AndroidManifest.xml App metadata: package name, components, permissions, exported flags. Binary-encoded inside the APK.
classes.dex (classes2.dex, …) Dalvik bytecode — the compiled Java/Kotlin.
resources.arsc Compiled resources table (strings, layouts).
res/ Resources (drawables, XML layouts).
assets/ Raw bundled files (configs, JS bundles, ML models, sometimes secrets).
lib/<abi>/ Native .so libraries per ABI (arm64-v8a, armeabi-v7a, x86_64).
META-INF/ Signature and manifest (CERT.RSA, MANIFEST.MF).

The AndroidManifest is your map. It declares every activity, service, receiver, and provider, whether each is exported, what permission guards it, the minSdkVersion/targetSdkVersion, and flags like android:debuggable and android:usesCleartextTraffic. Exported components reachable without permission are a classic IPC attack surface — see Android Deep Links and Intent Hijacking for where that leads.

Modern distributions are often AAB-derived split APKs (base.apk + split_config.*.apk). For analysis you typically merge them back into a universal APK with a tool like bundletool or APKEditor.

Prerequisites / Lab setup

You need the Android SDK command-line tools. The cleanest route is Android Studio (which ships adb, emulator, and sdkmanager) or the standalone command-line tools.

# macOS via Homebrew (platform-tools gives you adb)
brew install --cask android-platform-tools
brew install apktool jadx
pip install mobsf   # or run the official Docker image (recommended below)
Bash

Create and boot a Google-APIs (not Play) emulator image — Google-APIs images are rooted-friendly and let you remount system as writable, which Play images do not:

sdkmanager "system-images;android-34;google_apis;x86_64" "platform-tools"
avdmanager create avd -n pentest34 -k "system-images;android-34;google_apis;x86_64"
emulator -avd pentest34 -writable-system -no-snapshot
Bash

Confirm the device is connected and inspect it:

adb devices -l
adb shell getprop ro.build.version.release   # Android version
adb shell getprop ro.product.cpu.abi         # target ABI for native libs
Bash

For static analysis I run MobSF in Docker so it stays isolated and reproducible:

docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
# then browse to http://localhost:8000 and drag in the APK
Bash

Walkthrough / PoC

1. Acquire the APK

If the app is installed on your test device, pull it straight off:

# Find the package
adb shell pm list packages | grep -i target
# Resolve the on-device APK paths (split APKs return several)
adb shell pm path com.example.target
# package:/data/app/.../base.apk
adb pull /data/app/~~AbC==/com.example.target-xY==/base.apk ./base.apk
Bash

2. Inspect structure and the manifest

apktool decodes the binary manifest and resources back to readable XML:

apktool d base.apk -o base_decoded
# Key things to grep in the manifest
grep -E 'android:(exported|debuggable|usesCleartextTraffic)|<permission' \
  base_decoded/AndroidManifest.xml
Bash

Quickly enumerate the package metadata and exported components without full decompilation using aapt:

aapt dump badging base.apk | grep -E 'package|sdkVersion|uses-permission'
Bash

For source-level reading, jadx decompiles DEX back to Java:

jadx -d base_src base.apk
# or interactively
jadx-gui base.apk
Bash

3. Triage with MobSF

Upload base.apk to the MobSF web UI. The static report immediately surfaces:

  • Permissions and their risk weighting.
  • Exported activities/services/receivers/providers and missing permission guards.
  • Insecure config: android:debuggable="true", cleartext traffic, weak networkSecurityConfig.
  • Hardcoded secrets, API keys, and trackers found in code and strings.
  • Certificate details and signature scheme.

MobSF gives you a fast prioritized list; treat its findings as leads, then verify by hand in jadx.

4. Confirm a finding dynamically

Suppose MobSF flags an exported activity with no permission. Probe it directly with adb:

# Launch an exported component (no permission required = reachable by any app)
adb shell am start -n com.example.target/.AdminActivity

# Fire an intent into an exported receiver with an extra
adb shell am broadcast -a com.example.target.ACTION_SYNC --es token test123
Bash

If the activity loads internal state or the receiver acts on attacker-controlled extras, you have confirmed an IPC issue worth writing up. From here you would move to runtime instrumentation — see Frida for SSL Pinning Bypass on Android and reverse the native libraries with Ghidra when logic hides in lib/.

Mermaid diagram

Android Application Pentesting: Lab Setup and APK Internals diagram 1

The flow shows the triage path: prove scope, acquire and normalize the APK, run static analysis, then validate leads dynamically before reporting.

Detection & Defense (Blue Team)

Defenses here matter as much as the offense — the same checks a pentester runs are what a hardened build pipeline should fail on.

Ship secure manifests.

  • Never ship release builds with android:debuggable="true". Gradle handles this automatically for the release build type; verify it.
  • Set android:exported explicitly on every component. On targetSdkVersion 31+ (Android 12) the system requires it, but audit older modules.
  • Protect IPC entry points with android:permission and signature-level custom permissions so only your own signed apps can call them.

Enforce transport security.

  • Disable cleartext: android:usesCleartextTraffic="false" and ship a strict network_security_config.xml with certificate pinning. This raises the cost of the Burp/Frida interception step above.

Harden against static extraction.

  • Don't store secrets in assets/, res/, strings.xml, or code — MobSF and a simple strings/grep will find them. Use a backend token-exchange or the Android Keystore.
  • Apply R8/ProGuard obfuscation and remove logging. It won't stop a determined analyst but it slows triage.
  • Add Play Integrity API / SafetyNet attestation and root/emulator detection to break the casual emulator workflow.

Detect in CI and at runtime.

  • Gate releases on automated SAST: run MobSF in CI mode via its REST API, or use mobsfscan against source.
mobsfscan ./app/src   # static checks straight in the pipeline
Bash
  • Monitor for tampering: verify the app signing certificate at runtime and watch for repackaged builds in third-party stores.

This maps to MITRE ATT&CK for Mobile: T1626 (Abuse Elevation Control), T1517/T1409 (Access/Stored Application Data), and T1444 (Masquerading) via repackaged APKs.

Conclusion

A repeatable lab is the highest-leverage investment in mobile pentesting. With a writable Google-APIs emulator, adb fluency, an understanding of APK and AndroidManifest structure, and MobSF for triage, you can go from raw APK to a prioritized findings list in minutes — then validate the interesting parts dynamically. Defenders get the same checklist for free: lock down exported components, kill cleartext, keep secrets server-side, and gate releases on automated scanning.

References

Comments

Copied title and URL