目录
前言:
当我们想要分析较新版本的接口时,会发现一个有趣的现象,无论是用Charles还是Fiddler,都会出现抓不到包的情况(如下图),这是因为使用SSL Pinning证书锁定技术,是一种防止中间人攻击(MITM)的技术。
主要机制是当客户端发起请求 –> 收到服务器发来的证书进行校验,如果收到的证书不被客户端信任,就直接断开连接不继续请求。所以当我们抓包学习分析时,就只能看到Fildder/Charles上一排 CONNECT Failed 请求,找不到我们想要分析的接口。
方案:
当我们找到关键的校验位置,Hook掉对应的返回值就能愉快的抓包了。那这个关键位置是在libsscronet.so文件中,通过在IDA中找到“SSL_CTX_set_custom_verify”函数,Hook看返回值是1,经过反复调试发现只有当它返回值为0时,就可以绕过sslpinning证书校验。
知道了关键的位置,那就可以通过frida或者修改so的方式处理,还有一种通过编写好xposed去检测插件+JustTrustMe,可以完整的抓到所有请求包。
frida
这里分享一份16版本的SSL Pinning的解决方案,之前用的挺好,现在我自己测试发现不是特别好用了
缺点:
需要重启app启动注入js,运行麻烦;
hook时容易导致app异常崩溃;
服务端不给接口返回内容或403;
脚本下载:FridaHookSSL16.9.js
上面的js代码中并未hook libsscronet.so修改返回值绕过验证,是通过hook Java层方法实现的。
想要hook libsscronet.so的时候可以dlopen处理,监控so什么时候加载的,加载后可以附加后续hook代码
function main(){
// 高版本 安卓系统
var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
console.log(android_dlopen_ext);
if(android_dlopen_ext != null){
Interceptor.attach(android_dlopen_ext,{
onEnter: function(args){
var soName = args[0].readCString();
console.log(soName);
if(soName.indexOf("libsscronet.so") != -1){
this.hook = true;
}
},
onLeave: function(retval){
if (this.hook){
dlopentodo();
}
}
});
}
}
然后frida通过附加的方式启动
frida -U -f com.ss.android.ugc.aweme -l dy_hook.js
运行之后,就可以看到Charles有正常的请求出现了
替换so
我这里有一份21.8版本 libsscronet.so,通过adb shell连接上终端后,进入/data/app/com.ss.android.ugc.aweme目录下,找到原有的libsscronet.so文件,删除掉push修改后的so进去,然后执行以下命令,赋予对应的文件权限,重新启动APP就能看到请求包了。
adb connect "DeviceId"
adb -s "DeviceId" push ./libsscronet.so /data/app/com.ss.android.ugc.aweme-1/lib/arm
adb -s "DeviceId" shell
cd /data/app/com.ss.android.ugc.aweme-1/lib/arm/
chgrp system libsscronet.so
chown system libsscronet.so
chmod 777 libsscronet.so
Xposed
去检测xposed插件+JustTrustMe这种方式最好用,省去替换so或frida启动hook的流程,适用于较新多个版本,正常运行就能看到请求包。
需要插件或学习交流可以联系我,仅供学习参考!!!