diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 7f03a949a0b..150c9fd9de7 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -367,6 +367,7 @@ - [Android Applications Basics](mobile-pentesting/android-app-pentesting/android-applications-basics.md) - [Android Enterprise Work Profile Bypass](mobile-pentesting/android-app-pentesting/android-enterprise-work-profile-bypass.md) - [Android Hce Nfc Emv Relay Attacks](mobile-pentesting/android-app-pentesting/android-hce-nfc-emv-relay-attacks.md) + - [Android Package Manager Hooking And Dynamic Loading](mobile-pentesting/android-app-pentesting/android-package-manager-hooking-and-dynamic-loading.md) - [Android Task Hijacking](mobile-pentesting/android-app-pentesting/android-task-hijacking.md) - [ADB Commands](mobile-pentesting/android-app-pentesting/adb-commands.md) - [APK decompilers](mobile-pentesting/android-app-pentesting/apk-decompilers.md) diff --git a/src/mobile-pentesting/android-app-pentesting/README.md b/src/mobile-pentesting/android-app-pentesting/README.md index ff7922799c5..7b9cea4d797 100644 --- a/src/mobile-pentesting/android-app-pentesting/README.md +++ b/src/mobile-pentesting/android-app-pentesting/README.md @@ -27,6 +27,7 @@ Sometimes it is interesting to **modify the application code** to access **hidde - [Spoofing your location in Play Store](spoofing-your-location-in-play-store.md) - [Play Integrity attestation spoofing (SafetyNet replacement)](play-integrity-attestation-bypass.md) +- [PackageManager hooking & dynamic payload loading](android-package-manager-hooking-and-dynamic-loading.md) - [Android app-level virtualization / app cloning abuse & detection](android-application-level-virtualization.md) - [Shizuku Privileged API (ADB-based non-root privileged access)](shizuku-privileged-api.md) - [Exploiting Insecure In-App Update Mechanisms](insecure-in-app-update-rce.md) diff --git a/src/mobile-pentesting/android-app-pentesting/android-package-manager-hooking-and-dynamic-loading.md b/src/mobile-pentesting/android-app-pentesting/android-package-manager-hooking-and-dynamic-loading.md new file mode 100644 index 00000000000..4137a7a6cd8 --- /dev/null +++ b/src/mobile-pentesting/android-app-pentesting/android-package-manager-hooking-and-dynamic-loading.md @@ -0,0 +1,58 @@ +# Android PackageManager Hooking & Dynamic Payload Loading + +{{#include ../../banners/hacktricks-training.md}} + +Some Android malware/loaders **hook `IPackageManager` in-process** to spoof signatures/installer source and **rewrite `ApplicationInfo` paths** to execute a secondary payload from a dropped asset. These tricks are useful to recognize during static/dynamic analysis and to reproduce in red-team tooling. + +## PackageManager Proxy Hooking (Signature + Installer Spoofing) + +**Goal:** Intercept calls like `getPackageInfo()` and `getInstallerPackageName()` so integrity checks see attacker-controlled values. + +**High-level flow:** +1. Reflect into `android.app.ActivityThread` and read the global `sPackageManager` (or `mPM`) instance. +2. Create a **dynamic proxy** via `Proxy.newProxyInstance()` that implements `IPackageManager`. +3. In the proxy `invoke()` method, return a `PackageInfo` whose `signingInfo`/`signatures` contain a **hardcoded X.509 cert** when `getPackageInfo` is called (often decoded from a Base64 blob stored in `attachBaseContext`), and return `"com.android.vending"` when `getInstallerPackageName` is called to make a **sideloaded APK appear Play-installed**. +4. Replace `ActivityThread.sPackageManager` (and any cached `mPM`) with the proxy instance. + +**Triage indicators:** +- Reflection on `ActivityThread`, access to `sPackageManager`/`mPM`/`mPackages` fields. +- `Proxy.newProxyInstance()` + custom `InvocationHandler` that inspects `method.getName()`. +- Base64 blobs parsed into `Signature`/`Certificate` objects for `getPackageInfo` responses. + +## Hardcoded X.509 Signature Blob (Anti-Tamper Bypass) + +A common pattern is storing a serialized **certificate blob** that is decoded at runtime and returned as the app's signature: + +- A small header parsed with `DataInputStream` (e.g., number of signatures + length). +- Followed by **ASN.1/DER X.509 bytes** used to build a `Certificate`/`Signature` object. + +This allows signature checks in the app (or third-party SDKs) to **validate against the attacker's chosen cert** without changing the APK's real signing identity. + +## Dynamic Payload Loading via `ApplicationInfo` Path Rewriting + +**Goal:** Execute code from a secondary payload while making the runtime believe it is still loading the original APK. + +**High-level flow:** +1. Extract a hidden asset (often with no extension) into internal storage via `getFileStreamPath()`. +2. Reflectively update `ApplicationInfo.sourceDir` and `ApplicationInfo.publicSourceDir` to point to the dropped file. +3. Optionally update internal cached fields such as `mAppDir`/`mApplicationInfo` in loaded APK structures. +4. Load the dropped blob as a **DEX-like payload** (e.g., via `DexClassLoader`) and pivot execution. + +**Triage indicators:** +- Asset name with no extension + copy into app private storage. +- Reflection modifying `ApplicationInfo.sourceDir`/`publicSourceDir` at runtime. +- `DexClassLoader`/`PathClassLoader` initialized with the dropped file path. + +## Permission-State Polling to Trigger Modules + +Some loaders **continuously poll permission state** and immediately activate a specific module (SMS/contacts/GPS) as soon as a single permission is granted, rather than waiting for all permissions. Look for: + +- Background threads repeatedly calling `Context.checkSelfPermission()` / `ActivityCompat.checkSelfPermission()`. +- Module dispatch based on the first permission grant event. +- Staging harvested data into categorized local files before network upload. + +## References + +- [CloudSEK: RedAlert Trojan Campaign: Fake Emergency Alert App Spread via SMS Spoofing Israeli Home Front Command](https://www.cloudsek.com/blog/redalert-trojan-campaign-fake-emergency-alert-app-spread-via-sms-spoofing-israeli-home-front-command) + +{{#include ../../banners/hacktricks-training.md}}