1.前言
大家好呀,我是你们的好兄弟,星云牛马!这个signature
参数出来很久了,但是呢,网上并没有补环境相关的教程,偶尔有几个教程,但是并没有验证是否能够建立wss
链接,也有伙伴发现补环境补出来的并不能用,其实就是某些检测没有通过,但是呢,这个signature
作者水平是值得肯定的,环境相关的检测一看就知道是js的老手,这样的代码,不拿来深入研究学习,还等什么,所以今天我们就来看看这个加密参数的那些事儿!
记得加入我们的学习群:961566389
点击链接加入群聊:https://h5.qun.qq.com/s/62P0xwrCNO
我有话说:
其实我本人而言,是喜欢钻研技术本质和内涵的,在逆向参数的时候,不是简单为了使用,更多的是学习,学习源码作者是怎么检测的,像极了人与人之间的心里博弈,这种感觉你们懂得都懂。
2.补环境
啰嗦话就不说了,直接把加密的整个文件代码拿到本地,定睛一看,有ob混淆,二话不说,直接先上解混淆工具,解下混淆,一顿操作,代码清晰多了:
再一看,妈的,变量名是在太长了,调试影响观感,再简化变量名,压缩下:
哇哦,看起来舒服多了。调试少了很多眼睛痛苦。
接下来,写上测试代码:
我默认大家都会找到window.byted_acrawler.frontierSign
这个入口加密函数哈,本着补环境的原则,尽量少修改代码的情况下,就不用那种打断点,导出函数到全局的多此一举的操作了,因为本来人家就已经将函数导出到全局了,为啥每个jsvmp都会把加密函数挂载到window上??哈哈,当然是为了开发方便啊,团队协作,一般都是将加密的封装为一个js文件,然后挂载加密的对象、函数到window上,方便别人使用的时候,直接调用呗。
好,开始操作,补了一些发现,结果如下:
看看源码:
是在这里挂载的,为啥浏览器能挂载到window下,node不行呢?但至少说明上面代码的_0x1d18f2
一定是
byted_acrawler对象,但是node不是,那就追踪这个变量看看呗:
!function (_0xe67213, _0x19937e) {
"object" == typeof exports && "undefined" != typeof module ?
_0x19937e(exports) :
"function" == typeof define && define.amd ?
define(["exports"], _0x19937e) :
_0x19937e((_0xe67213 = "undefined" != typeof globalThis ? globalThis : _0xe67213 || self).byted_acrawler = {});
}(this, function (_0x1d18f2) {
//省略代码几千行
//……
_0x1d18f2.frontierSign = _0x5c2014;
_0x1d18f2.getReferer = _0x32e4a6;
_0x1d18f2.init = _0x498349;
_0x1d18f2.isWebmssdk = _0x1649bc;
_0x1d18f2.report = _0x475194;
_0x1d18f2.setConfig = _0x4a4111;
_0x1d18f2.setTTWebid = _0x3a4a1a;
_0x1d18f2.setTTWebidV2 = _0x3f0a66;
_0x1d18f2.setTTWid = _0x271dea;
_0x1d18f2.setUserMode = _0x3498af;
Object.defineProperty(_0x1d18f2, "__esModule", {
value: !0
});
})
可以看出,自执行函数传入了this,在浏览器是window,在node是global,然后看传进去干了啥,上面的三目运算中涉及的判断,我们对比下浏览器和node的区别:
浏览器 | node | 备注 | |
---|---|---|---|
exports | undefined | {} | exports实际就是module.exports |
module | undefined | ![]() | |
define | undefined | undefined | |
globalThis | window | global | |
this | window | global | 这里只讨论上述代码里传入的this,因为this很灵活,可以根据场景指向很多东西 |
self | window | undefined | |
top | window | undefined | |
process | undefined | object | |
有了上图,可以看出:
- 浏览器是走:
_0x19937e((_0xe67213 = "undefined" != typeof globalThis ? globalThis : _0xe67213 || self).byted_acrawler = {})
故_0x1d18f2
形参对应globalThis.byted_acrawler
,故frontierSign
挂载在window.byted_acrawler下。
- node走:
_0x19937e(exports)
故最终将frontierSign
挂载在了module.exports对象上。
综上分析后,就一目了然了,在node
调用方式不限于:
module.exports.frontierSign
exports.frontierSign
这里为了和浏览器尽可能一致,我们就想办法挂载在window.byted_acrawler上。
大道至简,直接将上述代码修改为:
!function (_0xe67213, _0x19937e) {
_0x19937e(window.byted_acrawler = {});
}(this, function (_0x1d18f2) {
//省略代码几千行
//……
_0x1d18f2.frontierSign = _0x5c2014;
_0x1d18f2.getReferer = _0x32e4a6;
_0x1d18f2.init = _0x498349;
_0x1d18f2.isWebmssdk = _0x1649bc;
_0x1d18f2.report = _0x475194;
_0x1d18f2.setConfig = _0x4a4111;
_0x1d18f2.setTTWebid = _0x3a4a1a;
_0x1d18f2.setTTWebidV2 = _0x3f0a66;
_0x1d18f2.setTTWid = _0x271dea;
_0x1d18f2.setUserMode = _0x3498af;
Object.defineProperty(_0x1d18f2, "__esModule", {
value: !0
});
})
接着挂上代理,缺啥补啥:
万万没想到,补上了ua就出值了,出值后,发现过了会又输出了东西。肯定是settimeout的问题,全局搜索直接注释了,看着碍眼:
拿着这个值去请求wss直连,发现不能成功,原因呢就是没有通过dom检测啦,你可以全局搜索envcode >> 8 & 255;
,定位到如下位置:
直接在这里魔改envcode为1,59等(尽可能小点)其实都不用补环境了,,,,,,当然,定位到这需要勇气和意识。
所以最终补环境补全也可,魔改这个值也可。
如果魔改,那么就是大道至简:
document = {};
window = {};
navigator = {
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
};
3.验证
完整补环境代码在星球,感兴趣的伙伴可以咨询:
记得加入我们的学习群:961566389
点击链接加入群聊:https://h5.qun.qq.com/s/62P0xwrCNO