背景
昨日失足于滑铁卢,临时开启的某数安全防护让很多人都铩羽而归。
惨败之余大葱哥对JS有了更深入的认识,一个JS能玩出这么多花样,真是太牛逼了。
通过js动态更新本地cookie值,服务端会校验该cokie值是否合法,如果不合法,服务端就会下毒,给用户产生假数据,如死循环、页面频繁跳转等。
js的动态更新本地cookie关联了很多窗口、鼠标、键盘事件,这些事件都会触发cookie的更新,同时js会采集浏览器信息加密存放到cookie中,通过这一些操作,服务端可以根据cookie来判断客户端特征,来识别是正常方式还是自动化访问,从而采取防护措施。
而这个js是做了加密混淆的,分成了多个部分,存在了不同的地方,有的放在meta中,有的放在页面脚本中,有的需要动态下载。
这每个地方的代码都会在每次请求时做变更,也就是每次看到的都不一样。
专业解释
现在很多网站都上了各种前端反爬手段,无论手段如何,最重要的是要把包含反爬手段的前端javascript代码加密隐藏起来,然后在运行时实时解密动态执行。
动态执行js代码无非两种方法,即eval和Function。那么,不管网站加密代码写的多牛,我们只要将这两个方法hook住,即可获取到解密后的可执行js代码。
注意,有些网站会检测eval和Function这两个方法是否原生,因此需要一些小花招来忽悠过去
js玩法
- 注入全局eval函数的钩子:
(function() {
if (window.__cr_eval) return
window.__cr_eval = window.eval
var myeval = function (src) {
console.log("================ eval begin: length=" + src.length + ",caller=" + (myeval.caller && myeval.caller.name) + " ===============")
console.log(src);
console.log("================ eval end ================")
return window.__cr_eval(src)
}
var _myeval = myeval.bind(null)
_myeval.toString = window.__cr_eval.toString
Object.defineProperty(window, 'eval', { value: _myeval })
console.log(">>>>>>>>>>>>>> eval injected: " + document.location + " <<<<<<<<<<<<<<<<<<<")
})();
- 注入全局function函数
(function() {
if (window.__cr_fun) return
window.__cr_fun = window.Function
var myfun = function () {
var args = Array.prototype.slice.call(arguments, 0, -1).join(","), src = arguments[arguments.length - 1]
console.log("================ Function begin: args=" + args + ", length=" + src.length + ",caller=" + (myfun.caller && myfun.caller.name) + " ===============")
console.log(src);
console.log("================ Function end ================")
return window.__cr_fun.apply(this, arguments)
}
myfun.toString = function() { return window.__cr_fun + "" }
Object.defineProperty(window, 'Function', { value: myfun })
console.log(">>>>>>>>>>>>>> Function injected: " + document.location + " <<<<<<<<<<<<<<<<<<<")
})();
- 打印系统全局变量
(function () {
for (var p in window) {
if (p.substr(0, 2) !== "_$") continue;
if (typeof window[p] !== "function" || window[p].name !== "") continue;
try {
var s = window[p]();
console.log(p + "=" + s)
} catch (e) {}
}
})()
网友评论