---
name: rt-mobile-ssl-pinning
description: "Comprehensive SSL/TLS pinning bypass for every framework — OkHttp3, TrustKit, Volley, Flutter, React Native, Xamarin, Cordova, native Android (Conscrypt), iOS SecTrustEvaluate, HPKP. Also covers network_security_config.xml bypass, ATS bypass, HTTP/2 and gRPC interception on mobile. Essential skill — almost every modern app has pinning. Docker: rtexit/kali:v3.1."
---

> 🐳 **Docker Environment (Recommended):** `docker exec -it rtexit-kali bash`

# rt-mobile-ssl-pinning — Bypass Every Pinning Implementation

## Overview

Modern mobile apps implement SSL pinning to prevent traffic interception. Every framework implements it differently — there's no single bypass. This skill covers every implementation you'll encounter in real engagements.

**Goal:** Get Burp Suite intercepting HTTPS traffic from any mobile app.

---

## Step 0: Burp Setup for Mobile

```bash
# Kali Docker — start Burp proxy
docker exec rtexit-kali bash -c "
# Start Burp on all interfaces
java -jar /opt/BurpSuitePro/burpsuite_pro.jar &
# Or headless:
java -Djava.awt.headless=true -jar burpsuite_pro.jar --project-file=mobile.burp &
"

# Configure Burp:
# Proxy → Options → Add listener: 0.0.0.0:8080
# Export Burp CA cert: http://burp → CA Certificate → DER format

# Android: Push Burp cert + trust it
docker exec rtexit-kali bash -c "
# Android 7+ requires cert in system store (not user store)
adb push burp-cacert.der /sdcard/burp.der

# Install in system store (requires root)
adb shell 'su -c \"cp /sdcard/burp.der /system/etc/security/cacerts/9a5ba575.0\"'
adb shell 'su -c \"chmod 644 /system/etc/security/cacerts/9a5ba575.0\"'
adb reboot
"
```

---

## Layer 1: network_security_config.xml Bypass (Android)

```bash
# Many apps restrict cleartext and pin via network_security_config.xml
# Patch it directly in the APK

docker exec rtexit-kali bash -c "
# Decompile
apktool d target.apk -o target_dc

# Edit res/xml/network_security_config.xml (or create it)
cat > target_dc/res/xml/network_security_config.xml << 'EOF'
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<network-security-config>
  <base-config cleartextTrafficPermitted=\"true\">
    <trust-anchors>
      <certificates src=\"system\" />
      <certificates src=\"user\" />
    </trust-anchors>
  </base-config>
  <debug-overrides>
    <trust-anchors>
      <certificates src=\"system\" />
      <certificates src=\"user\" />
    </trust-anchors>
  </debug-overrides>
</network-security-config>
EOF

# Make AndroidManifest.xml reference it (if not already)
# android:networkSecurityConfig=\"@xml/network_security_config\"

# Repackage + sign
apktool b target_dc -o target_patched.apk
uber-apk-signer -a target_patched.apk --out ./signed/
adb install signed/target_patched-aligned-debugSigned.apk
"
```

---

## Layer 2: Objection — Quick Bypass (OkHttp, Volley, standard Java)

```bash
docker exec rtexit-kali bash -c "
# Launch app with SSL pinning disabled
objection -g com.target.app explore --startup-command 'android sslpinning disable'

# Or attach to running app
objection -g com.target.app explore
# Then in objection shell:
# android sslpinning disable
# ios sslpinning disable
"
```

---

## Layer 3: Manual Frida — OkHttp3 / Retrofit

```javascript
// okhttp3-bypass.js — most common Android networking library

Java.perform(() => {
  // Method 1: CertificatePinner
  ['check', 'check$okhttp'].forEach(method => {
    try {
      const CP = Java.use('okhttp3.CertificatePinner');
      CP[method].overload('java.lang.String', 'java.util.List').implementation = function() {
        console.log('[*] OkHttp3 CertificatePinner.' + method + ' bypassed');
      };
    } catch(e) {}
  });

  // Method 2: OkHttpClient.Builder pinning
  try {
    const Builder = Java.use('okhttp3.OkHttpClient$Builder');
    Builder.certificatePinner.implementation = function(pinner) {
      console.log('[*] OkHttpClient.Builder.certificatePinner bypassed');
      return this;
    };
  } catch(e) {}

  // Method 3: ConnectionSpec
  try {
    const ConnectionSpec = Java.use('okhttp3.ConnectionSpec');
    const CLEARTEXT = ConnectionSpec.CLEARTEXT.value;
    const Builder = Java.use('okhttp3.OkHttpClient$Builder');
    Builder.connectionSpecs.implementation = function(specs) {
      const ArrayList = Java.use('java.util.ArrayList');
      const newSpecs = ArrayList.$new();
      newSpecs.add(CLEARTEXT);
      return this.connectionSpecs(newSpecs);
    };
  } catch(e) {}
});
```

---

## Layer 4: TrustKit (iOS + Android)

```javascript
// trustkit-bypass.js

Java.perform(() => {
  // Android TrustKit
  try {
    const TrustKit = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier');
    TrustKit.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function() {
      return true;
    };
  } catch(e) {}

  try {
    const PinningTrustManager = Java.use('com.datatheorem.android.trustkit.pinning.PinningTrustManager');
    PinningTrustManager.checkServerTrusted.implementation = function() {
      console.log('[*] TrustKit PinningTrustManager bypassed');
    };
  } catch(e) {}
});
```

---

## Layer 5: Flutter SSL Pinning Bypass

