| name | android-mobile-security-sandbox-jamboree |
| description | JAMBOREE Android security testing framework integrating Magisk, Burp Suite, Objection, and Frida for comprehensive mobile app penetration testing |
| triggers | ["set up android security testing environment","configure jamboree framework for mobile pentesting","integrate burp suite with android emulator","bypass ssl pinning on android app","use objection to hook android methods","set up magisk for rooted testing environment","intercept android app traffic with burp","automate frida scripts for android analysis"] |
Android Mobile Security Sandbox JAMBOREE
Skill by ara.so — Security Skills collection
Overview
JAMBOREE (Java Android Magisk Burp Objection Root Emulator Easy) is a unified Android security testing framework that orchestrates multiple tools into a cohesive pentesting environment. It automates the integration of:
- Magisk modules for systemless root and module management
- Burp Suite proxy for traffic interception and certificate handling
- Objection/Frida for runtime instrumentation and hooking
- Rooted Android emulators optimized for security testing
This framework eliminates fragmented workflows by providing pre-configured components that work together seamlessly for Android application security assessment.
Installation
Prerequisites
Ensure the following are installed:
java -version
which adb
python3 --version
pip3 install frida-tools objection
Framework Setup
git clone https://github.com/hero-mike/Android-Mobile-Security-Sandbox-Testing.git
cd Android-Mobile-Security-Sandbox-Testing
chmod +x orchestration/deploy.sh
./orchestration/deploy.sh
./orchestration/validate.sh
The deployment script will:
- Validate dependencies
- Configure Android emulator with Magisk
- Install Burp Suite CA certificates
- Deploy Objection scripts and Frida gadgets
- Set up proxy routing
Core Components
1. Magisk Module Management
adb push modules/magisk/systemless/universal-safetynet-fix.zip /sdcard/
adb shell su -c "magisk --install-module /sdcard/universal-safetynet-fix.zip"
adb shell su -c "ls /data/adb/modules"
adb shell su -c "touch /data/adb/modules/module-name/disable"
adb reboot
adb shell su -c "rm -rf /data/adb/modules/module-name"
Custom Module Installation:
adb push configurations/android/custom-init.sh /data/adb/service.d/
adb shell su -c "chmod 755 /data/adb/service.d/custom-init.sh"
2. Burp Suite Integration
Certificate Installation:
openssl x509 -inform DER -in burp-ca.der -out burp-ca.pem
CERT_HASH=$(openssl x509 -inform PEM -subject_hash_old -in burp-ca.pem | head -1)
adb root
adb remount
adb push burp-ca.pem /system/etc/security/cacerts/${CERT_HASH}.0
adb shell chmod 644 /system/etc/security/cacerts/${CERT_HASH}.0
adb reboot
Proxy Configuration:
adb shell settings put global http_proxy <HOST_IP>:8080
./orchestration/deployers/burp-proxy-setup.sh --host 192.168.1.100 --port 8080
adb shell settings get global http_proxy
adb shell settings put global http_proxy :0
VPN-based Interception:
adb install modules/burp/proxy-vpn.apk
adb shell am start -n com.proxyvpn/.MainActivity \
--es PROXY_HOST "192.168.1.100" \
--ei PROXY_PORT 8080
3. Objection Runtime Instrumentation
Basic Objection Usage:
frida-ps -Ua
objection -g com.example.target explore
objection -g com.example.target run
SSL Pinning Bypass:
android sslpinning disable
objection -g com.example.target explore \
-s "android sslpinning disable" \
-s "jobs list"
Common Objection Commands:
android hooking list activities
android hooking list classes
android hooking search methods decrypt
android hooking watch class_method com.example.Crypto.decrypt --dump-args --dump-return
android root disable
android file shared-preferences list
android file shared-preferences read com.example.target.prefs user_token
android sqlite list
android sqlite query /data/data/com.example.target/databases/main.db "SELECT * FROM users"
memory dump all /tmp/memory-dump.bin
android hooking dump class com.example.target.MainActivity
Custom Frida Scripts:
Create hooks/ssl-bypass.js:
Java.perform(function() {
console.log("[*] SSL Pinning Bypass Active");
var CertificatePinner = Java.use("okhttp3.CertificatePinner");
CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function() {
console.log("[+] Bypassed OkHttp3 Certificate Pinner");
};
var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
console.log("[+] Bypassed TrustManagerImpl verification for: " + host);
return untrustedChain;
};
var SSLContext = Java.use("javax.net.ssl.SSLContext");
SSLContext.init.overload('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom').implementation = function(keyManager, trustManager, secureRandom) {
console.log("[+] SSLContext.init() called, accepting all certificates");
this.init.overload('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom').call(this, keyManager, null, secureRandom);
};
});
Load custom script:
frida -U -l hooks/ssl-bypass.js -f com.example.target
objection -g com.example.target explore --startup-script hooks/ssl-bypass.js
Method Hooking Template:
Java.perform(function() {
var TargetClass = Java.use("com.example.target.Crypto");
TargetClass.encrypt.implementation = function(plaintext, key) {
console.log("[*] Encrypt called");
console.log("[*] Plaintext: " + plaintext);
console.log("[*] Key: " + key);
var result = this.encrypt(plaintext, key);
console.log("[*] Encrypted result: " + result);
return result;
};
TargetClass.processData.overload('java.lang.String').implementation = function(data) {
console.log("[*] processData(String) called with: " + data);
return this.processData(data);
};
TargetClass.processData.overload('[B').implementation = function(data) {
console.log("[*] processData(byte[]) called");
return this.processData(data);
};
});
4. Emulator Configuration
Create Rooted AVD:
./orchestration/deployers/create-rooted-avd.sh \
--name jamboree-test \
--api 30 \
--arch x86_64
avdmanager create avd \
-n security-test \
-k "system-images;android-30;google_apis;x86_64" \
-d "pixel_4"
emulator -avd security-test -writable-system -no-snapshot-load &
adb wait-for-device
adb install modules/magisk/Magisk-v26.1.apk
Anti-Emulation Evasion:
adb shell su -c "mount -o rw,remount /system"
adb shell su -c "echo 'ro.build.fingerprint=google/redfin/redfin:11/RQ3A.211001.001/7641976:user/release-keys' >> /system/build.prop"
adb shell su -c "echo 'ro.product.manufacturer=Google' >> /system/build.prop"
adb reboot
adb shell su -c "setprop ro.kernel.qemu 0"
adb shell su -c "setprop ro.hardware.goldfish 0"
Workflow Patterns
Complete Penetration Test Setup
#!/bin/bash
TARGET_PACKAGE="com.example.target"
BURP_HOST="192.168.1.100"
BURP_PORT="8080"
echo "[*] Starting JAMBOREE penetration test environment"
emulator -avd jamboree-test -writable-system -no-snapshot-load &
adb wait-for-device
sleep 10
adb shell settings put global http_proxy ${BURP_HOST}:${BURP_PORT}
adb shell su -c "id" || { echo "[!] Root not available"; exit 1; }
adb install -r target-app.apk
objection -g ${TARGET_PACKAGE} explore \
--startup-script hooks/ssl-bypass.js &
echo "[+] Environment ready. Burp Suite should show traffic."
Automated Hook Deployment
import frida
import sys
HOOKS = {
"crypto": """
Java.perform(function() {
var Cipher = Java.use("javax.crypto.Cipher");
Cipher.doFinal.overload('[B').implementation = function(data) {
console.log("[Cipher] doFinal called with " + data.length + " bytes");
return this.doFinal(data);
};
});
""",
"network": """
Java.perform(function() {
var URL = Java.use("java.net.URL");
URL.$init.overload('java.lang.String').implementation = function(url) {
console.log("[Network] URL requested: " + url);
return this.$init(url);
};
});
"""
}
def attach_hooks(package_name, hook_type):
device = frida.get_usb_device()
pid = device.spawn([package_name])
session = device.attach(pid)
script = session.create_script(HOOKS[hook_type])
script.on('message', lambda msg, data: print(msg))
script.load()
device.resume(pid)
print(f"[+] {hook_type} hooks attached to {package_name}")
sys.stdin.read()
if __name__ == "__main__":
attach_hooks(sys.argv[1], sys.argv[2])
Usage:
python3 deploy_hooks.py com.example.target crypto
Traffic Analysis Workflow
adb shell pm clear com.example.target
adb shell su -c "tcpdump -i wlan0 -w /sdcard/capture.pcap" &
objection -g com.example.target explore \
-s "android sslpinning disable" \
-s "android root disable"
adb shell su -c "killall tcpdump"
adb pull /sdcard/capture.pcap ./analysis/
Configuration Files
Burp Suite Extension Config
configurations/burp/extension-config.json:
{
"proxy": {
"enabled": true,
"host": "0.0.0.0",
"port": 8080,
"ssl": {
"generateCert": true,
"certPath": "/certificates/burp-ca.pem"
}
},
"interceptRules": [
{
"match": ".*\\.api\\.example\\.com.*",
"action": "intercept",
"modifyHeaders": {
"User-Agent": "CustomAgent/1.0"
}
}
],
"bypassSSL": true
}
Objection Startup Scripts
configurations/objection/startup.js:
android sslpinning disable;
android root disable;
android hooking watch class_method com.example.target.Auth.login --dump-args --dump-return;
android hooking watch class_method com.example.target.Network.makeRequest --dump-args --dump-return;
android hooking watch class java.io.FileOutputStream.$init --dump-args;
console.log("[JAMBOREE] Startup hooks loaded");
Load on startup:
objection -g com.example.target explore --startup-script configurations/objection/startup.js
Troubleshooting
Certificate Trust Issues
Symptom: HTTPS traffic not decrypted in Burp Suite
Solutions:
adb shell ls -la /system/etc/security/cacerts/ | grep $(openssl x509 -inform PEM -subject_hash_old -in burp-ca.pem | head -1)
openssl x509 -in /system/etc/security/cacerts/9a5ba575.0 -text -noout
adb shell su -c "chmod 644 /system/etc/security/cacerts/*.0"
adb push modules/magisk/movecert.zip /sdcard/
adb shell su -c "magisk --install-module /sdcard/movecert.zip"
adb reboot
Frida/Objection Connection Failures
Symptom: Failed to spawn: unable to find application with identifier
Solutions:
frida --version
adb shell /data/local/tmp/frida-server --version
wget https://github.com/frida/frida/releases/download/$(frida --version)/frida-server-$(frida --version)-android-x86_64.xz
unxz frida-server-*.xz
adb push frida-server-* /data/local/tmp/frida-server
adb shell su -c "chmod 755 /data/local/tmp/frida-server"
adb shell su -c "/data/local/tmp/frida-server &"
adb shell pm dump com.example.target | grep -A 1 "debuggable"
apktool d target.apk
apktool b target -o target-debug.apk
jarsigner -keystore debug.keystore target-debug.apk androiddebugkey
adb install target-debug.apk
Magisk Module Conflicts
Symptom: Device bootloop or modules not loading
Solutions:
adb shell su -c "touch /data/adb/modules/problem-module/disable"
adb reboot
adb shell su -c "rm -rf /data/adb/modules/*"
adb reboot
adb shell su -c "cat /cache/magisk.log"
Proxy Not Routing Traffic
Symptom: No requests appearing in Burp Suite
Solutions:
adb shell settings get global http_proxy
adb shell curl -x http://192.168.1.100:8080 http://example.com
adb shell su -c "iptables -t nat -L -n -v"
adb shell su -c "iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080"
adb shell su -c "iptables -t nat -A OUTPUT -p tcp --dport 443 -j DNAT --to-destination 192.168.1.100:8080"
adb install modules/burp/drony.apk
Advanced Techniques
Custom Magisk Module Creation
#!/system/bin/sh
MODDIR=${0%/*}
resetprop ro.debuggable 0
resetprop ro.secure 1
magiskhide enable
magiskhide add com.example.target
mount -o bind $MODDIR/system/lib/libc.so /system/lib/libc.so
log -p i -t JAMBOREE "Custom bypass module loaded"
Module metadata (module.prop):
id=jamboree-custom-bypass
name=JAMBOREE Custom Bypass
version=1.0
versionCode=1
author=YourName
description=Custom root and emulator detection bypass
Install:
cd modules/magisk/custom-bypass
zip -r custom-bypass.zip .
adb push custom-bypass.zip /sdcard/
adb shell su -c "magisk --install-module /sdcard/custom-bypass.zip"
adb reboot
Runtime Memory Manipulation
Java.perform(function() {
var String = Java.use("java.lang.String");
var token = null;
var SharedPreferences = Java.use("android.content.SharedPreferences");
var Editor = Java.use("android.content.SharedPreferences$Editor");
Editor.putString.implementation = function(key, value) {
if (key.indexOf("token") !== -1 || key.indexOf("auth") !== -1) {
console.log("[*] Token stored: " + key + " = " + value);
token = value;
var File = Java.use("java.io.File");
var FileWriter = Java.use("java.io.FileWriter");
var file = File.$new("/sdcard/extracted-token.txt");
var writer = FileWriter.$new(file);
writer.write(value);
writer.close();
}
return this.putString(key, value);
};
});
Automated Testing Pipeline
import subprocess
import time
import json
class JAMBOREEPipeline:
def __init__(self, package_name, burp_host="192.168.1.100"):
self.package = package_name
self.burp_host = burp_host
self.results = {"findings": []}
def setup_environment(self):
"""Configure emulator and proxy"""
subprocess.run(["adb", "wait-for-device"])
subprocess.run(["adb", "shell", "settings", "put", "global",
"http_proxy", f"{self.burp_host}:8080"])
print("[+] Environment configured")
def deploy_hooks(self):
"""Load Frida scripts"""
scripts = [
"hooks/ssl-bypass.js",
"hooks/root-bypass.js",
"hooks/crypto-trace.js"
]
for script in scripts:
subprocess.Popen(["frida", "-U", "-l", script,
"-f", self.package])
print("[+] Hooks deployed")
def run_tests(self):
"""Execute test scenarios"""
test_cases = [
self.test_ssl_pinning,
self.test_root_detection,
self.test_data_storage
]
for test in test_cases:
result = test()
if result:
self.results["findings"].append(result)
def test_ssl_pinning(self):
"""Test SSL certificate pinning bypass"""
print("[*] Testing SSL pinning...")
subprocess.run(["adb", "shell", "monkey", "-p", self.package,
"-c", "android.intent.category.LAUNCHER", "1"])
time.sleep(5)
return {"test": "ssl_pinning", "status": "bypassed"}
def test_root_detection(self):
"""Test root detection bypass"""
print("[*] Testing root detection...")
result = subprocess.run(
["adb", "shell", "su", "-c", "id"],
capture_output=True, text=True
)
if "uid=0" in result.stdout:
return {"test": "root_detection", "status": "bypassed"}
return None
def test_data_storage(self):
"""Check for sensitive data in storage"""
print("[*] Checking data storage...")
result = subprocess.run([
"adb", "shell", "su", "-c",
f"find /data/data/{self.package} -name '*.db' -o -name '*.xml'"
], capture_output=True, text=True)
files = result.stdout.strip().split('\n')
return {"test": "data_storage", "files": files}
def generate_report(self):
"""Output findings"""
with open("test-results.json", "w") as f:
json.dump(self.results, f, indent=2)
print(f"[+] Report saved: test-results.json")
if __name__ == "__main__":
pipeline = JAMBOREEPipeline("com.example.target")
pipeline.setup_environment()
pipeline.deploy_hooks()
pipeline.run_tests()
pipeline.generate_report()
Run the pipeline:
python3 automation/test-pipeline.py
Environment Variables
export JAMBOREE_HOME="/path/to/Android-Mobile-Security-Sandbox-Testing"
export JAMBOREE_BURP_HOST="192.168.1.100"
export JAMBOREE_BURP_PORT="8080"
export JAMBOREE_AVD_NAME="jamboree-test"
export ANDROID_SDK_ROOT="/path/to/android-sdk"
export FRIDA_SERVER_VERSION="16.1.4"
source ${JAMBOREE_HOME}/orchestration/helpers.sh
This skill provides comprehensive coverage of the JAMBOREE framework for AI agents to assist developers with Android security testing workflows, from initial setup through advanced exploitation techniques.