今天我们来爬取问财网站的信息:
在这个网站输入时间+跌停/涨停,可以查看当天的股票数据
今天我们的目标就是,拿到这些数据:
关键在于:有一个v的加密参数
1. 分析:
因为这个参数在cookie中,我们可以使用hook的方式来定位加密函数:
hook——>cookie:
//在get/set cookie 的时候进去该hook代码:
(function (){
var temp = "";
Object.defineProperty(document, "cookie", {
get: function(){
debugger;
return temp
},
set: function(v){
debugger;
temp = v;
return v
}
})
}());
断进来之后:查看调用栈
下一步,直到发现:c就是cookie的值
看代码,发现c里的 t 是重点:(第二个参数)
进入下一个调用栈:
找到入口函数rt.update(),进入:
运行的是o():
function O() {
S[R]++,
S[p] = Jn.serverTimeNow(),
S[d] = Jn.timeNow(),
S[B] = Vn,
S[I] = nt.getMouseMove(),
S[y] = nt.getMouseClick(),
S[_] = nt.getMouseWhell(),
S[C] = nt.getKeyDown(),
S[E] = nt.getClickPos().x,
S[A] = nt.getClickPos().y;
var n = S.toBuffer(); # <———这里
return zn.encode(n)
}
n[e[57]] = P;
function D() {
return O()
}
2.补环境:
今天我们采取补环境的方式实现逆向。
思路:
我们可以看到:O函数中对S进行了运算
而S在前面也有添加元素,故应该扣下整个闭包代码:
猜测一下执行过程:
// 大概率是
// rt.Init()
// rt.update() => 我们要的cookie
观察代码也发现,在最后的自运行函数中,调用了rt.Init()
使用思路应该是:
扣下该自运行函数:先实现运行n[“Init”] = P,然后n[“update”] = D
但是var t过于长,难以补充环境 ——>尝试扣下更多代码
我们需要的 t 是一个超大数组:
思路:先复制该js的头尾,实现实参:
再把r = e = a = n;r = e = a = n;具体的赋值扣下来:
其中缺少Wn,at,ot:补全
补全后,注释调用代码,看看环境是否补齐:发现缺document、window
//尝试:
window = global;
document = {};
补环境完毕
放开注释代码后:这是因为rt定义在闭包里——>放到全局就可以了
运行发现:
发现缺qn
进入后:注意观察 虽然是进来在 l(r)
但qn是大函数返回的值+() ——> l ()
直接扣下全部代码
运行继续报错:
s是Date, TOKEN_SERVER_TIME经搜索是存在的,函数走后面
记得把TOKEN_SERVER_TIME补进环境
摸清楚执行逻辑后:
function M() {
var n = Qn.getCookie(Fn) || Zn.get(jn);
if (n && n[s[111]] == parseInt(c[221], e[93])) {
var t = zn.decode(n);
if (t && (S.decodeBuffer(t),
S[l] != s[2]))
return
}
S[l] = Jn.random()
}
逻辑;Fn是’v’,jn是"hexin-v" ————>这两应该是同时出现的!
如果用户第一次访问,Jn.random()
如果是第n次访问,有cookie,那么就有n
直接简化:
进入Jn:发现是随机 ——>直接定死
运行:缺Vn,Un:
运行:
这里是取值,在浏览器运行看看是什么:
同理解决函数O():
运行:
进入zn:老规矩 ——>这玩意应该是一坨,复制整个zn
运行:
进入发现:et 是无效代码
直接:
终于搞定: