Overview
Xamarin Mobile Pentesting
Xamarin is a Microsoft framework used to build Android and iOS apps mainly with C#/.NET, while still interacting with native Android components. During mobile pentesting, this matters because the app's networking and certificate validation may not behave exactly like a typical Java/Kotlin Android application. Xamarin apps can contain .NET networking components alongside Android Java classes, so identifying the framework and the actual TLS/certificate-validation path is an important first step when troubleshooting HTTPS interception.
Below given Frida script targets Xamarin/.NET certificate-validation components. It hooks
DotnetProxyTrustManagerto accept server/client certificates and modifies Xamarin'sFakeSSLSessioncertificate handling. The goal is to bypass certificate validation that can prevent HTTPS traffic from being intercepted through tools such as ProxyDroid + Burp Suite. It is not a universal SSL-pinning bypass. it works only when those specific Xamarin classes are part of the application's certificate-validation flow.
Basic Setup
# Check Android device architecture
adb shell getprop ro.product.cpu.abi
# List all installed packages
adb shell pm list packages
# Search installed packages by name (PowerShell)
adb shell pm list packages | Select-String "camera"
# Start Frida Server on the Android device
/data/local/tmp/frida-server-x86_64 > /dev/null 2>&1 &
# Verify Frida can communicate with the device
frida-ps -U
# Start Frida Server (when running it from the current directory)
./frida-server &
# Spawn the target application and load the Xamarin SSL bypass script
frida -U -l XamarinBypass.js -f com.mobile.package
Background
Android App
│
▼
Xamarin/.NET networking
│
▼
TLS connection
│
▼
Certificate validation
│
├── DotnetProxyTrustManager
│ └── checkServerTrusted() → ACCEPT
│
└── FakeSSLSession
└── getPeerCertificates() → []
SSL Xamarin/.NET SSL Pinning bypass :
Use proxydroid or Playstore if not work directly
Java.perform(function() {
console.log("[*] ================================================");
console.log("[*] BYPASS FOR PROXYDROID");
console.log("[*] ================================================\n");
// Bypass .NET TrustManager
try {
var DotnetProxyTrustManager = Java.use("net.dot.android.crypto.DotnetProxyTrustManager");
DotnetProxyTrustManager.checkServerTrusted.implementation = function(certs, authType) {
console.log("[✓] Server cert accepted");
};
DotnetProxyTrustManager.checkClientTrusted.implementation = function(certs, authType) {
console.log("[✓] Client cert accepted");
};
console.log("[✓] .NET TrustManager bypassed");
} catch(e) {}
// Bypass Xamarin Fake SSL Session
try {
var FakeSSLSession = Java.use("xamarin.android.net.ServerCertificateCustomValidator_TrustManager_FakeSSLSession");
FakeSSLSession.getPeerCertificates.implementation = function() {
return [];
};
console.log("[✓] Fake SSL session bypassed");
} catch(e) {}
console.log("[✓] READY - Login in the app now\n");
});
Archicture of the commnucation:
Outbound request:
Xamarin App → ProxyDroid → Burp Suite → Application Server
Inbound response:
Application Server → Burp Suite → ProxyDroid → Xamarin App
┌─────────────────────────┐
│ Pentester PC │
│ │
│ ┌─────────┐ ┌───────┐ │
│ │ Frida │ │ Burp │ │
│ │ CLI │ │ Suite │ │
│ └────┬────┘ └───┬───┘ │
└───────┼──────────┼──────┘
│ │
ADB / Frida │ │
│ │
▼ │
┌─────────────────────────────┐
│ Android Device │
│ │
│ ┌───────────────────────┐ │
│ │ Xamarin App │ │
│ │ │ │
│ │ C# / .NET Networking │ │
│ │ TLS Validation │ │
│ └───────────┬───────────┘ │
│ │ │
│ │ HTTPS │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ ProxyDroid │ │
│ │ Proxy Routing │ │
│ └───────────┬───────────┘ │
└──────────────┼──────────────┘
│
┌─────────────┴─────────────┐
│ │
Request │ │ Response
▼ ▲
┌────────────────────────────────────┐
│ Burp Suite │
│ │
│ Proxy / Intercept │
│ HTTP(S) Inspection │
└───────────────┬────────────────────┘
│
Request │ Response
▼
┌──────────────────┐
│ Application API │
│ / Server │
└──────────────────┘