立即注册,突破游客限制,与技术大牛交流切磋,畅享海量资源,让你的技术之路不再孤单!
您需要 登录 才可以下载或查看,没有账号?立即注册
×
某音采取的不是 https协议 所以常用的抓包软件无法解析数据包抓取 比如 小黄鸟 小蓝鸟
某音系列采取的是GQUIC协议
根据从网上查到的一些公开怎么应对GQUIC协议抓包的方法,大多都是在想办法去绕过这个协议。如,修改路由规则来阻止UDP上443端口的流量使其被动地降级到HTTPS,或者逆向分析调整QUIC配置使其直接降级到HTTPS。还有一些其他方法,如Dump SSL中的KeyLog,然后再使用Wireshark解密。这个方法用来抓取HTTPS特别好用,对于QUIC来说则只支持IETF标准下的QUIC,本例中的APP使用的是早期的GQUIC,它有着一套自己的加密方式QUIC Crypto,所以并不适用。
QUIC协议结构
怎么解密GQUIC数据包 GQUIC Crypto 使用了前向安全机制,即双方先计算出一个临时的初始密钥,用于对握手阶段的信息进行加密。后续再基于这个初始密钥,进一步计算出会话密钥,用于加密后续的通信数据。这样做的优点就在于,即使服务器的私钥后续被泄露,也无法解密之前已经完成的通信记录。所以想要解密GQUIC数据包,则必须也按照这个步骤先计算出初始密钥,再计算出会话密钥。
想要解密GQUIC数据包至少需要四个材料:预主密钥(premaster secret)、CHLO握手数据包,REJ握手数据包,和随机数(Diversification Nonce)。其中后三者都可以通过抓包工具直接获得,但是,预主密钥的生成依赖于各自的私钥和对方的公钥,公钥信息可以从握手数据包中提取,私钥信息则是保密的。因此,解密GQUIC数据包的关键实际上就是怎么去获取私钥。当然,获取服务器的私钥不太现实,但是获取客户端的私钥还是有一定操作空间的。 目前商用的QUIC协议大多都是基于已开源的项目,因此在分析采用QUIC协议的客户端时,可以先确定其使用的是哪个开源项目后再去分析该项目的开源代码,根据从代码中提取到的特征去逆向分析客户端,使其能直接定位到生成私钥的地方,然后再通过Hook获取。至于怎么通过特征去逆向分析,那办法就多了,最简单的莫过于通过字符串去定位,总之对于有经验的人来说就是小case。 以某茄APP为例,它使用了Google的cronet库GitHub - google/quiche, 所以通过分析cronet的开源代码后通过从代码中提取到的字符串”Key exchange failure“特征,成功地定位到了生成私钥的地方。 然后再使用Frida hook,代码如下
- function OnCreatePrivateKey(imgBase)
- {
- var cornetBase = Module.findBaseAddress(imgBase);
- if (cornetBase == null)
- {
- console.log("can't found the cornet\n");
- return;
- }
- var onCreatePrivateKeyFun = cornetBase.add(0x1E524C);
- if (onCreatePrivateKeyFun == null)
- {
- console.log("bad onCreatePrivateKeyFun");
- return;
- }
- if (onCreatePrivateKeyFun.readU64().toString(16) != "97fff8b8910163e8")
- {
- console.log(`bad feature${ onCreatePrivateKeyFun.readU64().toString(16)}`);
- return;
- }
-
- Interceptor.attach(onCreatePrivateKeyFun, {
- onEnter: function(args)
- {
- var private_key_ptr = new NativePointer(this.context.x0);
- var len = this.context.x1.toUInt32();
- if (len != 32)
- {
- console.log("bad private key");
- }
- else
- {
- var private_key = private_key_ptr.readByteArray(32);
- var private_key_hex = Array.prototype.map.call(new Uint8Array(private_key), x => ('00' +
- x.toString(16)).slice(-2)).join('');
-
- console.log(`hit OnCreatePrivateKey and the key is ${private_key_hex} the len is ${len}`)
- }
-
- }
- })
- console.log("success found onCreatePrivateKeyFun")
- }
复制代码
现在已经能获取到私钥了,然后再根据上述的步骤去生成密钥就可以对数据包解密了,不会也没关系,后面有开源代码。
实战至于某音的话朋友说和这个一样,不过我没尝试,不想去折腾它的反调试了。 至于具体的实现,这里就不讲了,不然篇幅实在太大,我会把代码上传到Github上,感兴趣的自己去研究吧。 https://github.com/google/quiche
|