Android App抓包防护概述
什么是抓包防护
抓包防护是Android应用为了防止网络流量被第三方工具(如Burp Suite、Fiddler、Charles等)拦截和分析而实施的安全措施。这些防护措施旨在保护敏感数据的传输安全,防止中间人攻击和数据泄露。
Android App抓包防护架构图
主要防护机制
1. SSL/TLS证书固定(Certificate Pinning)
防护原理:应用在代码中硬编码了服务器的证书信息,只信任特定的证书,拒绝其他证书(包括用户安装的CA证书)。
SSL Pinning证书固定流程图
实现方式: 证书固定通常通过OkHttp库实现,开发者会在代码中硬编码服务器的证书哈希值。当应用发起HTTPS请求时,会验证服务器证书是否与预设的哈希值匹配,如果不匹配则拒绝连接。这种方式可以有效防止中间人攻击,但也会阻止合法的抓包工具。
// OkHttp证书固定示例OkHttpClient client = new OkHttpClient.Builder() .certificatePinner(new CertificatePinner.Builder() .add("api.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") .add("api.example.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=") .build()) .build();检测方法: 检测证书固定可以通过尝试使用自签名证书连接服务器来实现。如果应用没有实施证书固定,连接会成功;如果实施了证书固定,会抛出证书验证异常。
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}2. 证书验证绕过检测
防护原理:应用检测是否安装了用户CA证书,如果检测到则拒绝连接。
实现方式: 应用通过检查系统的信任存储来检测是否安装了用户CA证书。常见的抓包工具如Burp Suite、Charles、Fiddler等都会安装自己的CA证书,应用可以通过检查证书的颁发者信息来识别这些工具。
// 检测用户CA证书publicbooleanhasUserCACertificate(){try { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init((KeyStore) null); X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];// 检查是否有用户添加的CA证书 X509Certificate[] acceptedIssuers = defaultTrustManager.getAcceptedIssuers();for (X509Certificate cert : acceptedIssuers) { String subject = cert.getSubjectDN().getName();if (subject.contains("Burp") || subject.contains("Charles") || subject.contains("Fiddler") || subject.contains("Custom")) {returntrue; } }returnfalse; } catch (Exception e) {returnfalse; }}3. 网络环境检测
防护原理:检测设备是否连接了代理服务器,如果检测到代理则拒绝网络请求。
实现方式: 网络环境检测主要通过检查系统代理设置和网络连接信息来实现。当用户配置了代理服务器时,系统会设置相应的代理属性,应用可以通过检查这些属性来判断是否存在代理。
// 检测代理设置publicbooleanisProxyEnabled(){try {// 检查系统代理设置 String proxyHost = System.getProperty("http.proxyHost"); String proxyPort = System.getProperty("http.proxyPort");if (proxyHost != null && proxyPort != null) {returntrue; }// 检查网络连接 ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo();if (activeNetwork != null && activeNetwork.isConnected()) {// 检查是否有代理 ProxyInfo proxyInfo = activeNetwork.getProxyInfo();if (proxyInfo != null) {returntrue; } }returnfalse; } catch (Exception e) {returnfalse; }}4. 反调试检测
防护原理:检测应用是否在调试模式下运行,如果检测到调试则拒绝网络请求。
反Hook检测流程图
实现方式:
// 检测调试状态publicbooleanisDebugging(){try {// 检查调试标志boolean isDebug = (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;if (isDebug) {returntrue; }// 检查调试器连接boolean isDebuggerConnected = Debug.isDebuggerConnected();if (isDebuggerConnected) {returntrue; }// 检查调试端口try { Socket socket = new Socket("127.0.0.1", 8700); socket.close();returntrue; } catch (Exception e) {// 端口未开放,不是调试状态 }returnfalse; } catch (Exception e) {returnfalse; }}5. 应用完整性检测
防护原理:检测应用是否被修改或重打包,如果检测到则拒绝网络请求。
实现方式:
// 检测应用签名publicbooleanisAppModified(){try { PackageManager pm = getPackageManager(); PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);// 获取当前签名 Signature[] signatures = packageInfo.signatures; String currentSignature = signatures[0].toCharsString();// 与预期签名比较 String expectedSignature = "预期签名的SHA1值";if (!currentSignature.equals(expectedSignature)) {returntrue; }returnfalse; } catch (Exception e) {returntrue; }}绕过技术详解
Frida Hook原理图
1. SSL Pinning绕过
方法一:Frida Hook
Frida Hook是最常用的SSL Pinning绕过方法,通过Hook证书验证相关的函数来实现绕过。这种方法不需要修改应用代码,只需要在运行时动态Hook即可。
// Frida Hook SSL PinningJava.perform(function() {// Hook OkHttp的CertificatePinnervar CertificatePinner = Java.use("okhttp3.CertificatePinner"); CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function(hostname, peerCertificates) {console.log("绕过SSL Pinning: " + hostname);return; };// Hook X509TrustManagervar X509TrustManager = Java.use("javax.net.ssl.X509TrustManager"); X509TrustManager.checkClientTrusted.implementation = function(chain, authType) {console.log("绕过客户端证书检查"); }; X509TrustManager.checkServerTrusted.implementation = function(chain, authType) {console.log("绕过服务端证书检查"); }; X509TrustManager.getAcceptedIssuers.implementation = function() {return Java.use("java.util.ArrayList").$new(); };});方法二:Xposed模块
// Xposed模块绕过SSL PinningpublicclassSSLUnpinningimplementsIXposedHookLoadPackage{@OverridepublicvoidhandleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam)throws Throwable {// Hook OkHttp XposedHelpers.findAndHookMethod("okhttp3.CertificatePinner", lpparam.classLoader,"check", String.class, List.class, newXC_MethodReplacement() {@Overrideprotected Object replaceHookedMethod(MethodHookParam param)throws Throwable {returnnull; } });// Hook TrustManager XposedHelpers.findAndHookMethod("javax.net.ssl.X509TrustManager", lpparam.classLoader,"checkServerTrusted", X509Certificate[].class, String.class, newXC_MethodReplacement() {@Overrideprotected Object replaceHookedMethod(MethodHookParam param)throws Throwable {returnnull; } }); }}方法三:内存补丁
// 内存补丁绕过SSL Pinning#include<jni.h>#include<string.h>JNIEXPORT void JNICALL Java_com_example_SSLUnpinner_unpin(JNIEnv *env, jobject thiz){// 获取SSL_CTX_set_verify函数地址void *ssl_ctx_set_verify = dlsym(RTLD_DEFAULT, "SSL_CTX_set_verify");if (ssl_ctx_set_verify) {// 修改函数实现unsignedchar patch[] = {0x90, 0x90, 0x90, 0x90, 0x90}; // NOP指令 mprotect(ssl_ctx_set_verify, 5, PROT_READ | PROT_WRITE | PROT_EXEC);memcpy(ssl_ctx_set_verify, patch, 5); mprotect(ssl_ctx_set_verify, 5, PROT_READ | PROT_EXEC); }}2. 代理检测绕过
方法一:Hook系统属性
// Frida Hook代理检测Java.perform(function() {// Hook System.getPropertyvar System = Java.use("java.lang.System"); System.getProperty.overload("java.lang.String").implementation = function(key) {if (key === "http.proxyHost" || key === "http.proxyPort" || key === "https.proxyHost" || key === "https.proxyPort") {console.log("绕过代理检测: " + key);returnnull; }returnthis.getProperty(key); };// Hook ConnectivityManagervar ConnectivityManager = Java.use("android.net.ConnectivityManager"); ConnectivityManager.getActiveNetworkInfo.implementation = function() {var networkInfo = this.getActiveNetworkInfo();if (networkInfo) {// 清除代理信息 networkInfo.setProxyInfo(null); }return networkInfo; };});方法二:修改网络配置
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}03. 反调试绕过
方法一:Frida Hook反调试检测
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}1方法二:修改应用标志
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}24. 应用完整性绕过
方法一:Hook签名验证
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}3方法二:修改签名文件
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}4进阶内容
1. 动态Hook技术
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}52. 内存修改技术
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}63. 系统调用Hook
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}7检测与防护
1. 检测Hook工具
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}82. 反Hook技术
// 检测证书固定publicbooleanisCertificatePinningEnabled(){try {// 尝试使用自签名证书连接 URL url = new URL("https://api.example.com"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect();returnfalse; // 如果没有抛出异常,说明没有证书固定 } catch (Exception e) {returntrue; // 抛出异常说明有证书固定 }}9结语
技术对抗演进
绕过技术分类
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……




还没有评论,来说两句吧...