本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除!
APP
aHR0cHM6Ly93d3cud2FuZG91amlhLmNvbS9hcHBzLzMyMjE4OS9oaXN0b3J5X3Y5MDczMDAx
抓包
安卓版本点击演唱会的详情页返回了sslError错误,不废话使用JustTrustMe就行。ios的不会。
分析
团系的基本都有一个方法【getRequestSignature】,直接搜就能找到mtgsig的生成了。hook下getRequestSignature,发现就一开始输出了mtgsig参数,详情页根本就hook不到mtgsig的生成。
看一下详情页抓包到的mtgsig参数中a1=1.2,但是getRequestSignature生成的a1=3.0。再看一眼其他包,发现有类似h5guard的包,这个h5guard就是在web端生成mtgsig参数的js主要代码。现在我就怀疑详情页走的是类似web端js的代码,不是走app的so层代码的(猜测)。
但是getRequestSignature生成的mtgsig拿去调用有没有用呢?主动调用下将生成的3.0的mtgsig带到详情接口中发现也能调用成功。那也就是说现在有两个方向。
- 继续找1.2是在哪里生成的。
- 直接逆向3.0。
1.2分析
感觉3.0加so肯定是会比1.2难的,因此还是先看看1.2版本的。
抓包知道有个叫H5guard.js的包,搞过web端团系列的应该会比较敏感,在web端就是这个js内的代码负责生成了签名参数,我们把js代码拷贝到本地初略的看一眼还真和web端一样。
我前面文章有搞过某团h5端的mtgsig,他的生成的mtgsig格式和某眼详情页的可以说是一模一样了,就a6参数某团h5的是h1.6开头,现在是h1.9开头,怀疑是更新了,那么就去看看现在的某团h5,发现也变成了h1.9。
那接下来就是补环境了,把之前的某团h5端的补环境代码放到这里来直接使用,能运行成功且能生成mtgsig,生成的格式和抓包到的一模一样,a6也是h1.9开头。
现在我们要知道他window.H5guard.sign的参数都是啥了,ast还原后的话还是很好找的
jH = JSON["stringify"](jG);
if (jj) {
ji["headers"]["mtgsig"] = jH;
b9("dfp_h5_sign_len", 200, 200, jH["length"], .001);
}
jG就是传入的参数了,生成后调用下也是调用成功了。
深入分析
虽然同样可以调用,但毕竟这是新版,且在app上运行,所以还是得深入分析下。下面写出我得分析过程吧。
第一步:找到a6也就是环境生成的地方,更新过后之前的寻找方法已经不适用了,这里直接搜索”k”,就能找到位置了,这里的co就是存放环境的地方

然后就是导出的co里面的内容,把co赋值给window,调用下就得到了。

第二步:获取到android上的真实设备环境,然后和上方本地生成的进行比较。那么他是在app上调用定制浏览器,在浏览器中执行js,这种情况下该怎么调试这份js呢?frida使用下面这段代码就好了,将WebView的调试设置为true,然后再电脑浏览器进入chrome://inspect,就可以在电脑端调试app中的js了。接下来就和上方一样导出环境比较即可。
Java.perform(function() {
console.log("[+] Starting WebView Debug Enable...");
var WebView = Java.use("android.webkit.WebView");
var Looper = Java.use("android.os.Looper");
var Handler = Java.use("android.os.Handler");
// 方法1: 在UI线程中设置WebView调试
var setWebContentsDebuggingEnabled = WebView.setWebContentsDebuggingEnabled;
// 创建一个在主线程中运行的任务
var runOnUiThread = function() {
try {
console.log("[+] Setting WebView debugging on UI thread...");
WebView.setWebContentsDebuggingEnabled(true);
console.log("[+] WebView debugging enabled successfully!");
} catch(e) {
console.log("[-] Error enabling WebView debugging: " + e);
}
};
// 获取主线程的Handler
var mainHandler = Handler.$new(Looper.getMainLooper());
// 在主线程中执行
mainHandler.post(Java.registerClass({
name: 'com.example.EnableDebugRunnable',
implements: [Java.use('java.lang.Runnable')],
methods: {
run: function() {
try {
console.log("[+] Running on UI thread, enabling WebView debugging...");
WebView.setWebContentsDebuggingEnabled(true);
console.log("[+] WebView debugging enabled globally on UI thread");
} catch(e) {
console.log("[-] Error in UI thread: " + e);
}
}
}
}).$new());
// 备用方法:直接调用静态方法
setTimeout(function() {
Java.scheduleOnMainThread(function() {
try {
console.log("[+] Using scheduleOnMainThread to enable debugging...");
WebView.setWebContentsDebuggingEnabled(true);
console.log("[+] WebView debugging enabled via scheduleOnMainThread");
} catch(e) {
console.log("[-] scheduleOnMainThread error: " + e);
}
});
}, 100);
});
第三步:都能在浏览器调试了具体的环境自己去补就行了,具体如何补是和之前的版本一样的,但是这版本是将生成a6的环境代码写成了jsvmp的形式,分析起来麻烦了点,但是任然还有很多参数是和之前一样一个方法一个参数的。上一个k8的生成方法。

第四步:当你环境全部补完后生成的环境里面任然存在部分参数是空的,比如k80。
这部分是通过window.addEventListener监听后生成的。具体是H5guard.js代码会去加载package-v1.js,package-v1.js加载完成后会发送事件,H5guard.js收到事件后就会去执行对应的代码,然后k80等参数就有值了。
下面这段中的fw方法就是生成k80等参数值的代码,当缺少package-v1.js时fw方法是不会去执行的。

解决办法很简单,把package-v1.js代码也扣下来加载下就好了

接下来就是剩下的一些参数处理了