本来就想拦截一下Android app的消息,没想到过程曲折,而且还没成功,希望师傅们指点迷津
字数 1492 2025-08-22 12:22:36
Android应用消息拦截与SSL Pinning绕过实战指南
1. 环境准备与基础配置
1.1 模拟器选择与配置
推荐使用Genymotion模拟器,版本选择Android 10.0 API 29:
- 需要注册Genymotion账号
- 安装对应版本的ARM Translation包(Android 10.0 API 29需使用Genymotion_ARM_Translation_8.0)
- 其他版本组合可能不兼容,需严格匹配
1.2 网络配置要点
- 模拟器默认HTTP连接正常
- HTTPS连接需要额外配置证书
- 浏览器可访问HTTP网站(如http://baidu.com)但无法访问HTTPS网站(如https://baidu.com)是典型症状
2. SSL证书安装流程
2.1 生成BurpSuite证书
- 从BurpSuite导出CA证书
- 命名为
burp.cer(或其他易识别名称) - 将证书文件拖入模拟器的
sdcard/download目录
2.2 证书安装步骤
- 在模拟器中找到证书文件
- 通过文件管理器安装证书
- 确保证书安装在"系统"或"VPN和应用"信任区域
- 验证:安装后应能正常访问HTTPS网站
3. SSL Pinning绕过技术
3.1 常见SSL Pinning实现方式
- 证书固定(Certificate Pinning)
- 公钥固定(Public Key Pinning)
- 证书链验证
3.2 绕过方法
-
使用Frida脚本:
setTimeout(function(){ Java.perform(function (){ console.log("[*] Script loaded"); // 绕过证书验证 var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl"); TrustManagerImpl.checkTrustedRecursive.implementation = function(a, b, c, d, e, f) { console.log("[*] Bypassing SSL verification"); return this.checkTrustedRecursive(a, b, c, d, e, f); }; }); }, 0); -
使用Objection框架:
objection explore --startup-command "android sslpinning disable" -
修改APK文件:
- 使用apktool反编译APK
- 修改网络安全性配置
- 重新打包并签名
4. 双向SSL校验绕过
4.1 识别双向SSL校验
- 检查APK的assets和res目录
- 查找.p12或.pfx证书文件
- 注意非常规证书文件(如stamp-cert-sha256)
4.2 处理方法
-
动态Hook:
- 使用Frida Hook SSL上下文初始化
- 替换客户端证书加载逻辑
-
静态分析:
// 典型客户端证书加载代码 KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(context.getResources().openRawResource(R.raw.client_cert), "password".toCharArray()); -
证书提取:
- 对未知格式证书文件进行逆向分析
- 使用hex编辑器查看文件内容
- 尝试转换为标准格式
5. 常见问题解决方案
5.1 模拟器崩溃问题
- 原因:通常与ARM Translation包不兼容或证书安装错误有关
- 解决方案:
- 重新安装匹配版本的ARM Translation
- 清除模拟器数据重新开始
- 尝试不同版本的模拟器
5.2 HTTPS拦截失败
- 检查项:
- 确保证书正确安装且受信任
- 验证BurpSuite代理设置
- 检查应用是否使用了证书固定
- 确认是否有双向SSL校验
5.3 未知证书文件处理
- 对stamp-cert-sha256等非常规文件:
- 使用hex编辑器分析文件头
- 尝试作为PEM/DER格式处理
- 查找APK中加载该文件的代码逻辑
- 使用动态分析工具监控文件访问
6. 进阶技巧
6.1 组合使用工具
- Frida + BurpSuite + Wireshark联合分析
- Objection + adb logcat实时监控
6.2 自定义脚本示例
// 绕过特定应用的SSL验证
Java.perform(function() {
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
var TrustManager = Java.registerClass({
name: 'com.example.TrustManager',
implements: [X509TrustManager],
methods: {
checkClientTrusted: function(chain, authType) {
console.log("Bypassing client trust check");
},
checkServerTrusted: function(chain, authType) {
console.log("Bypassing server trust check");
},
getAcceptedIssuers: function() {
return [];
}
}
});
SSLContext.init.overload('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom').implementation = function(kms, tms, sr) {
console.log("Replacing trust managers");
var newTms = [TrustManager.$new()];
return this.init(kms, newTms, sr);
};
});
7. 总结流程
- 环境准备:正确配置模拟器和ARM Translation
- 基础拦截:安装Burp证书,验证基础HTTPS拦截
- 分析障碍:识别是SSL Pinning还是双向SSL校验
- 选择方法:根据障碍类型选择适当绕过技术
- 验证结果:确认拦截成功,数据可读
- 问题排查:针对特定错误寻找解决方案
通过系统性地应用这些技术和方法,应该能够成功拦截大多数Android应用的消息通信。对于特别加固的应用,可能需要结合多种技术和更深入的反向工程分析。