Skip to content

Android Network Security Testing - Watching Apps Talk

Overview - Intercepting What Apps Say

Every Android app talks to the internet. Some more than others, but they all do it eventually. The question is: are they talking securely? Are they using TLS? Is certificate pinning implemented correctly? Can we intercept and manipulate their communications? That's what network security testing answers.

The Reality:

Network testing reveals: - Cleartext Traffic: HTTP instead of HTTPS (still happens, unfortunately) - Weak TLS Configuration: Old TLS versions, weak cipher suites - Certificate Pinning Bypasses: SSL pinning that can be circumvented - Authentication Issues: Tokens in headers, weak session management - Sensitive Data in Transit: Personal info, credentials, API keys in traffic - API Security: Insecure endpoints, missing validation, rate limiting

What We're Testing:

  • TLS/SSL Configuration: Is encryption actually working?
  • Certificate Validation: Can we use a custom CA? Is pinning present?
  • Traffic Interception: Can we see what the app is sending/receiving?
  • Authentication Mechanisms: How does the app authenticate? Where are tokens stored?
  • API Security: Are endpoints properly secured? Is data validated?

The Tools We'll Use:

  • Burp Suite: Industry standard proxy for interception
  • mitmproxy: command line alternative (powerful and scriptable)
  • Frida: For bypassing SSL pinning
  • Objection: Quick SSL pinning bypass
  • ADB: For device configuration

The Testing Flow:

  1. Setup: Configure proxy, install CA certificate
  2. Intercept: Capture traffic, verify TLS works
  3. Analyze: Review requests/responses for sensitive data
  4. Bypass: If pinning exists, bypass it
  5. Test: Manipulate requests, test API endpoints
  6. Document: Note findings, sensitive endpoints, authentication flows

Prerequisites: Understanding of Android Basics, Networking Basics, and Cryptography concepts. You need to understand TLS, certificates, and how HTTP/HTTPS works. Without this, you'll be guessing blindly.

Table of Contents

  1. Traffic Interception Setup
  2. TLS/SSL Configuration Testing
  3. Certificate Pinning Bypass
  4. Network Security Config Analysis
  5. OAuth and Token Handling
  6. Cleartext Traffic Testing

Traffic Interception Setup

Proxy Configuration

Set System Proxy via ADB:

# Set HTTP proxy
adb shell settings put global http_proxy 192.168.1.100:8080

# Verify proxy setting
adb shell settings get global http_proxy

# Clear proxy
adb shell settings put global http_proxy :0

Wi-Fi Proxy Setup (Requires Root):

# Method 1: Via settings API
adb shell "su -c 'settings put global http_proxy 192.168.1.100:8080'"

# Method 2: Modify Wi-Fi properties
adb shell "su -c 'sqlite3 /data/data/com.android.providers.settings/databases/settings.db \"INSERT OR REPLACE INTO global VALUES(99, \\\"http_proxy\\\", \\\"192.168.1.100:8080\\\")\"'"

Certificate Installation

Install Burp/mitmproxy CA Certificate:

# Push certificate to device
adb push burp-cert-der.crt /sdcard/

# Convert to PEM if needed
openssl x509 -inform DER -in burp-cert-der.crt -out burp-cert.pem

# Get certificate hash for filename (Android 7.0+)
HASH=$(openssl x509 -inform PEM -subject_hash_old -in burp-cert.pem | head -1)

# Copy to system certificates (requires root)
adb shell "su -c 'cp /sdcard/burp-cert.pem /system/etc/security/cacerts/$HASH.0'"
adb shell "su -c 'chmod 644 /system/etc/security/cacerts/$HASH.0'"
adb shell "su -c 'chown root:root /system/etc/security/cacerts/$HASH.0'"

# For user certificates (Android 7.0+, no root needed)
adb push burp-cert.pem /sdcard/
# Then install via: Settings > Security > Install from storage

Verify Certificate Installation:

adb shell "ls /system/etc/security/cacerts/ | grep -i burp"
adb shell "ls /data/misc/user/0/cacerts-added/ | grep -i burp"

Tools Setup

Burp Suite Configuration: 1. Burp Proxy listening on 0.0.0.0:8080 2. Proxy options: Support invisible proxying 3. CA certificate export: Proxy → Options → Import/Export CA Certificate

mitmproxy Configuration:

# Start mitmproxy
mitmproxy -p 8080

# Get certificate
# Certificate stored in ~/.mitmproxy/mitmproxy-ca-cert.pem


TLS/SSL Configuration Testing

Network Security Config Analysis

Locate Network Security Config:

# From decompiled APK
find out/ -name "network_security_config.xml"

# From resources
grep -r "networkSecurityConfig" out/AndroidManifest.xml

Analyze Network Security Config:

<!-- Example network_security_config.xml -->
<network-security-config>
    <!-- Base configuration -->
    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="system"/>
            <certificates src="user"/>
        </trust-anchors>
    </base-config>

    <!-- Domain-specific configuration -->
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">api.target.com</domain>
        <pin-set expiration="2027-01-01">
            <pin digest="SHA-256">base64_encoded_hash==</pin>
        </pin-set>
    </domain-config>

    <!-- Debug overrides (security issue if in release) -->
    <debug-overrides>
        <trust-anchors>
            <certificates src="user"/>
        </trust-anchors>
    </debug-overrides>