```bash
# Flutter uses BoringSSL (native, not Java) — Java hooks don't work
# Must hook at native level

docker exec rtexit-kali bash -c "
# Find libflutter.so offset for ssl_crypto_x509_session_verify_cert_chain
adb pull /data/app/com.target.app-*/lib/arm64/libflutter.so /tmp/
# Use strings + grep to find ssl function offsets
strings /tmp/libflutter.so | grep -i 'ssl\|verify\|cert'
"
```

```javascript
// flutter-ssl-bypass.js — native hook on libflutter.so

setTimeout(() => {
  const flutterLib = Process.getModuleByName('libflutter.so');
  
  // Hook ssl_crypto_x509_session_verify_cert_chain
  // Offset varies per Flutter version — find with:
  // strings libflutter.so | grep ssl_crypto_x509
  // or: objdump -d libflutter.so | grep ssl_crypto
  
  const offset = 0x123456; // Replace with actual offset from analysis
  const sslVerify = flutterLib.base.add(offset);
  
  Interceptor.replace(sslVerify, new NativeCallback(() => {
    console.log('[*] Flutter ssl_verify bypassed');
    return 1; // SSL_VERIFY_OK
  }, 'int', []));
}, 1000);
```

```bash
# Alternative: use reFlutter (patches libflutter.so directly)
docker exec rtexit-kali bash -c "
pip3 install reFlutter
reFlutter target.apk
# Produces patched APK with SSL pinning removed from Flutter engine
adb install release.RE.apk
"
```

---

## Layer 6: React Native SSL Pinning Bypass

```javascript
// react-native-bypass.js

Java.perform(() => {
  // React Native uses OkHttp under the hood on Android
  // Also may use react-native-ssl-pinning library
  try {
    const OkHttpClientProvider = Java.use('com.facebook.react.modules.network.OkHttpClientProvider');
    OkHttpClientProvider.createClientBuilder.implementation = function() {
      const builder = this.createClientBuilder();
      // Remove certificate pinner
      const CP = Java.use('okhttp3.CertificatePinner$Builder');
      builder.certificatePinner(CP.$new().build());
      return builder;
    };
  } catch(e) {}
  
  // react-native-ssl-pinning bypass
  try {
    const RNSslPinning = Java.use('com.toyberman.RNSslPinningModule');
    RNSslPinning.getCertSha256.implementation = function() { return null; };
  } catch(e) {}
});
```

---

## Layer 7: Xamarin SSL Bypass

```javascript
// xamarin-bypass.js

Java.perform(() => {
  // Xamarin uses mono runtime
  try {
    const ServicePointManager = Java.use('java.lang.Class').forName('System.Net.ServicePointManager');
    // Hook via Mono reflection
  } catch(e) {}

  // Alternative: hook native SSL
  const ssl_verify = Module.findExportByName('libmono.so', 'mono_security_x509_chain_verify');
  if (ssl_verify) {
    Interceptor.replace(ssl_verify, new NativeCallback(() => {
      console.log('[*] Xamarin SSL verify bypassed');
      return 1;
    }, 'int', []));
  }
});
```

---

## Layer 8: iOS Pinning Bypass

```javascript
// ios-ssl-bypass.js — covers SecTrustEvaluate, NSURLSession, AFNetworking

// SecTrustEvaluate — system-level bypass
Interceptor.replace(Module.findExportByName('Security', 'SecTrustEvaluate'), 
  new NativeCallback((trust, result) => {
    const ptr = Memory.alloc(4);
    ptr.writeS32(1); // kSecTrustResultProceed
    result.writePointer(ptr);
    console.log('[*] SecTrustEvaluate bypassed');
    return 0;
  }, 'int', ['pointer', 'pointer'])
);

// SecTrustEvaluateWithError (iOS 13+)
Interceptor.replace(Module.findExportByName('Security', 'SecTrustEvaluateWithError'),
  new NativeCallback((trust, error) => {
    if (!error.isNull()) error.writePointer(ptr(0));
    console.log('[*] SecTrustEvaluateWithError bypassed');
    return 1; // true = trusted
  }, 'bool', ['pointer', 'pointer'])
);

// AFNetworking (common iOS library)
try {
  const AFSec = ObjC.classes.AFSecurityPolicy;
  Interceptor.attach(AFSec['- evaluateServerTrust:forDomain:'].implementation, {
    onLeave: function(retval) {
      retval.replace(ptr(1));
      console.log('[*] AFNetworking evaluateServerTrust bypassed');
    }
  });
} catch(e) {}
```

---

## Proxy Setup Per App (Programmatic)

```bash
# Set proxy via ADB for specific WiFi network
docker exec rtexit-kali bash -c "
# Set system-wide proxy (requires root or developer mode)
adb shell settings put global http_proxy 192.168.200.10:8080

# Clear after testing
adb shell settings put global http_proxy :0
"
```

---

## Related Skills
- `rt-frida-advanced` — write custom bypass scripts
- `rt-exploit-android` — full Android methodology
- `rt-exploit-ios` — full iOS methodology
- `rt-cross-platform-mobile` — Flutter/React Native specifics
- `rt-apk-repackaging` — patch APK when dynamic bypass fails

## References
- https://github.com/httptoolkit/frida-android-unpinning (community bypass collection)
- https://github.com/nccgroup/PinKit
- https://codeshare.frida.re/@pcipolloni/universal-android-ssl-pinning-bypass-with-frida/
- https://attack.mitre.org/techniques/T1553/ — Subvert Trust Controls
