Skip to main content
1 min read Advanced Mobile

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 DotnetProxyTrustManager to accept server/client certificates and modifies Xamarin's FakeSSLSession certificate 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 │
└──────────────────┘