本文案例主要分析七麦数据榜单中的analysis参数。
url: https://www.qimai.cn/rank/index/brand/paid/device/iphone/country/cn/genre/5000
接口分析
经分析接口中有加密参数analysis。
cookie中参数由服务端返回,可以免cookie访问,所以只需要分析analysis。
逆向分析
全局搜analysis没有找到。 那么从堆栈进。
进来断点后,点一下别的榜单类型,触发请求。
可以发现触发断点的时候已经有 analysis了。
此时可以往回调试
多摁几下,摁了有5下看到了请求发起 添加参数的代码。
所以这里就是参数生成的地方。除了这种分析方式外,也可以通过注入hook Params代码 或者 AST漫游的方式来进行定位。
在该位置多下几个断点,刷新页面触发请求,F11往下调试。注意接口是否是 /rank/index。
往下继续调试, h + "=" + encodeURIComponent(a))
h = analysis
那怎么扣这个代码。 就是要把 a = (0,n.cv)((0,n.oZ)(r, l)) 和 后面的 -1 == e.url.indexOf(h)... 都搞出来
a = (0,n.cv)((0,n.oZ)(r, l))返回了一个字符串
后面的 -1 == e.url.indexOf(h)... 返回的是e,e中有analysis。
n.cv和n.oZ , e是请求对象,t是时间戳"1641980727.333"
function ncv(e) {
return function(e) {
try {
return btoa(e)
} catch (t) {
return Buffer.from(e).toString("base64")
}
}(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g, (function(e, t) {
return i("0x" + t)
}
)))
}
function noZ(e, t) {
t || (t = s());
for (var a = (e = e.split("")).length, n = t.length, o = "charCodeAt", r = 0; r < a; r++)
e[r] = i(e[r][o](0) ^ t[(r + 10) % n][o](0));
return e.join("")
}
r = "NTAwMGNuaXBob25lcGFpZA==@#/rank/index@#126855073625@#1"
l = "0000000c735d856"
所以在本地也执行一下 ,报错 ReferenceError: i is not defined 。
去在i那行断点,把i也拿下来。
再次运行程序,成功输出结果,并且和浏览器中的一样。
到这里并没有结束,可以发现r是一个随机值
把params的参数拿出来做一些处理。
接下来还是扣代码,这个过程就不说了,一点一点调试即可。
JS代码
最终扣下来的JS代码如下:
// 需要nodejs环境
function ncv(e) {
return function(e) {
try {
return btoa(e);
} catch (t) {
return Buffer.from(e).toString("base64")
}
}(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g, (function(e, t) {
return i("0x" + t)
}
)))
}
function noZ(e, t) {
t || (t = s());
for (var a = (e = e.split("")).length, n = t.length, o = "charCodeAt", r = 0; r < a; r++)
e[r] = i(e[r][o](0) ^ t[(r + 10) % n][o](0));
return e.join("")
}
function i(e) {
var t, a = (t = "",
["66", "72", "6f", "6d", "43", "68", "61", "72", "43", "6f", "64", "65"].forEach((function(e) {
t += unescape("%u00" + e)
}
)),
t);
return String[a](e)
}
// 此部分是f的生成,但是发现f是个定值,所以注释了
// var cookie = ""
// function nej(e) {
// var t, a = new RegExp("(^| )" + e + "=([^;]*)(;|$)");
// return (t = cookie.match(a)) ? unescape(t[2]) : null
// }
// var t = (0,nej)("synct");
// f = -(0,nej)("syncd") || +new Date - 1e3 * t
function get_analysis(xhr,brand){
var f = 267;
var l = "0000000c735d856";
var a,
o = +new Date - (f || 0) - 1515125653845,
r = [];
var e = {};
e.url = xhr;
e.params = {
brand: brand,
country: "cn",
device: "iphone",
genre: "5000"
};
Object.keys(e.params).forEach((function(t) {
if (t == false)
return !1;
e.params.hasOwnProperty(t) && r.push(e.params[t])
})),
r = r.sort().join(""),
r = (0,
ncv)(r),
r += "@#" + e.url.replace('https://api.qimai.cn', ""),
r += "@#" + o,
r += "@#" + 1,
a = (0,ncv)((0, noZ)(r, l)),
-1 == e.url.indexOf("analysis") && (e.url += (-1 != e.url.indexOf("?") ? "&" : "?") + "analysis" + "=" + encodeURIComponent(a)),
e;
return e
}
// console.log(get_analysis("/rank/index","paid"));
运行查看结果:
Python调用
【温馨提示:此处隐藏内容需要付费订阅后才能查看!】
运行