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:
- Setup: Configure proxy, install CA certificate
- Intercept: Capture traffic, verify TLS works
- Analyze: Review requests/responses for sensitive data
- Bypass: If pinning exists, bypass it
- Test: Manipulate requests, test API endpoints
- 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¶
- Traffic Interception Setup
- TLS/SSL Configuration Testing
- Certificate Pinning Bypass
- Network Security Config Analysis
- OAuth and Token Handling
- 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
Related Reading¶
- Network Security Config - Detailed config analysis
- Android Basics - Network Testing - Network security fundamentals
- Networking Basics - Network fundamentals
- Cryptography - TLS and certificate concepts
- Instrumentation - Advanced Frida techniques for network testing
This guide covers essential network security testing techniques. Combine with Component Testing and Dynamic Analysis for comprehensive assessments.