android-pentest-environment-setup

Complete Android app penetration testing environment setup with Android Studio, rooted emulator, Magisk, and reverse engineering tools

Skill file

Preview skill file
---
name: android-pentest-environment-setup
description: Complete Android app penetration testing environment setup with Android Studio, rooted emulator, Magisk, and reverse engineering tools
triggers:
  - how do I set up an Android pentesting environment
  - configure Android emulator for app security testing
  - root Android Studio emulator with Magisk
  - install frida on rooted Android emulator
  - setup Android app reverse engineering environment
  - configure proxy for Android app traffic interception
  - bypass Android SSL pinning with Magisk modules
  - setup ADB for Android security testing
---

# Android Penetration Testing Environment Setup

> Skill by [ara.so](https://ara.so) — Security Skills collection.

This skill covers setting up a complete Android application penetration testing environment using Android Studio emulators, including rooting with Magisk, installing security testing frameworks (Frida, LSPosed), and configuring traffic interception tools.

## What This Project Provides

A comprehensive guide to building a modern (2026) Android app penetration testing lab environment on Android Studio, including:

- Android Studio AVD (Android Virtual Device) configuration optimized for security testing
- Root access via Magisk framework
- Frida dynamic instrumentation framework
- LSPosed/Xposed module framework for runtime hooking
- SSL/TLS certificate pinning bypass capabilities
- Traffic interception setup with Burp Suite/mitmproxy
- Anti-emulator detection bypass techniques

**Key Advantages:**
- Reproducible environment using snapshots
- No need for physical devices
- Full system access for deep analysis
- Support for Android 16 (API 36)

**Limitations:**
- Some apps detect emulators and refuse to run
- Performance may be slower than physical devices

## Prerequisites

- macOS, Linux, or Windows
- 16GB+ RAM recommended
- Android Studio installed
- Proxy tool (Burp Suite, mitmproxy, Charles) for traffic analysis

## Installation

### 1. Install Android Studio and SDK

```bash
# macOS/Linux - Download from official site
# https://developer.android.google.cn/studio

# After installation, configure SDK path (default recommended)
# macOS: ~/Library/Android/sdk
# Linux: ~/Android/Sdk
# Windows: %LOCALAPPDATA%\Android\Sdk

# Set environment variables (macOS/Linux bash)
cat >> ~/.bash_profile << 'EOF'
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/emulator
EOF

source ~/.bash_profile

# For zsh users
cat >> ~/.zshrc << 'EOF'
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/emulator
EOF

source ~/.zshrc

# Verify ADB is accessible
adb version
```

**Windows PowerShell:**
```powershell
# Add to System Environment Variables
[Environment]::SetEnvironmentVariable("ANDROID_HOME", "$env:LOCALAPPDATA\Android\Sdk", "User")
$path = [Environment]::GetEnvironmentVariable("Path", "User")
[Environment]::SetEnvironmentVariable("Path", "$path;$env:ANDROID_HOME\platform-tools;$env:ANDROID_HOME\tools", "User")
```

### 2. Create Android Virtual Device (AVD)

```bash
# List available system images
sdkmanager --list | grep system-images

# Install Android 16 (API 36) Google APIs ARM64
sdkmanager "system-images;android-36;google_apis;arm64-v8a"

# Create AVD via command line (alternative to GUI)
avdmanager create avd \
  -n pentest_pixel9 \
  -k "system-images;android-36;google_apis;arm64-v8a" \
  -d "pixel_9_pro"

# Or use Android Studio GUI:
# More Actions → Virtual Device Manager → Create Device
# - Device: Pixel 9 Pro
# - System Image: API 36 (Android 16), Google APIs, arm64-v8a
# - Configuration:
#   * RAM: 4096 MB
#   * Internal Storage: 16384 MB
#   * VM heap: 512 MB
#   * Boot option: Cold Boot
```

**Important:** Choose **Google APIs** (NOT Google Play) to allow root access.

### 3. Root with Magisk (Method A: rootAVD - Recommended)

```bash
# Clone rootAVD tool
git clone https://gitlab.com/newbit/rootAVD.git
cd rootAVD

# Download latest Magisk APK and rename to Magisk.zip
# https://github.com/topjohnwu/Magisk/releases
curl -L -o Magisk.zip https://github.com/topjohnwu/Magisk/releases/download/v28.1/Magisk-v28.1.apk

# List available AVDs
./rootAVD.sh ListAllAVDs

# Root the specific system image
./rootAVD.sh system-images/android-36/google_apis/arm64-v8a/ramdisk.img

# Start emulator (will auto-install Magisk)
emulator -avd pentest_pixel9 -writable-system

# Verify root
adb shell su -c "id"
# Expected output: uid=0(root) gid=0(root)
```

### 4. Root with Magisk (Method B: Manual Patch - If rootAVD Fails)

```bash
# Start emulator with writable system
emulator -avd pentest_pixel9 -writable-system &
sleep 30
adb root
adb remount

# Install Magisk APK
adb install Magisk-v28.1.apk

# Push ramdisk to device
RAMDISK="$ANDROID_HOME/system-images/android-36/google_apis/arm64-v8a/ramdisk.img"
adb push "$RAMDISK" /sdcard/Download/ramdisk.img

# In Magisk app: Install → Select and Patch a File → Choose ramdisk.img
# Wait for patching to complete

# Pull patched ramdisk
adb pull /sdcard/Download/magisk_patched_*.img ./

# Replace original ramdisk
cp magisk_patched_*.img "$ANDROID_HOME/system-images/android-36/google_apis/arm64-v8a/ramdisk.img"

# Restart emulator
adb reboot
```

## Key Commands

### ADB (Android Debug Bridge)

```bash
# List connected devices
adb devices

# Connect to specific emulator
adb -s emulator-5554 shell

# Install APK
adb install app.apk
adb install -r app.apk  # Reinstall keeping data

# Pull/Push files
adb pull /data/data/com.example.app/databases/app.db ./
adb push burp-cert.der /sdcard/

# Forward ports
adb forward tcp:8080 tcp:8080

# Get root shell
adb root
adb shell

# Remount system as writable
adb remount

# Log viewing
adb logcat | grep -i "com.example.app"
adb logcat -c  # Clear logs

# Screen capture
adb shell screencap /sdcard/screen.png
adb pull /sdcard/screen.png

# Start/Stop app
adb shell am start -n com.example.app/.MainActivity
adb shell am force-stop com.example.app
```

### Magisk Module Management

```bash
# Install module via ADB
adb push module.zip /sdcard/Download/
adb shell su -c "magisk --install-module /sdcard/Download/module.zip"

# List installed modules
adb shell su -c "ls /data/adb/modules"

# Enable Zygisk (required for LSPosed)
adb shell su -c "magisk --sqlite 'UPDATE settings SET value=1 WHERE key=\"zygisk\"'"
adb reboot

# Check Magisk status
adb shell su -c "magisk -v"
```

## Installing Security Testing Frameworks

### 1. Install Frida

```bash
# Get Android architecture
adb shell getprop ro.product.cpu.abi
# Output: arm64-v8a

# Download Frida server (match version with frida-tools)
FRIDA_VERSION=$(pip3 show frida | grep Version | cut -d' ' -f2)
wget "https://github.com/frida/frida/releases/download/${FRIDA_VERSION}/frida-server-${FRIDA_VERSION}-android-arm64.xz"
unxz frida-server-*-android-arm64.xz

# Push to device
adb root
adb push frida-server-*-android-arm64 /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server

# Start Frida server
adb shell "/data/local/tmp/frida-server &"

# Verify on host
pip3 install frida-tools
frida-ps -U
# Should list running processes
```

**Persistent Frida with Magisk Module:**

```bash
# Create Magisk module structure
mkdir -p frida-module/system/bin
cp frida-server-*-android-arm64 frida-module/system/bin/frida-server

# Create module.prop
cat > frida-module/module.prop << 'EOF'
id=frida_server
name=Frida Server
version=16.5.0
versionCode=16050
author=Frida
description=Frida dynamic instrumentation toolkit
EOF

# Create service script
cat > frida-module/service.sh << 'EOF'
#!/system/bin/sh
/system/bin/frida-server &
EOF

# Package and install
cd frida-module
zip -r ../frida-module.zip .
adb push ../frida-module.zip /sdcard/
adb shell su -c "magisk --install-module /sdcard/frida-module.zip"
adb reboot
```

### 2. Install LSPosed (Xposed Framework)

```bash
# Download LSPosed Zygisk version
# https://github.com/LSPosed/LSPosed/releases
wget https://github.com/LSPosed/LSPosed/releases/download/v1.9.2/LSPosed-v1.9.2-7024-zygisk-release.zip

# Install via Magisk
adb push LSPosed-v1.9.2-7024-zygisk-release.zip /sdcard/
adb shell su -c "magisk --install-module /sdcard/LSPosed-v1.9.2-7024-zygisk-release.zip"
adb reboot

# Access LSPosed Manager (after reboot)
# Notification will appear, or run:
adb shell am start -n org.lsposed.manager/.ui.activity.MainActivity
```

**Common LSPosed Modules for Pentesting:**

```bash
# TrustMeAlready - Bypass SSL pinning
# https://github.com/ViRb3/TrustMeAlready/releases

# JustTrustMe - Alternative SSL bypass
# Install via LSPosed Manager → Repository

# XPrivacyLua - Privacy/permission control
# Useful for testing permission bypasses
```

### 3. Install ZygiskNext (Improved Zygisk)

```bash
# Download ZygiskNext
wget https://github.com/Dr-TSNG/ZygiskNext/releases/download/v4.0.1/Zygisk-Next-4.0.1-release.zip

# Disable built-in Zygisk first
adb shell su -c "magisk --sqlite 'UPDATE settings SET value=0 WHERE key=\"zygisk\"'"

# Install ZygiskNext
adb push Zygisk-Next-4.0.1-release.zip /sdcard/
adb shell su -c "magisk --install-module /sdcard/Zygisk-Next-4.0.1-release.zip"
adb reboot
```

## SSL/TLS Certificate Pinning Bypass

### Method 1: System Certificate Installation

```bash
# Convert PEM cert to Android format
openssl x509 -inform PEM -subject_hash_old -in burp-cert.pem | head -1
# Output: 9a5ba575

# Rename cert
cp burp-cert.pem 9a5ba575.0

# Push to system store
adb root
adb remount
adb push 9a5ba575.0 /system/etc/security/cacerts/
adb shell chmod 644 /system/etc/security/cacerts/9a5ba575.0
adb reboot
```

### Method 2: Using Magisk Modules

**Install TrustMeAlready:**

```bash
# Download from LSPosed Manager or:
adb push TrustMeAlready.apk /sdcard/
adb install /sdcard/TrustMeAlready.apk

# Enable in LSPosed:
# 1. Open LSPosed Manager
# 2. Modules → TrustMeAlready → Enable
# 3. Select target apps
# 4. Reboot
```

**Install Shamiko (Hide root from apps):**

```bash
wget https://github.com/LSPosed/LSPosed.github.io/releases/download/shamiko-354/Shamiko-v0.7.4-354-release.zip
adb push Shamiko-v0.7.4-354-release.zip /sdcard/
adb shell su -c "magisk --install-module /sdcard/Shamiko-v0.7.4-354-release.zip"
adb reboot
```

## Traffic Interception Setup

### Configure Proxy on Emulator

```bash
# Method 1: Via ADB (requires root)
adb shell settings put global http_proxy <HOST_IP>:8080

# Method 2: Via emulator settings
# Settings → Network & Internet → Wi-Fi → AndroidWifi → 
# Proxy → Manual → Hostname: <HOST_IP>, Port: 8080

# Disable proxy
adb shell settings put global http_proxy :0

# Verify proxy settings
adb shell settings get global http_proxy
```

### Burp Suite Configuration

```bash
# 1. Export Burp CA certificate (DER format)
# Proxy → Options → Import/Export CA Certificate → Export DER

# 2. Push to emulator
adb push burp-cert.der /sdcard/

# 3. Install via Settings
# Settings → Security → Install from SD card → Select burp-cert.der

# 4. For system-level trust (Android 7+)
openssl x509 -inform DER -in burp-cert.der -out burp-cert.pem
openssl x509 -inform PEM -subject_hash_old -in burp-cert.pem | head -1
# e.g., output: 9a5ba575
cp burp-cert.pem 9a5ba575.0

adb root
adb remount
adb push 9a5ba575.0 /system/etc/security/cacerts/
adb shell chmod 644 /system/etc/security/cacerts/9a5ba575.0
adb reboot
```

## Frida Scripts for Common Tasks

### Bypass SSL Pinning (Universal Script)

```javascript
// ssl-pinning-bypass.js
Java.perform(function() {
    console.log("[*] Bypassing SSL Pinning...");
    
    // OkHttp3
    try {
        var CertificatePinner = Java.use('okhttp3.CertificatePinner');
        CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function() {
            console.log('[+] OkHttp3 pinning bypassed');
            return;
        };
    } catch(err) {
        console.log('[-] OkHttp3 not found');
    }
    
    // TrustManager
    var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
    var SSLContext = Java.use('javax.net.ssl.SSLContext');
    
    var TrustManager = Java.registerClass({
        name: 'dev.asd.test.TrustManager',
        implements: [X509TrustManager],
        methods: {
            checkClientTrusted: function(chain, authType) {},
            checkServerTrusted: function(chain, authType) {},
            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(keyManager, trustManager, secureRandom) {
        console.log('[+] TrustManager bypassed');
        SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
    };
});
```

**Run the script:**

```bash
frida -U -f com.example.app -l ssl-pinning-bypass.js --no-pause
```

### Extract Shared Preferences

```javascript
// extract-prefs.js
Java.perform(function() {
    var context = Java.use('android.app.ActivityThread')
        .currentApplication()
        .getApplicationContext();
    
    var prefsDir = context.getFilesDir().getParent() + '/shared_prefs';
    console.log('[*] Shared Preferences location:', prefsDir);
    
    var File = Java.use('java.io.File');
    var dir = File.$new(prefsDir);
    var files = dir.listFiles();
    
    for (var i = 0; i < files.length; i++) {
        console.log('[+] Found:', files[i].getName());
    }
});
```

### Hook Crypto Functions

```javascript
// crypto-hook.js
Java.perform(function() {
    var Cipher = Java.use('javax.crypto.Cipher');
    
    Cipher.doFinal.overload('[B').implementation = function(byteArr) {
        console.log('[*] Cipher.doFinal called');
        console.log('[*] Algorithm:', this.getAlgorithm());
        console.log('[*] Input:', Java.use('android.util.Base64')
            .encodeToString(byteArr, 0));
        
        var result = this.doFinal(byteArr);
        console.log('[*] Output:', Java.use('android.util.Base64')
            .encodeToString(result, 0));
        return result;
    };
});
```

## Troubleshooting

### Emulator Won't Start

```bash
# Check available resources
emulator -list-avds
emulator -avd pentest_pixel9 -verbose

# Try cold boot
emulator -avd pentest_pixel9 -no-snapshot-load

# Wipe data if corrupted
emulator -avd pentest_pixel9 -wipe-data
```

### ADB Can't Connect

```bash
# Kill and restart ADB server
adb kill-server
adb start-server

# Check emulator port
adb devices
# emulator-5554 device

# Manually connect
adb connect localhost:5554
```

### Magisk Not Working After Reboot

```bash
# Re-run rootAVD
cd rootAVD
./rootAVD.sh system-images/android-36/google_apis/arm64-v8a/ramdisk.img

# Or restore from snapshot before rooting
```

### Frida Connection Issues

```bash
# Ensure frida-server is running
adb shell "ps | grep frida-server"

# Kill and restart
adb shell "pkill frida-server"
adb shell "/data/local/tmp/frida-server &"

# Check port forwarding
adb forward tcp:27042 tcp:27042

# Verify version match
frida --version
adb shell /data/local/tmp/frida-server --version
```

### LSPosed Not Appearing

```bash
# Verify Zygisk is enabled
adb shell su -c "magisk --sqlite 'SELECT * FROM settings WHERE key=\"zygisk\"'"
# Should show value=1

# Check module status
adb shell su -c "ls -la /data/adb/modules/zygisk_lsposed"

# View logs
adb logcat | grep -i lsposed
```

### App Detects Emulator

**Use Shamiko + DenyList:**

```bash
# Enable Shamiko (if not already)
# Configure DenyList in Magisk
adb shell su -c "magisk --denylist add com.example.app"
adb shell su -c "magisk --denylist enable"

# Hide Magisk app itself
# Magisk → Settings → Hide Magisk App → Random package name
```

**Modify build.prop:**

```bash
adb root
adb remount
adb pull /system/build.prop

# Edit locally, change:
# ro.product.manufacturer=Google
# ro.product.model=Pixel 9 Pro
# ro.build.fingerprint=google/...

adb push build.prop /system/build.prop
adb reboot
```

### SSL Pinning Still Active

```bash
# Try multiple bypass methods simultaneously
frida -U -f com.example.app \
  -l ssl-pinning-bypass.js \
  -l universal-ssl-bypass.js \
  --no-pause

# Enable TrustMeAlready in LSPosed for target app
# Reboot and test again
```

## Advanced Configuration

### Create Snapshot After Setup

```bash
# Via Android Studio GUI
# Virtual Device Manager → AVD → Dropdown → Snapshots → Take Snapshot

# Via command line (emulator must be running)
adb shell "sync; echo 3 > /proc/sys/vm/drop_caches"
# Then use GUI to snapshot
```

### Automated Environment Setup Script

```bash
#!/bin/bash
# setup-pentest-env.sh

AVD_NAME="pentest_pixel9"
ANDROID_API="android-36"
ARCH="arm64-v8a"

echo "[*] Setting up Android Pentest Environment..."

# Install system image
sdkmanager "system-images;${ANDROID_API};google_apis;${ARCH}"

# Create AVD
avdmanager create avd -n ${AVD_NAME} \
  -k "system-images;${ANDROID_API};google_apis;${ARCH}" \
  -d "pixel_9_pro" --force

# Root with rootAVD
cd rootAVD
./rootAVD.sh system-images/${ANDROID_API}/google_apis/${ARCH}/ramdisk.img

# Start emulator
emulator -avd ${AVD_NAME} -writable-system &
sleep 60

# Install Frida
FRIDA_VERSION=$(pip3 show frida | grep Version | awk '{print $2}')
wget -q "https://github.com/frida/frida/releases/download/${FRIDA_VERSION}/frida-server-${FRIDA_VERSION}-android-${ARCH}.xz"
unxz frida-server-*.xz
adb root
adb push frida-server-* /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
adb shell "/data/local/tmp/frida-server &"

echo "[+] Setup complete. Connect via: adb -s emulator-5554 shell"
```

## References

- Original project: https://github.com/d0ctorsec/AndroidStudioAppPentestEnvironmentSetup
- rootAVD: https://gitlab.com/newbit/rootAVD
- Magisk: https://github.com/topjohnwu/Magisk
- Frida: https://frida.re
- LSPosed: https://github.com/LSPosed/LSPosed

Source

Creator's repository · aradotso/security-skills

View on GitHub

Security

Security checks in progress
Results will appear here once audits complete
Checked by 3 independent security firms
Does it try to trick the AI?Not yet checkedPending · Gen Agent Trust Hub
Does it sneak in hidden code?Not yet checkedPending · Socket
Does it have known bugs?Not yet checkedPending · Snyk