| name | jamboree-android-security-sandbox |
| description | Configure and orchestrate Android security testing environments with Magisk, Burp Suite, Objection, and rooted emulators for penetration testing. |
| triggers | ["set up android security testing environment","configure burp suite with android emulator","use objection to hook android app","bypass android certificate pinning","set up magisk modules for testing","configure rooted android emulator for pentesting","intercept android app traffic with burp","hook android runtime with frida objection"] |
JAMBOREE Android Security Sandbox Skill
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 integrates:
- Magisk: Systemless root and module management
- Burp Suite: HTTPS traffic interception and analysis
- Objection: Frida-powered runtime instrumentation
- Rooted Emulator: Pre-configured Android Virtual Devices
This skill enables AI agents to help developers configure, deploy, and use JAMBOREE for Android application security assessment, penetration testing, and reverse engineering.
Installation
Prerequisites Verification
Before deployment, verify the environment has required dependencies:
java -version
adb version
avdmanager list
python3 --version
which burpsuite || echo "Burp Suite not found in PATH"
Core Installation Steps
- Clone and Initialize
git clone https://github.com/hero-mike/Android-Mobile-Security-Sandbox-Testing.git
cd Android-Mobile-Security-Sandbox-Testing
./orchestration/validators/check-prerequisites.sh
- Deploy Core Components
./orchestration/validators/validate-all.sh
./orchestration/deployers/deploy-magisk.sh
./orchestration/deployers/setup-burp-proxy.sh
./orchestration/deployers/install-objection.sh
- Calibrate Settings
cp configurations/android/default.conf configurations/android/custom.conf
nano configurations/android/custom.conf
./orchestration/calibrators/apply-config.sh custom
Configuration
Android Emulator Setup
Create or modify an AVD for security testing:
avdmanager list targets
avdmanager create avd \
-n jamboree-test \
-k "system-images;android-33;google_apis_playstore;x86_64" \
-d "pixel_5" \
-c 4096M
emulator -avd jamboree-test -writable-system -no-snapshot-load &
adb wait-for-device
adb root
adb remount
Magisk Module Configuration
Deploy core modules for testing:
adb install modules/magisk/MagiskManager.apk
adb push modules/magisk/systemless/busybox.zip /sdcard/
adb shell magisk --install-module /sdcard/busybox.zip
adb push modules/magisk/systemless/ssl-unpinning.zip /sdcard/
adb shell magisk --install-module /sdcard/ssl-unpinning.zip
adb reboot
adb wait-for-device
Burp Suite Proxy Setup
Configure system-wide traffic interception:
openssl x509 -inform DER -in burp-cert.der -out burp-cert.pem
CERT_HASH=$(openssl x509 -inform PEM -subject_hash_old -in burp-cert.pem | head -1)
adb root
adb remount
adb push burp-cert.pem /system/etc/security/cacerts/${CERT_HASH}.0
adb shell chmod 644 /system/etc/security/cacerts/${CERT_HASH}.0
adb shell settings put global http_proxy ${BURP_HOST}:${BURP_PORT}
adb shell iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination ${BURP_HOST}:${BURP_PORT}
adb shell iptables -t nat -A OUTPUT -p tcp --dport 443 -j DNAT --to-destination ${BURP_HOST}:${BURP_PORT}
Configuration file example (configurations/network/burp-proxy.conf):
[proxy]
host = 192.168.1.100
port = 8080
upstream_proxy =
cert_path = ./modules/burp/certificates/burp-ca.pem
[interception]
mode = transparent
dns_spoofing = true
ssl_passthrough = false
[filters]
include_hosts = *.example.com,*.target-app.io
exclude_hosts = *.google.com,*.android.com
Objection Environment
Install and configure Objection with Frida:
pip3 install objection
FRIDA_VERSION=$(frida --version)
wget https://github.com/frida/frida/releases/download/${FRIDA_VERSION}/frida-server-${FRIDA_VERSION}-android-x86_64.xz
unxz frida-server-${FRIDA_VERSION}-android-x86_64.xz
adb push frida-server-${FRIDA_VERSION}-android-x86_64 /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server"
adb shell "/data/local/tmp/frida-server &"
Key Commands and Workflows
Basic Application Analysis
adb shell pm list packages | grep -i target
adb shell dumpsys package com.example.targetapp
adb shell pm path com.example.targetapp
adb pull /data/app/~~random~~/com.example.targetapp-hash==/base.apk
Objection Runtime Hooking
Launch Objection against a running app:
objection -g com.example.targetapp explore
objection -g $(adb shell pidof com.example.targetapp) explore
Common Objection commands in the interactive shell:
android hooking list activities
android hooking list classes
android hooking search methods encrypt
android hooking search classes database
android hooking watch class_method com.example.crypto.AES.encrypt --dump-args --dump-return
android root disable
android sslpinning disable
sqlite connect /data/data/com.example.targetapp/databases/app.db
.tables
SELECT * FROM users;
android hooking list shared_preferences
android hooking get shared_preference com.example.targetapp_preferences
memory dump all com.example.targetapp
memory search "password" --string
Advanced Frida Scripts
Custom hooking scripts in modules/objection/scripts/:
hook-crypto.js - Monitor cryptographic operations:
Java.perform(function() {
var Cipher = Java.use('javax.crypto.Cipher');
Cipher.doFinal.overload('[B').implementation = function(input) {
console.log('[Cipher.doFinal] Input length: ' + input.length);
console.log('[Cipher.doFinal] Input hex: ' + bytesToHex(input));
var result = this.doFinal(input);
console.log('[Cipher.doFinal] Output length: ' + result.length);
console.log('[Cipher.doFinal] Output hex: ' + bytesToHex(result));
return result;
};
function bytesToHex(bytes) {
var hex = [];
for (var i = 0; i < bytes.length && i < 32; i++) {
hex.push(('0' + (bytes[i] & 0xFF).toString(16)).slice(-2));
}
return hex.join(' ') + (bytes.length > 32 ? '...' : '');
}
console.log('[+] Cipher.doFinal hooked');
});
bypass-root-check.js - Defeat root detection:
Java.perform(function() {
var RootDetection = Java.use('com.example.security.RootDetection');
RootDetection.isRooted.implementation = function() {
console.log('[Root Detection] Bypass triggered');
return false;
};
RootDetection.checkSuperUser.implementation = function() {
console.log('[Root Detection] SuperUser check bypassed');
return false;
};
RootDetection.checkBuildTags.implementation = function() {
console.log('[Root Detection] Build tags check bypassed');
return false;
};
console.log('[+] Root detection bypassed');
});
Load custom scripts:
objection -g com.example.targetapp explore -s modules/objection/scripts/hook-crypto.js
frida -U -l modules/objection/scripts/bypass-root-check.js -f com.example.targetapp
Burp Suite Automation
Extend Burp with Python extensions in modules/burp/extensions/:
auto-scanner.py - Automated endpoint discovery:
from burp import IBurpExtender, IHttpListener, ITab
from javax.swing import JPanel, JTextArea, JScrollPane
import json
class BurpExtender(IBurpExtender, IHttpListener, ITab):
def registerExtenderCallbacks(self, callbacks):
self._callbacks = callbacks
self._helpers = callbacks.getHelpers()
callbacks.setExtensionName("JAMBOREE Auto Scanner")
self.endpoints = set()
self.setup_ui()
callbacks.registerHttpListener(self)
def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
if not messageIsRequest:
return
request = messageInfo.getRequest()
analyzedRequest = self._helpers.analyzeRequest(messageInfo)
url = analyzedRequest.getUrl()
endpoint = f"{url.getProtocol()}://{url.getHost()}{url.getPath()}"
if endpoint not in self.endpoints:
self.endpoints.add(endpoint)
self.update_display()
def setup_ui(self):
self.panel = JPanel()
self.textarea = JTextArea(20, 80)
self.textarea.setEditable(False)
scrollPane = JScrollPane(self.textarea)
self.panel.add(scrollPane)
self._callbacks.addSuiteTab(self)
def update_display(self):
output = "\n".join(sorted(self.endpoints))
self.textarea.setText(f"Discovered Endpoints ({len(self.endpoints)}):\n\n{output}")
def getTabCaption(self):
return "JAMBOREE Scanner"
def getUiComponent(self):
return self.panel
Traffic Analysis Workflow
Complete workflow for intercepting and analyzing app traffic:
adb shell "/data/local/tmp/frida-server &"
burpsuite --proxy-port=${BURP_PORT} &
adb shell settings put global http_proxy ${BURP_HOST}:${BURP_PORT}
objection -g com.example.targetapp explore <<EOF
android sslpinning disable
exit
EOF
adb shell am start -n com.example.targetapp/.MainActivity
Common Patterns
Pattern 1: API Endpoint Discovery and Analysis
#!/bin/bash
PACKAGE=$1
DURATION=${2:-300}
echo "[+] Starting API discovery for ${PACKAGE}"
adb shell tcpdump -i any -w /sdcard/capture.pcap &
TCPDUMP_PID=$!
objection -g ${PACKAGE} explore <<EOF
android hooking watch class_method okhttp3.OkHttpClient.newCall --dump-args --dump-return
android hooking watch class_method retrofit2.Retrofit.create --dump-args
exit
EOF &
sleep ${DURATION}
kill ${TCPDUMP_PID}
adb pull /sdcard/capture.pcap ./analysis/
tshark -r ./analysis/capture.pcap -Y "http || tls" -T fields \
-e http.request.full_uri \
-e tls.handshake.extensions_server_name | sort -u > ./analysis/endpoints.txt
echo "[+] Discovered $(wc -l < ./analysis/endpoints.txt) unique endpoints"
cat ./analysis/endpoints.txt
Pattern 2: Database Extraction and Analysis
#!/bin/bash
PACKAGE=$1
OUTPUT_DIR="./databases/${PACKAGE}"
mkdir -p ${OUTPUT_DIR}
adb shell "run-as ${PACKAGE} find /data/data/${PACKAGE} -name '*.db'" | while read DB_PATH; do
DB_NAME=$(basename ${DB_PATH})
echo "[+] Extracting ${DB_NAME}"
adb shell "run-as ${PACKAGE} cp ${DB_PATH} /sdcard/${DB_NAME}"
adb pull /sdcard/${DB_NAME} ${OUTPUT_DIR}/
sqlite3 ${OUTPUT_DIR}/${DB_NAME} ".schema" > ${OUTPUT_DIR}/${DB_NAME}.schema.sql
sqlite3 ${OUTPUT_DIR}/${DB_NAME} ".dump" > ${OUTPUT_DIR}/${DB_NAME}.dump.sql
echo "[+] ${DB_NAME}: $(sqlite3 ${OUTPUT_DIR}/${DB_NAME} 'SELECT COUNT(*) FROM sqlite_master WHERE type=\"table\"') tables"
done
Pattern 3: Automated Certificate Pinning Bypass
Create a persistent bypass module:
Java.perform(function() {
console.log('[+] Loading persistent SSL bypass');
try {
var CertificatePinner = Java.use('okhttp3.CertificatePinner');
CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function() {
console.log('[SSL] OkHttp3 pinning bypassed for: ' + arguments[0]);
};
} catch(e) {}
try {
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
var TrustManager = Java.registerClass({
name: 'com.jamboree.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('[SSL] SSLContext.init hooked');
SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
};
} catch(e) {}
try {
var SSLContext = Java.use('javax.net.ssl.SSLContext');
var TrustManager = Java.registerClass({
name: 'com.jamboree.UniversalTrust',
implements: [Java.use('javax.net.ssl.X509TrustManager')],
methods: {
checkClientTrusted: function() {},
checkServerTrusted: function() {},
getAcceptedIssuers: function() { return []; }
}
});
SSLContext.getDefault.implementation = function() {
var context = SSLContext.getInstance('TLS');
context.init(null, [TrustManager.$new()], null);
return context;
};
} catch(e) {}
console.log('[+] SSL bypass hooks installed');
});
Deploy automatically on app launch:
mkdir -p ~/.frida/scripts
cp modules/objection/scripts/persistent-ssl-bypass.js ~/.frida/scripts/
cat > ~/bin/jamboree-launch <<'EOF'
PACKAGE=$1
frida -U -l ~/.frida/scripts/persistent-ssl-bypass.js -f ${PACKAGE} --no-pause
EOF
chmod +x ~/bin/jamboree-launch
Troubleshooting
Issue: Certificate Not Trusted
Symptoms: HTTPS traffic not captured, SSL errors in app
Solution:
adb shell ls -la /system/etc/security/cacerts/ | grep -i burp
openssl x509 -inform PEM -subject_hash_old -in burp-cert.pem | head -1
adb root && adb remount
CERT_HASH=$(openssl x509 -inform PEM -subject_hash_old -in burp-cert.pem | head -1)
adb push burp-cert.pem /system/etc/security/cacerts/${CERT_HASH}.0
adb shell chmod 644 /system/etc/security/cacerts/${CERT_HASH}.0
adb reboot
Issue: Frida Connection Failed
Symptoms: Failed to spawn: unable to find process with name 'com.example.app'
Solution:
adb shell "ps -A | grep frida"
adb shell "killall frida-server"
adb shell "/data/local/tmp/frida-server &"
frida --version
adb shell "/data/local/tmp/frida-server --version"
Issue: Magisk Module Not Loading
Symptoms: Module shows as installed but features not working
Solution:
adb shell magisk --list
adb shell cat /cache/magisk.log
adb reboot recovery
adb shell magisk --remove-module conflicting-module
adb reboot
Issue: Objection Hooks Not Triggering
Symptoms: Hooks installed but no output when methods called
Solution:
Java.perform(function() {
Java.enumerateLoadedClasses({
onMatch: function(className) {
if (className.indexOf('example') !== -1) {
console.log('[+] Found: ' + className);
var clazz = Java.use(className);
var methods = clazz.class.getDeclaredMethods();
methods.forEach(function(method) {
console.log(' -> ' + method);
});
}
},
onComplete: function() {}
});
});
Issue: Emulator Detection
Symptoms: App exits or shows warning about running on emulator
Solution:
adb root && adb remount
adb shell "cat >> /system/build.prop <<EOF
ro.product.manufacturer=samsung
ro.product.model=SM-G991B
ro.product.brand=samsung
ro.build.fingerprint=samsung/o1sxxx/o1s:13/TP1A.220624.014/G991BXXU5DVLB:user/release-keys
EOF"
adb shell magisk --denylist add com.example.targetapp
adb push modules/magisk/systemless/shamiko.zip /sdcard/
adb shell magisk --install-module /sdcard/shamiko.zip
adb reboot
Environment Variables
JAMBOREE uses these environment variables:
export BURP_HOST="192.168.1.100"
export BURP_PORT="8080"
export BURP_CERT_PATH="./modules/burp/certificates/burp-ca.pem"
export ANDROID_SDK_ROOT="${HOME}/Android/Sdk"
export ANDROID_AVD_HOME="${HOME}/.android/avd"
export FRIDA_SERVER_PATH="/data/local/tmp/frida-server"
export JAMBOREE_LOG_LEVEL="DEBUG"
export JAMBOREE_LOG_PATH="./logs/jamboree.log"
Best Practices
- Always work in isolated environments - Use dedicated emulators or test devices
- Document findings - Keep detailed logs of hooks, modified traffic, and discovered vulnerabilities
- Version control configurations - Track changes to Frida scripts and Burp extensions
- Regular updates - Keep Magisk, Frida, and Objection current for compatibility
- Test incrementally - Apply one bypass at a time to identify what works
- Backup emulator snapshots - Save working configurations before major changes
Additional Resources