快手升级到v8.x版本以后,会发现直接用Charles、Fiddler等抓包工具抓包的时候,抓不到包了。这是因为快手用了quic协议,下面就具体讲一下分析过程和解决方案。
一、分析过程
我曾经在分析sig参数的时候看到过有一个方法入参是okhttp3.Request,我们就直接从这里入手。
用Frida hook一下,打印request看一下。
var s = Java.use('j.a.a.b7.s');
s.a.overload('okhttp3.Request', 'java.util.Map', 'java.util.Map').implementation = function (a1, a2, a3) {
console.log(a1)
return this.a(a1, a2, a3)
}
打印后,可以看到url和一些参数,并没有协议相关的信息。
打印堆栈看一下。
var exc = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new());
console.log(exc)
可以看到在j.a.v.f这个类中有一个拦截器。
直接hook这个intercept方法,打印一下response。
var f = Java.use('j.a.v.f');
f.intercept.overload("okhttp3.Interceptor$Chain").implementation = function (a1) {
var ret = this.intercept(a1);
console.log(ret);
return ret;
}
可以看到,请求使用了quic协议。
quic协议目前通过直接抓包是无法抓到的,我们得想办法迫使app使用http协议,然后再抓包。
这里我卡了很久,后来在InfoQ网站上看到一篇关于快手kQUIC的文章(文章链接:https://www.infoq.cn/article/41HJkeZM7hEgIYlJRFK0),其中有这么一段话。
文章中写到,在app中使用了客户端网络库Aegon。
二、解决方案
我们从Aegon库入手,最终可以在一个native方法中找到一个开关:”enable_quic”: true
我们直接hook这个位置,强制把true改为false。
var aegon = Java.use('com.*.*.Aegon');
aegon.nativeUpdateConfig.overload("java.lang.String", "java.lang.String").implementation = function (a1, a2) {
a1 = '{"enable_quic": false, "preconect_num_streams": 2, "quic_idle_timeout_sec": 180, "quic_use_bbr": true, "altsvc_broken_time_max": 600, "altsvc_broken_time_base": 60, "proxy_host_blacklist": []}'
this.nativeUpdateConfig(a1, a2);
}
如果还是抓不到包,可以考虑在手机上使用Postern软件创建vpn转发到charles上,最终效果如下。