大数跨境
0
0

Android App抓包防护与绕过技术

Android App抓包防护与绕过技术 哆啦安全
2025-10-31
2
导读:分析Android App的抓包防护机制,从SSL Pinning到证书固定,从网络检测到反调试,全面解析防护原理并提供相应的绕过技术

在前面的文章中,探讨了SSL/TLS协议解析、SSL Pinning绕过技术、Frida Hook、Xposed Hook以及ADB命令等移动安全技术。本篇内容将基于这些技术基础,来分析Android App的抓包防护机制,从SSL Pinning到证书固定,从网络检测到反调试,全面解析防护原理并提供相应的绕过技术,干货拉满了。。

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();

检测方法: 检测证书固定可以通过尝试使用自签名证书连接服务器来实现。如果应用没有实施证书固定,连接会成功;如果实施了证书固定,会抛出证书验证异常。

// 检测证书固定
public boolean isCertificatePinningEnabled() {
    try {
        // 尝试使用自签名证书连接
        URL url = new URL("https://api.example.com");
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.connect();
        return false// 如果没有抛出异常,说明没有证书固定
    } catch (Exception e) {
        return true// 抛出异常说明有证书固定
    }
}

2. 证书验证绕过检测

防护原理:应用检测是否安装了用户CA证书,如果检测到则拒绝连接。

实现方式: 应用通过检查系统的信任存储来检测是否安装了用户CA证书。常见的抓包工具如Burp Suite、Charles、Fiddler等都会安装自己的CA证书,应用可以通过检查证书的颁发者信息来识别这些工具。

