首页
社区
课程
招聘
[原创]Android上中间人抓包的原理?如何进行防护?如何进行对抗?
发表于: 2025-3-20 12:29 1674

[原创]Android上中间人抓包的原理?如何进行防护?如何进行对抗?

2025-3-20 12:29
1674

中间人攻击(MITM)是怎么抓包的?

MITM 攻击一般有几种方式,都是围绕着让应用“误信”伪造的服务器或证书。

代理劫持流量(Burp Suite / Charles)

攻击者在手机上安装一个代理工具(比如 Burp Suite、Charles),然后手动安装伪造 CA 证书,让 HTTPS 流量经过代理。这样一来,所有数据就可以被解密、查看、甚至篡改。

对抗方案:

  • SSL Pinning(证书固定),让应用只信任指定的证书,而不是系统 CA。
  • 检测系统代理,如果发现有代理工具在运行,直接阻断网络请求。

代码检测代理:

1
2
3
4
private boolean isUsingProxy() {
    String proxyHost = System.getProperty("http.proxyHost");
    return proxyHost != null;
}

篡改系统证书(Root + Magisk)

如果手机已经 Root,攻击者可以修改 /system/etc/security/cacerts/,加入自己的伪造 CA 证书,让整个系统都信任它。这样,哪怕应用开启了 SSL Pinning,流量还是会被解密。

对抗方案:

  • 应用内部存储证书哈希值,避免使用系统 CA。
  • 检测 Root 状态,如果发现设备被 Root,直接提醒用户或禁止某些功能。

代码检测 Root:

1
2
3
4
5
6
7
private boolean isDeviceRooted() {
    String[] paths = { "/system/bin/su", "/system/xbin/su", "/sbin/su" };
    for (String path : paths) {
        if (new File(path).exists()) return true;
    }
    return false;
}

Hook SSL 相关 API(Frida / Xposed)

更高级的攻击方式是 Hook SSLSocketFactoryOkHttp 相关的 SSL 方法,把 checkServerTrusted() 直接改成 始终返回 true,这样 SSL Pinning 形同虚设。

Frida 绕过 SSL Pinning 的代码(攻击者用的):

1
2
3
4
5
6
7
8
Java.perform(function () {
    var SSLContext = Java.use("javax.net.ssl.SSLContext");
    SSLContext.init.implementation = function (key, trust, secure) {
        console.log("[Bypassed] SSL Pinning check");
        return this.init.overload('java.security.KeyManager[]', 'java.security.TrustManager[]', 'java.security.SecureRandom')
            .call(this, key, null, secure);
    };
});

对抗方案:

  • 检测 Frida Hook 进程,如果发现 Frida 在运行,直接终止应用。
  • 使用 Native 层(C/C++)实现 SSL 逻辑,让 Hook 更困难。
  • 在 SSL Pinning 逻辑里加时间验证,防止攻击者随便改逻辑。

代码检测 Frida:

1
2
3
4
5
6
7
8
9
public static boolean detectFrida() {
    String[] fridaLibs = { "frida-agent", "libfrida" };
    for (String lib : fridaLibs) {
        if (new File("/system/lib/" + lib).exists() || new File("/system/lib64/" + lib).exists()) {
            return true;
        }
    }
    return false;
}

对抗方案(多层防御)

光靠 SSL Pinning 其实不够,因为 Hook 可以绕过它。所以我一般会用多层防护,提高攻击难度。

1. 启用 SSL Pinning

让应用只信任固定的证书,防止伪造 CA。

代码(OkHttp 实现 SSL Pinning):

1
2
3
4
5
6
7
CertificatePinner certificatePinner = new CertificatePinner.Builder()
    .add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAA=")
    .build();
 
OkHttpClient client = new OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .build();

2. 检测代理和 VPN

避免流量被导入 Burp Suite/Fiddler 之类的工具。

代码检测 VPN:

1
2
3
4
private boolean isUsingVPN() {
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_VPN;
}

3. 反 Hook 保护

防止 Frida/Xposed Hook 关键 API。

代码检测 Xposed:

1
2
3
4
5
6
7
8
public static boolean isXposedActive() {
    try {
        Class.forName("de.robv.android.xposed.XposedBridge");
        return true;
    } catch (ClassNotFoundException e) {
        return false;
    }
}

4. 数据层加密(即使被抓包,也无法解密)

即使 TLS 失效,攻击者拿到的数据仍然是加密的。

AES 加密数据

1
2
3
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, aesKey, new IvParameterSpec(ivBytes));
byte[] encryptedData = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

5. 服务器端 HMAC 校验

防止攻击者篡改数据或重放请求。

服务器端 HMAC 签名校验

1
2
3
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secretKey.getBytes(), "HmacSHA256"));
byte[] signature = mac.doFinal(data.getBytes());

最后简洁版如下:

防护措施 目的 实现方式
SSL Pinning 防止伪造证书 OkHttp CertificatePinner
检测代理/VPN 防止 Burp/Fiddler 抓包 isUsingProxy() / isUsingVPN()
反 Hook 防止 Frida/Xposed 绕过 SSL Pinning 进程检测
应用层加密 即使 TLS 失效,数据也无法解密 AES + HMAC
服务器端 HMAC 校验 防止数据篡改 HMAC-SHA256 签名

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
免费 4
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回