Why detect root/jailbreak?
- Stop unauthorised entry to app knowledge.
- Mitigate tampering with app logic.
- Adjust to safety requirements (e.g., banking apps).
Root detection in Android
Root detection in Android may be applied utilizing varied checks:
Pattern implementation (Android)
override enjoyable isDeviceRooted(): Boolean checkForRWPaths()
non-public enjoyable checkForSuBinary(): Boolean {
val paths = arrayOf(
"/system/app/Superuser.apk",
"/sbin/su",
"/system/bin/su",
"/system/xbin/su",
"/knowledge/native/xbin/su",
"/knowledge/native/bin/su",
"/system/sd/xbin/su",
"/system/bin/failsafe/su",
"/knowledge/native/su",
"/su/bin"
)non-public enjoyable checkForRootPackages(): Boolean {
val packages = arrayOf(
"com.noshufou.android.su",
"com.thirdparty.superuser",
"eu.chainfire.supersu",
"com.koushikdutta.superuser",
"com.zachspong.temprootremovejb",
"com.ramdroid.appquarantine"
)
return packages.any { packageName ->
attempt {
val pm = context.packageManager
pm.getPackageInfo(packageName, 0)
true
} catch (e: Exception) {
false
}
}
}
}
Jailbreak detection in iOS
iOS jailbreak detection may be carried out utilizing:
- Checking for the existence of Cydia or different jailbreak apps like Sileo or Zebra.
- Checking for writable entry to system directories, akin to /non-public.
- Trying to execute shell instructions, that are usually restricted.
Pattern implementation (iOS) [Platform.ios.kt]
override val jailbreakDetectionResult: JailbreakDetectionResult
get() = checkJailbreak()non-public enjoyable checkJailbreak(): JailbreakDetectionResult {
val jailbreakPaths = mapOf(
"/Functions/Cydia.app" to "Cydia app detected",
"/Library/MobileSubstrate/MobileSubstrate.dylib" to "MobileSubstrate detected",
"/bin/bash" to "Bash shell detected",
"/usr/sbin/sshd" to "SSH daemon detected",
"/and so on/apt" to "APT bundle supervisor detected"
)
}
2. SSL pinning
SSL pinning prevents man-in-the-middle (MITM) assaults by making certain that solely trusted certificates are accepted, even when an attacker has put in a customized certificates authority (CA) on the machine.
SSL pinning in Android
Android makes use of OkHttpClient with a customized certificates pinning configuration.
Certificates pinning logic
val certificatePinner = CertificatePinner.Builder()
.add(hostname, “sha256/47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=”) // Unique pin
.add(hostname, “sha256/Cl7dc6nofBuxRWuGgnZc9Fi/VYDPg608JSN91g/wQXA=”)
// Your pin
.add(hostname, “sha256/wMSCtagZr+ada2dTKz2S7x2fU6YgXGn/a9pBqyEHu7U=”) // Burp Pin
.construct()
- CertificatePinner: Specifies the legitimate certificates fingerprints for the server hostname. If the server certificates doesn’t match these fingerprints, the connection will fail.
- Hostname: jsonplaceholder.typicode.com.
- Pins: The SHA-256 hashes of legitimate server certificates.
Making the API request
val shopper = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.construct()
val request = Request.Builder()
.url(“https://$hostname/customers“)
.construct()
val response = shopper.newCall(request).execute()
-
OkHttpClient: Configured with the certificates pinning logic.
-
Request: A easy HTTP GET request to fetch consumer knowledge.
-
Response: Captures the response physique as a string.
SSL pinning in iOS
In iOS, SSL pinning is often applied utilizing a customized URLSessionDelegate that intercepts and validates server belief throughout community requests.
Beneath is a real-world implementation that mixes SSL pinning with proxy detection. This ensures the app not solely trusts particular certificates but in addition terminates execution if a community proxy is detected (a typical technique utilized by attackers to intercept visitors).
Pattern implementation (iOS)
static let shared = BlockProxyAndSSLPinning()
non-public let pinnedKey = "sha256/47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" // jsonplaceholder.typicode.com
static func setup() {
// 1. Test for proxy instantly
if hasProxy() {
fatalError("Proxy detected! Disable proxy to make use of the app.")
}
// 2. Configure SSL pinning for all requests
URLProtocol.registerClass(BlockAllRequestsProtocol.self)
}
static func hasProxy() -> Bool {
guard let settings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as? [String: Any] else {
return false
}
return !(settings["HTTPProxy"] as? String ?? "").isEmpty
}
// SSL Pinning Validation
func validate(problem: URLAuthenticationChallenge) -> Bool {
guard let belief = problem.protectionSpace.serverTrust else { return false }// Confirm certificates
var error: CFError?
guard SecTrustEvaluateWithError(belief, &error) else { return false }
// Get server's public key
guard let serverKey = SecTrustCopyKey(belief),
let keyData = SecKeyCopyExternalRepresentation(serverKey, nil) else {
return false
}
// Calculate SHA256
let knowledge = keyData as Knowledge
var hash = [UInt8](repeating: 0, depend: Int(CC_SHA256_DIGEST_LENGTH))
knowledge.withUnsafeBytes { _ = CC_SHA256($0.baseAddress, CC_LONG(knowledge.depend), &hash) }
let serverKeyHash = "sha256/" + Knowledge(hash).base64EncodedString()return serverKeyHash == pinnedKey
}
}
SSL pinning logic
-
Makes use of SecTrustEvaluateWithError() to confirm the server’s certificates.
-
Extracts the general public key from the certificates and hashes it utilizing SHA256.
-
Compares the ensuing hash with a predefined pinned worth (pinnedKey).
SSL pinning ensures your app solely trusts particular certificates, decreasing MITM danger.
Android SSL pinning instance (OkHttp3)
val certificatePinner = CertificatePinner.Builder()
.add(hostname, "sha256/47DEQpj8HBSa+/TIm...")
.construct()
iOS SSL pinning with proxy detection
func validate(problem: URLAuthenticationChallenge) -> Bool { // confirm SSL certs & examine SHA256 hash }
Part 2: Bypass methods
Root/Jailbreak detection bypass methods
1. Bypassing root/jailbreak detection with Frida
Frida is a strong dynamic instrumentation instrument that permits attackers to hook into working purposes and modify their behaviour at runtime.
Steps to bypass root detection utilizing Frida
1. Begin the Frida server on the machine
adb push frida-server /knowledge/native/tmp/
adb shell chmod 755 /knowledge/native/tmp/frida-server
adb shell ./knowledge/native/tmp/frida-server &
2. Connect Frida to the goal utility
frida -U -n com.instance.kmm_test -e "console.log('Frida connected');"
3. Run a Frida script to override root detection features
Java.carry out(operate() {
var rootCheck = Java.use("com.instance.kmm_test.RootDetector");
rootCheck.isDeviceRooted.implementation = operate() {
console.log("Bypassing root detection");
return false;
};
});
2. Bypassing root/jailbreak detection with Objection
Objection is a runtime cell exploitation framework constructed on Frida, permitting safety researchers to bypass safety mechanisms simply.
Steps to bypass root/jailbreak detection utilizing Objection
1. Connect Objection to the app
objection -g com.instance.kmm_test discover
2. Disable root detection
android root disable
Efficiently bypassed ✅
3. Disable jailbreak detection
ios jailbreak disable
Efficiently bypassed ✅
Bypassing root/jailbreak detection at a look
Instrument |
Platform |
Technique |
Final result |
Frida |
Android/iOS |
Hook root/jailbreak checks |
Rooted machine seems “protected” |
Objection |
Each |
Disable detection at runtime |
Bypasses checks immediately |
SSL pinning bypass methods
SSL pinning ensures that solely particular certificates are trusted by the appliance, stopping Man-in-the-Center (MITM) assaults. Attackers usually attempt to bypass SSL pinning to intercept and modify API requests.
1. Bypassing SSL pinning with Frida
If you attempt the objection instrument to bypass SSL pinning, you’ll get error messages and won’t be able to bypass.
Not capable of bypass utilizing Objection ❌
Now we use a Frida script to bypass SSL pinning and goal a specific OkHttp3 operate and alter the return worth.
Steps to bypass SSL pinning
1. Begin the Frida server
adb shell ./knowledge/native/tmp/frida-server &
2. Use an SSL pinning bypass script
frida -U -f org.instance.challenge -e "
Java.carry out(operate () {
attempt {
var CertificatePinner = Java.use('okhttp3.CertificatePinner');// Hook the overloaded technique: verify$okhttp(String, Function0)
CertificatePinner.verify$okhttp.overload('java.lang.String', 'kotlin.jvm.features.Function0').implementation = operate (host, certChainCleaner) {
console.log('[+] Bypassing OkHTTPv3 CertificatePinner verify$okhttp');
console.log(' Host: ' + host);
// You'll be able to return with out throwing any exceptions to bypass the verify
return;
};console.log('[*] OkHTTPv3 pinning bypass hooked efficiently');
} catch (err) {
console.log('[!] Exception: ' + err.message);
}
}); "
This Frida script is designed to bypass SSL pinning in Android purposes that use OkHttp3. Particularly, it targets the CertificatePinner class and hooks the verify$okhttp technique, which is liable for validating the server’s SSL certificates towards a predefined pin.
By overriding this technique’s implementation, the script ensures that no exceptions are thrown throughout certificates validation, successfully disabling the pinning mechanism. This enables visitors interception instruments like Burp Suite to examine HTTPS visitors with out being blocked by certificates mismatches. Using Frida allows this modification dynamically at runtime with out the necessity to recompile the APK.
Efficiently bypassed SSL pinning ✅
2. Bypassing SSL pinning with Objection for iOS
Steps to bypass SSL pinning
1. Connect Objection to the app
objection -g com.instance.kmm_test discover
2. Disable SSL pinning in iOS
ios sslpinning disable
Efficiently bypassed iOS SSL pinning ✅
Bypassing SSL pinning at a look
Instrument |
Platform |
Technique |
Final result |
Frida |
Android |
Hook CertificatePinner |
Disables SSL checks |
Objection |
iOS |
Command: ios sslpinning disable |
SSL pinning bypassed |
Fast comparability: Implementation vs. bypass
Mechanism |
Implementation technique |
Widespread bypass instruments |
Mitigation |
Root/Jailbreak detection |
System checks (binaries, directories, packages) |
Frida, Objection |
Obfuscation, RASP |
SSL pinning |
Certificates hash verification |
Frida, Objection |
Dynamic pinning, Cert transparency logs |
Greatest practices: Staying forward of attackers
✅ Mix root/jailbreak detection + SSL pinning for layered protection
✅ Frequently replace detection logic towards new bypass scripts
✅ Use runtime utility self-protection (RASP) for stronger enforcement
✅ At all times conduct penetration testing earlier than app releases
Conclusion
KMM streamlines cross-platform cell growth, however sturdy safety relies on platform-specific implementations. Root detection and SSL pinning are important instruments in your defence arsenal, however they have to be applied rigorously and constantly up to date.
Whereas no system is foolproof, layering safety features and understanding how attackers bypass them places you a step forward.
🚧 “Defence isn’t simply constructing partitions, it’s figuring out the place attackers climb them.”
Keep safe and at all times take a look at your apps like an attacker would!
💡Remaining tip: At all times conduct penetration testing to determine vulnerabilities earlier than attackers do!
Incessantly requested questions (FAQs)
1. Is SSL pinning foolproof?
No. Attackers can nonetheless bypass with Frida or Objection. That’s why layered safety and steady testing are important.
2. Do all apps want jailbreak/root detection?
Not all apps want jailbreak/root detection, however apps dealing with delicate knowledge (banking, fintech, healthcare) ought to implement it.
3. What’s one of the simplest ways to check my implementation?
Use instruments like Frida and Objection your self throughout penetration testing to validate defenses and take a look at your implementation.