目标地址:aHR0cDovL3p3Zncuc2FuLWhlLmdvdi5jbi9pY2l0eS9pY2l0eS9ndWVzdGJvb2svaW50ZXJhY3Q=
点击下一页,即可抓包查看接口,但是一打开调试工具,马上开始debugger,点击下一步,又会被断到另一个 debugger 的位置,这种情况就是无限 debugger,无限 debugger 存在的意义就是防止一部分人进行调试,但事实上绕过无限 debugger 的方法非常简单,方法也非常多,以下介绍常用的几种绕过方法。
-
Never pause here
最简单快捷的方法
-
Add conditional breakpoint
同样右键选择 Add conditional breakpoint,输入 false 即可跳过无限 debugger,其原理是添加条件断点,不管前面代码的逻辑是什么,运行到 debugger 的时候必定是 true 才能执行,只需要将其改为 false,那么它就不执行了,其实Never pause here也是这个道理。 -
中间人拦截替换
所谓中间人拦截替换,就是将原来的含有无限 debugger 的函数给替换掉,这种方法适用于知道无限 debugger 函数所在的具体 JS 文件,重写 JS 文件,使其不含有无限 debugger 的函数,利用第三方工具将原来的 JS 文件替换成重写过后的文件,这类工具有很多,例如浏览器插件 ReRes,它通过指定规则,可以把请求映射到其他的 URL,也可以映射到本机的文件或者目录,抓包软件 Fidder 的 Auto responder 功能,也可以实现替换,甚至新一点的谷歌浏览器地source面板都可以重写JS了。
绕过无限debugger后,这个网站的逆向就非常简单了,抓包结果如下
json数据可以看到很简单,就是分页用的,url参数有几个像是加密的,直接全局搜索OPEN@,只有一处结果,下断,只需跟进execute函数,可以找到加密位置
所有的逻辑都在addUrlAuth函数中,直接全盘扣出来
/**
* 添加url 参数校验
*/
addUrlAuth: function (url) {
var curUrl = url;
if (this.isApiV2) {
var sig = "";
var chars = "0123456789abcdef";
if (!LEx.isNotNull(__signature)) {
var curTime = parseInt(Math.random() * (9999 - 1000 + 1) + 1000) + "" + Date.parse(new Date());
sig = chars.charAt(parseInt(Math.random() * (15 - 15 + 1) + 10)) + chars.charAt(curTime.length) + "" + curTime;
} else {
sig = __signature;
}
var key = "";
var keyIndex = -1;
for (var i = 0; i < 6; i++) {
var c = sig.charAt(keyIndex + 1);
key += c;
keyIndex = chars.indexOf(c);
if (keyIndex < 0 || keyIndex >= sig.length) {
keyIndex = i;
}
}
var timestamp = parseInt(Math.random() * (9999 - 1000 + 1) + 1000) + "_" + key + "_" + Date.parse(new Date());
var t = timestamp;
t = t.replace(/\+/g, "_");
var tkey = "";
var tkeyIndex = -1;
for(var i=0;i<6;i++){
var c=timestamp.charAt(tkeyIndex+1);
tkey +=c;
tkeyIndex = chars.indexOf(c);
if(tkeyIndex<0 || tkeyIndex>=timestamp.length){
tkeyIndex = i;
}
}
curUrl += "?s=" + sig;
curUrl += "&t=" + t;
curUrl += "&o=" + tkey;
}
return curUrl;
}
其中的__signature可以在html源码中找到,this.isApiV2也可以直接改为ture。
Q.E.D.