|
| 1 | +# Mobile Phishing & Malicious App Distribution (Android & iOS) |
| 2 | + |
| 3 | +{{#include ../../banners/hacktricks-training.md}} |
| 4 | + |
| 5 | +> [!INFO] |
| 6 | +> This page covers techniques used by threat actors to distribute **malicious Android APKs** and **iOS mobile-configuration profiles** through phishing (SEO, social engineering, fake stores, dating apps, etc.). |
| 7 | +> The material is adapted from the SarangTrap campaign exposed by Zimperium zLabs (2025) and other public research. |
| 8 | +
|
| 9 | +## Attack Flow |
| 10 | + |
| 11 | +1. **SEO/Phishing Infrastructure** |
| 12 | + * Register dozens of look-alike domains (dating, cloud share, car service…). |
| 13 | + – Use local language keywords and emojis in the `<title>` element to rank in Google. |
| 14 | + – Host *both* Android (`.apk`) and iOS install instructions on the same landing page. |
| 15 | +2. **First Stage Download** |
| 16 | + * Android: direct link to an *unsigned* or “third-party store” APK. |
| 17 | + * iOS: `itms-services://` or plain HTTPS link to a malicious **mobileconfig** profile (see below). |
| 18 | +3. **Post-install Social Engineering** |
| 19 | + * On first run the app asks for an **invitation / verification code** (exclusive access illusion). |
| 20 | + * The code is **POSTed over HTTP** to the Command-and-Control (C2). |
| 21 | + * C2 replies `{"success":true}` ➜ malware continues. |
| 22 | + * Sandbox / AV dynamic analysis that never submits a valid code sees **no malicious behaviour** (evasion). |
| 23 | +4. **Runtime Permission Abuse** (Android) |
| 24 | + * Dangerous permissions are only requested **after positive C2 response**: |
| 25 | + ```xml |
| 26 | + <uses-permission android:name="android.permission.READ_CONTACTS"/> |
| 27 | + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> |
| 28 | + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> |
| 29 | + <!-- Older builds also asked for SMS permissions --> |
| 30 | + ``` |
| 31 | + * Recent variants **remove `<uses-permission>` for SMS from `AndroidManifest.xml`** but leave the Java/Kotlin code path that reads SMS through reflection ⇒ lowers static score while still functional on devices that grant the permission via `AppOps` abuse or old targets. |
| 32 | +5. **Facade UI & Background Collection** |
| 33 | + * App shows harmless views (SMS viewer, gallery picker) implemented locally. |
| 34 | + * Meanwhile it exfiltrates: |
| 35 | + - IMEI / IMSI, phone number |
| 36 | + - Full `ContactsContract` dump (JSON array) |
| 37 | + - JPEG/PNG from `/sdcard/DCIM` compressed with [Luban](https://github.com/Curzibn/Luban) to reduce size |
| 38 | + - Optional SMS content (`content://sms`) |
| 39 | + Payloads are **batch-zipped** and sent via `HTTP POST /upload.php`. |
| 40 | +6. **iOS Delivery Technique** |
| 41 | + * A single **mobile-configuration profile** can request `PayloadType=com.apple.sharedlicenses`, `com.apple.managedConfiguration` etc. to enroll the device in “MDM”-like supervision. |
| 42 | + * Social-engineering instructions: |
| 43 | + 1. Open Settings ➜ *Profile downloaded*. |
| 44 | + 2. Tap *Install* three times (screenshots on the phishing page). |
| 45 | + 3. Trust the unsigned profile ➜ attacker gains *Contacts* & *Photo* entitlement without App Store review. |
| 46 | +7. **Network Layer** |
| 47 | + * Plain HTTP, often on port 80 with HOST header like `api.<phishingdomain>.com`. |
| 48 | + * `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)` (no TLS → easy to spot). |
| 49 | + |
| 50 | +## Defensive Testing / Red-Team Tips |
| 51 | + |
| 52 | +* **Dynamic Analysis Bypass** – During malware assessment, automate the invitation code phase with Frida/Objection to reach the malicious branch. |
| 53 | +* **Manifest vs. Runtime Diff** – Compare `aapt dump permissions` with runtime `PackageManager#getRequestedPermissions()`; missing dangerous perms is a red flag. |
| 54 | +* **Network Canary** – Configure `iptables -p tcp --dport 80 -j NFQUEUE` to detect unsolid POST bursts after code entry. |
| 55 | +* **mobileconfig Inspection** – Use `security cms -D -i profile.mobileconfig` on macOS to list `PayloadContent` and spot excessive entitlements. |
| 56 | + |
| 57 | +## Blue-Team Detection Ideas |
| 58 | + |
| 59 | +* **Certificate Transparency / DNS Analytics** to catch sudden bursts of keyword-rich domains. |
| 60 | +* **User-Agent & Path Regex**: `(?i)POST\s+/(check|upload)\.php` from Dalvik clients outside Google Play. |
| 61 | +* **Invite-code Telemetry** – POST of 6–8 digit numeric codes shortly after APK install may indicate staging. |
| 62 | +* **MobileConfig Signing** – Block unsigned configuration profiles via MDM policy. |
| 63 | + |
| 64 | +## Useful Frida Snippet: Auto-Bypass Invitation Code |
| 65 | + |
| 66 | +```python |
| 67 | +# frida -U -f com.badapp.android -l bypass.js --no-pause |
| 68 | +# Hook HttpURLConnection write to always return success |
| 69 | +Java.perform(function() { |
| 70 | + var URL = Java.use('java.net.___URL'); |
| 71 | + URL.openConnection.implementation = function() { |
| 72 | + var conn = this.openConnection(); |
| 73 | + var HttpURLConnection = Java.use('java.net.HttpURLConnection'); |
| 74 | + if (Java.cast(conn, HttpURLConnection)) { |
| 75 | + conn.getResponseCode.implementation = function(){ return 200; }; |
| 76 | + conn.getInputStream.implementation = function(){ |
| 77 | + return Java.use('java.io.ByteArrayInputStream').$new("{\"success\":true}".getBytes()); |
| 78 | + }; |
| 79 | + } |
| 80 | + return conn; |
| 81 | + }; |
| 82 | +}); |
| 83 | +``` |
| 84 | + |
| 85 | +## Indicators (Generic) |
| 86 | + |
| 87 | +``` |
| 88 | +/req/checkCode.php # invite code validation |
| 89 | +/upload.php # batched ZIP exfiltration |
| 90 | +LubanCompress 1.1.8 # "Luban" string inside classes.dex |
| 91 | +``` |
| 92 | + |
| 93 | +## References |
| 94 | + |
| 95 | +- [The Dark Side of Romance: SarangTrap Extortion Campaign](https://zimperium.com/blog/the-dark-side-of-romance-sarangtrap-extortion-campaign) |
| 96 | +- [Luban – Android image compression library](https://github.com/Curzibn/Luban) |
| 97 | + |
| 98 | +{{#include ../../banners/hacktricks-training.md}} |
0 commit comments