// 检测用户CA证书
public boolean hasUserCACertificate() {
    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. 网络环境检测

防护原理:检测设备是否连接了代理服务器,如果检测到代理则拒绝网络请求。

实现方式: 网络环境检测主要通过检查系统代理设置和网络连接信息来实现。当用户配置了代理服务器时,系统会设置相应的代理属性,应用可以通过检查这些属性来判断是否存在代理。

// 检测代理设置
public boolean isProxyEnabled() {
    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检测流程图


实现方式

// 检测调试状态
public boolean isDebugging() {
    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. 应用完整性检测

防护原理:检测应用是否被修改或重打包,如果检测到则拒绝网络请求。

实现方式

// 检测应用签名
public boolean isAppModified() {
    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 Pinning
Java.perform(function({
    // Hook OkHttp的CertificatePinner
    var 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 X509TrustManager
    var 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 Pinning
publicclass SSLUnpinning implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        // Hook OkHttp
        XposedHelpers.findAndHookMethod("okhttp3.CertificatePinner", lpparam.classLoader,
            "check", String.classList.classnew XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                returnnull;
            }
        });
        
        // Hook TrustManager
        XposedHelpers.findAndHookMethod("javax.net.ssl.X509TrustManager", lpparam.classLoader,
            "checkServerTrusted", X509Certificate[].classString.classnew XC_MethodReplacement() {
            @Override
            protected 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[] = {0x900x900x900x900x90}; // 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.getProperty
    var 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 ConnectivityManager
    var ConnectivityManager = Java.use("android.net.ConnectivityManager");
    ConnectivityManager.getActiveNetworkInfo.implementation = function({
        var networkInfo = this.getActiveNetworkInfo();
        if (networkInfo) {
            // 清除代理信息
            networkInfo.setProxyInfo(null);
        }
        return networkInfo;
    };
});

方法二:修改网络配置

// 修改网络配置绕过代理检测
publicclass ProxyBypass {
    public static void bypassProxyDetection() {
        try {
            // 清除系统代理设置
            System.setProperty("http.proxyHost""");
            System.setProperty("http.proxyPort""");
            System.setProperty("https.proxyHost""");
            System.setProperty("https.proxyPort""");
            
            // 修改网络配置
            ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            if (cm != null) {
                // 强制使用直连
                cm.setNetworkPreference(ConnectivityManager.TYPE_WIFI);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. 反调试绕过

方法一:Frida Hook反调试检测

// Frida Hook反调试检测
Java.perform(function({
    // Hook Debug.isDebuggerConnected
    var Debug = Java.use("android.os.Debug");
    Debug.isDebuggerConnected.implementation = function({
        console.log("绕过调试检测");
        returnfalse;
    };
    
    // Hook ApplicationInfo.FLAG_DEBUGGABLE
    var ApplicationInfo = Java.use("android.content.pm.ApplicationInfo");
    ApplicationInfo.flags.implementation = function({
        var flags = this.flags;
        // 清除调试标志
        flags = flags & ~ApplicationInfo.FLAG_DEBUGGABLE.value;
        return flags;
    };
    
    // Hook Socket连接检测
    var Socket = Java.use("java.net.Socket");
    Socket.$init.overload("java.lang.String""int").implementation = function(host, port{
        if (host === "127.0.0.1" && port === 8700) {
            console.log("绕过调试端口检测");
            throw Java.use("java.net.ConnectException").$new("Connection refused");
        }
        returnthis.$init(host, port);
    };
});

方法二:修改应用标志

// 修改应用标志绕过反调试
publicclass DebugBypass {
    public static void bypassDebugDetection() {
        try {
            // 修改调试标志
            ApplicationInfo appInfo = getApplicationInfo();
            appInfo.flags = appInfo.flags & ~ApplicationInfo.FLAG_DEBUGGABLE;
            
            // 修改系统属性
            System.setProperty("ro.debuggable""0");
            System.setProperty("ro.secure""1");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4. 应用完整性绕过

方法一:Hook签名验证

// Frida Hook签名验证
Java.perform(function({
    // Hook PackageManager.getPackageInfo
    var PackageManager = Java.use("android.content.pm.PackageManager");
    PackageManager.getPackageInfo.overload("java.lang.String""int").implementation = function(packageName, flags{
        var packageInfo = this.getPackageInfo(packageName, flags);
        
        if (flags == PackageManager.GET_SIGNATURES.value) {
            // 替换签名信息
            var Signature = Java.use("android.content.pm.Signature");
            var fakeSignature = Signature.$new("伪造的签名信息");
            packageInfo.signatures = [fakeSignature];
        }
        
        return packageInfo;
    };
});

方法二:修改签名文件

# 使用apktool重新签名
apktool d app.apk
# 修改应用代码
# 重新打包
apktool b app -o app_modified.apk
# 签名
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore app_modified.apk alias_name

进阶内容

1. 动态Hook技术

// 动态Hook技术
Java.perform(function({
    // 等待类加载
    Java.choose("com.example.SecurityChecker", {
        onMatchfunction(instance{
            console.log("找到SecurityChecker实例");
            
            // Hook实例方法
            instance.checkSecurity.implementation = function({
                console.log("绕过安全检查");
                returnfalse// 返回安全检查通过
            };
        },
        onCompletefunction({
            console.log("搜索完成");
        }
    });
});

2. 内存修改技术

// 内存修改技术
#include <sys/mman.h>
#include <unistd.h>

void patchMemory(void *addr, unsigned char *patch, size_t patchSize) {
    // 修改内存保护
    mprotect(addr, patchSize, PROT_READ | PROT_WRITE | PROT_EXEC);
    
    // 应用补丁
    memcpy(addr, patch, patchSize);
    
    // 恢复内存保护
    mprotect(addr, patchSize, PROT_READ | PROT_EXEC);
}

3. 系统调用Hook

// 系统调用Hook
#include <sys/ptrace.h>
#include <sys/user.h>

long syscall_hook(int syscall_num, struct user_regs_struct *regs) {
    switch (syscall_num) {
        case SYS_ptrace:
            // 绕过ptrace检测
            return0;
        case SYS_kill:
            // 绕过kill检测
            return0;
        default:
            return syscall(syscall_num, regs->rdi, regs->rsi, regs->rdx);
    }
}

检测与防护

1. 检测Hook工具

// 检测Hook工具
public boolean isHooked() {
    try {
        // 检测Frida
        if (isFridaDetected()) {
            returntrue;
        }
        
        // 检测Xposed
        if (isXposedDetected()) {
            returntrue;
        }
        
        // 检测Substrate
        if (isSubstrateDetected()) {
            returntrue;
        }
        
        returnfalse;
    } catch (Exception e) {
        returntrue;
    }
}

private boolean isFridaDetected() {
    try {
        // 检测Frida相关文件
        String[] fridaFiles = {
            "/data/local/tmp/frida-server",
            "/data/local/tmp/re.frida.server",
            "/system/bin/frida-server"
        };
        
        for (String file : fridaFiles) {
            if (new File(file).exists()) {
                returntrue;
            }
        }
        
        // 检测Frida端口
        try {
            Socket socket = new Socket("127.0.0.1"27042);
            socket.close();
            returntrue;
        } catch (Exception e) {
            // 端口未开放
        }
        
        returnfalse;
    } catch (Exception e) {
        returnfalse;
    }
}

2. 反Hook技术

// 反Hook技术
publicclass AntiHook {
    public static void enableAntiHook() {
        // 检测并清除Hook
        if (isHooked()) {
            // 退出应用
            System.exit(0);
        }
        
        // 定期检查
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                if (isHooked()) {
                    System.exit(0);
                }
            }
        }, 05000); // 每5秒检查一次
    }
}

结语


技术对抗演进


绕过技术分类



【声明】内容源于网络
0
0
哆啦安全
移动安全(Android/iOS/鸿蒙)30+款智能产品、车联网安全、Web安全、终端安全、隐私合规、数据安全、防作弊、溯源取证、软件安全开发等的技术研究、分享,安全服务、安全培训,AI智能安全产品的研发,为政企等用户提供AI智能解决方案!
内容 912
粉丝 0
哆啦安全 移动安全(Android/iOS/鸿蒙)30+款智能产品、车联网安全、Web安全、终端安全、隐私合规、数据安全、防作弊、溯源取证、软件安全开发等的技术研究、分享,安全服务、安全培训,AI智能安全产品的研发,为政企等用户提供AI智能解决方案!
总阅读1.8k
粉丝0
内容912