</network-security-config>

Checklist for Network Security Config: - ✅ Cleartext traffic disabled globally (cleartextTrafficPermitted="false") - ✅ No debug-overrides in release builds - ✅ Certificate pinning properly configured - ✅ Trust anchors limited to system/user (no custom CAs) - ✅ No wildcard domains in pin-sets

Related reading: See Cryptography - TLS for TLS fundamentals.


Certificate Pinning Bypass

Objection Quick Bypass

# Start Objection
objection -g com.target.app explore

# Disable SSL pinning
android sslpinning disable

# Test other bypasses
android root disable
android root simulate

Frida SSL Pinning Bypass Scripts

Universal Trust Manager Bypass:

Java.perform(function() {
    var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
    var SSLContext = Java.use('javax.net.ssl.SSLContext');

    var TrustAll = Java.registerClass({
        name: 'com.bypass.TrustAll',
        implements: [X509TrustManager],
        methods: {
            checkClientTrusted: function(chain, authType) {},
            checkServerTrusted: function(chain, authType) {},
            getAcceptedIssuers: function() {
                return [];
            }
        }
    });

    var trustAll = TrustAll.$new();
    var TrustAllCerts = Java.use('java.util.Arrays').asList([trustAll]);

    var SSLContextClass = Java.use('javax.net.ssl.SSLContext');
    var ctx = SSLContextClass.getInstance('TLS');
    ctx.init(null, TrustAllCerts, null);
    SSLContext.setDefault(ctx);

    console.log('[+] SSL Pinning bypassed via TrustManager');
});

OkHttp CertificatePinner Bypass:

Java.perform(function() {
    try {
        var CertificatePinner = Java.use('okhttp3.CertificatePinner');
        CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function(hostname, peerCertificates) {
            console.log('[+] Bypassing CertificatePinner for: ' + hostname);
            return;
        };
    } catch(e) {
        console.log('[-] OkHttp CertificatePinner not found');
    }
});

X509TrustManager Hook:

Java.perform(function() {
    var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
    var SSLContext = Java.use('javax.net.ssl.SSLContext');

    X509TrustManager.checkServerTrusted.implementation = function(chain, authType) {
        console.log('[+] Bypassing checkServerTrusted');
        return;
    };

    X509TrustManager.checkClientTrusted.implementation = function(chain, authType) {
        console.log('[+] Bypassing checkClientTrusted');
        return;
    };
});

Using Frida Scripts

# Attach to running app
frida -U -f com.target.app -l ssl-bypass.js --no-pause

# Or spawn and attach
frida -U com.target.app -l ssl-bypass.js

Cleartext Traffic Testing

Checking for Cleartext Allowed

From Manifest:

grep -i "usesCleartextTraffic" out/AndroidManifest.xml
# usesCleartextTraffic="true" indicates vulnerability

From Network Security Config:

grep -i "cleartextTrafficPermitted" out/res/xml/network_security_config.xml

Runtime Check:

# Monitor network traffic for HTTP (non-HTTPS)
adb logcat | grep -i "http://"

Testing Cleartext Endpoints

#!/usr/bin/env python3
import requests

# Test if app allows cleartext HTTP
urls = [
    'http://api.target.com/endpoint',
    'http://192.168.1.100/api',
]

for url in urls:
    try:
        response = requests.get(url, timeout=5)
        print(f"Cleartext allowed: {url} - Status: {response.status_code}")
    except Exception as e:
        print(f"Cleartext blocked or error: {url} - {e}")

OAuth and Token Handling

Token Storage Analysis

Check SharedPreferences:

adb shell run-as com.target.app \
  cat /data/data/com.target.app/shared_prefs/*.xml | \
  grep -iE "token|auth|bearer|oauth"

Check Databases:

adb shell run-as com.target.app \
  sqlite3 /data/data/com.target.app/databases/auth.db \
  "SELECT * FROM tokens;"

Monitor Logcat for Tokens:

adb logcat | grep -iE "token|bearer|authorization|oauth"

OAuth Flow Testing

Intercept Authorization Requests:

# Monitor network for OAuth endpoints
# Look for:
# - authorization_code
# - access_token
# - refresh_token
# - PKCE parameters

Token Replay Testing:

#!/usr/bin/env python3
import requests

# Extract token from app storage
token = "extracted_token_here"

# Test token validity
headers = {
    'Authorization': f'Bearer {token}',
    'Content-Type': 'application/json'
}

response = requests.get('https://api.target.com/protected', headers=headers)
print(f"Token valid: {response.status_code == 200}")

Related reading: See Storage Testing for comprehensive token extraction techniques.


Network Testing Checklist

  • Proxy successfully configured and certificate installed
  • TLS traffic intercepted and decrypted
  • Certificate pinning identified and bypassed
  • Network Security Config analyzed for misconfigurations
  • Cleartext traffic checks performed
  • OAuth flows analyzed and tokens extracted
  • API endpoints enumerated and tested
  • Authentication mechanisms tested
  • Sensitive data in transit identified


This guide covers essential network security testing techniques. Combine with Component Testing and Dynamic Analysis for comprehensive assessments.