【某OTA网站加密参数还原生成】

文章目录

  • 前言
  • 一、接口加密参数怎么生成?
  • 二、JS代码
  • 三、 环境


前言

最近看了下某网站的接口数据,发现和以前不一样了,于是花了会时间看了下

一、接口加密参数怎么生成?

【某OTA网站加密参数还原生成】_第1张图片
看了下接口 会发现有个testab参数 (以前叫eleven)
那么这参数怎么生成的呢?

既然这个参数名字叫testab
不妨试着搜索一下这个参数
如图

【某OTA网站加密参数还原生成】_第2张图片
然后直接点击进入代码查看
【某OTA网站加密参数还原生成】_第3张图片
可以发现这里就是这个接口的地址

然后断点
进入调试
【某OTA网站加密参数还原生成】_第4张图片
然后发现这个参数就是这个e的值 通过 e=e()这个函数返回的
那么这个参数怎么生成的呢

找下调用栈
【某OTA网站加密参数还原生成】_第5张图片
在这里 我直接在控制台运行了这一行代码 发现返回undefined
然后试着看看里面的参数 去掉外面的函数_bot_098b后 运行了下里面这个函数
发现这个就是ajax请求的接口地址

至于为什么会有两个一样的testdb参数 是因为我第一行代码也执行了一次函数,把地址拼接起来了
如下图
【某OTA网站加密参数还原生成】_第6张图片
我再运行的话 会发现又多了一个testab参数

所以得出结论
func.apply(typeof ref._bot_6d390 == "undefined" ? _bot_523b7 : ref._bot_6d390, args)这个函数执行后的作用就是往接口url拼接一个&testab=xxxx

到这里
既然我们已经知道这个函数的作用 那么不妨看看它的参数
【某OTA网站加密参数还原生成】_第7张图片
发现这个ref是个对象
再看看这个args
是一个array 里面的元素是window对象和一个函数

【某OTA网站加密参数还原生成】_第8张图片
接着我们试着运行下这个args里面的函数
在这里插入图片描述

二、JS代码

既然已经找到了生成testab的函数,
【某OTA网站加密参数还原生成】_第9张图片
跟下调用栈
【某OTA网站加密参数还原生成】_第10张图片
到这里发现 这段js代码是自调用函数 传了一个window,和一个对象{"b":"xxx", "d":"xxx"}
其实这个b,d两个参数就是和生成testab挂钩的 ,每次请求根据b,d的值来生成不同testab值

那么问题来了 现在我们还没有找到这段JS代码是从哪来的
继续
【某OTA网站加密参数还原生成】_第11张图片
到这里 发现这是一个用eval函数运行的代码 挂载在window里面

经过一番调试 找到了js代码的位置

是一个post请求

callback参数生成的方法

function r(){

        for (var e = "qwertyuiopasdfg$hjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM",t = "", n = 0; n<10; n++)
            t += e.charAt(~~(Math.random() * e.length));
        return t
            };

【某OTA网站加密参数还原生成】_第12张图片

【某OTA网站加密参数还原生成】_第13张图片

没错正是这段js 代码

接下来就是重点了 检测点很多 很多

三、 环境

新开一个窗口 把代码扔到控制台
【某OTA网站加密参数还原生成】_第14张图片

先在浏览器环境拿到这个正确的值,然后再一步一步来

'519398dc3f8944c29bb52f95e109b4e911caae7f40142f11c7276006fe2ac74c'

观察下这个加密值 64位 并且仅通过 a-f 0-9的数字组成的 (有点类似md5构成,但这里显然不是md5了)

如果 生成的加密值 出现了大写字母 或者符号 或者乱码的话
那么就可以肯定判断出 被检测到了 生成的是错误的值

首先 我不推荐使用nodejs 去执行补环境 这段代码 因为 他检测了nodejs的一些地方 代码并不好绕过

直接使用 vm2模块 使用v8环境去补

首先是window
在这里插入图片描述
补上 报错
在这里插入图片描述
这里用了window.self 那么补上吧

window.self = window;

后续相关对window的操作都是用window.self操作的

之后运行也会报错

挂上代理看看

会发现很多都是undefined

之后会发现 navigator.userAgent appCodeName appCode等等、document.createElement appendChild remove getAttribute等等都是要补的

补上这些之后

我们在关键点插桩看看

            var _bot_25721 = function(_bot_8536a) {
                if (typeof _bot_8536a._bot_05141 == 'object' || typeof _bot_8536a._bot_05141 == 'function'){
                console.log(_bot_8536a._bot_05141)}
                return _bot_8536a._bot_39d1c ? _bot_8536a._bot_6cb58[_bot_8536a._bot_aaa5b] : _bot_8536a._bot_05141;

在本地node vm2环境下跑下
【某OTA网站加密参数还原生成】_第15张图片

计算的值: 519398Q^Qf894?{<9bb5TrbJe109b]yR11caaeGr40142f17c7276006fe2ac74c
正确的值: 519398dc3f8944c29bb52f95e109b4e911caae7f40142f11c7276006fe2ac74c

保存好浏览器上 和vm2 输出的日志 分析看看

由于补充的东西太多 只说下关键点

按照日志输出顺序来

appendChild方法的检测

【某OTA网站加密参数还原生成】_第16张图片
【某OTA网站加密参数还原生成】_第17张图片

这里发现被检测到了

从日志分析 发现 连续调用了两次document.createElement("div")方法和 appendChild()方法

这里我们就要注意

往div标签里面添加element时,实际上我们是伪造的,所以我们直接往其children属性里面push一个元素就行了(如果你要完全还原实现appendChild方法的话 也不是不可以,,但太复杂了,这里主要是为了绕过这个检测)

改一下appendChild方法 (注意!!!!!!!!这里有个大坑)

Node.prototype.appendChild = function appendChild(x){
    debugger;
    this['children'].push("div");
};

等你补上这个之后 发现计算的值还是没变化

具体什么情况呢 我们分析分析

我们知道它对appenChild调用了两次

我们进到断点里面分析下 appendChild的具体流程

【某OTA网站加密参数还原生成】_第18张图片
这里相当于 以下这种方式添加 是没问题的

d1 = document.createElement('div');
d2 = document.createElement('div');
d1.appendChild(d2);
<div>
	<div></div>
</div>

接下来看看第二次调用appendChild

【某OTA网站加密参数还原生成】_第19张图片
d2.appendChild(d1)

类似于我往d2标签里面添加一个子标签,但是这个子标签里面又包含了自己

在浏览器上就会出错 而如果我们是自写的appendChild方法添加对象 是不会报错的

浏览器出错逻辑如下图;
【某OTA网站加密参数还原生成】_第20张图片
所以我们的appendChild方法也要抛异常

改好之后 看看

在这里插入图片描述
之前日志输出的true 也变成false

计算的值: 519398dcQf8944c59bb52fC<e109bQnG11caae@q40142f19c7276006fe2ac74c
正确的值: 519398dc3f8944c29bb52f95e109b4e911caae7f40142f11c7276006fe2ac74c

发现之前出错的第7/8位字符都正确了 但是其他位置还是不对

继续 offsetHeight

浏览器上是false

【某OTA网站加密参数还原生成】_第21张图片
vm2 是ture
【某OTA网站加密参数还原生成】_第22张图片

offsetHeight 是在HTMLElement原型下的属性

补上之后

计算的值: 519398dcQf8944c59bb52fC<e109bQnG11caae@q40142f19c7276006fe2ac74c
正确的值: 519398dc3f8944c29bb52f95e109b4e911caae7f40142f11c7276006fe2ac74c

发现还是不对 我们去看看浏览器上的这个属性

HTMLElement.prototype.offsetHeight
VM14136:1 Uncaught TypeError: Illegal invocation
    at <anonymous>:1:23

浏览器上这个属性是不可获取的

所以要改一下get 方法 让他抛出异常

HTMLElement.prototype.__defineGetter__("offsetHeight",function(){
    throw TypeError("Illegal invocation")
})

【某OTA网站加密参数还原生成】_第23张图片

可以发现补上之后 true就变成false

Object.keys方法获取属性检测
【某OTA网站加密参数还原生成】_第24张图片
hook Object.keys 函数【某OTA网站加密参数还原生成】_第25张图片Object.getOwnPropertyDescriptor检测【某OTA网站加密参数还原生成】_第26张图片
浏览器上:
在这里插入图片描述
本地:
【某OTA网站加密参数还原生成】_第27张图片
所以 我们需要hook这个函数

toString检测
【某OTA网站加密参数还原生成】_第28张图片
补上!

一、原型属性检测

Object.getOwnPropertyNames检测

【某OTA网站加密参数还原生成】_第29张图片
这里取了navigator的属性 如果你是通过navigator = {xxx: xxx}这种定义的 那么肯定会被检测到 拿出来不是空数组

解决方案1:定义其原型 并且在原型上补

Navigator.prototype.plugins = [];
Navigator.prototype.appCodeName = "Mozilla";
Navigator.prototype.appName = "Netscape";
Navigator.prototype.platform = "Win32";
Navigator.prototype.userAgent =  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36";
Navigator.prototype.languages = ["zh-CN"];
Navigator.prototype.webdriver = false;

解决方案2:hook

var obj_name = Object.getOwnPropertyNames;

Object.getOwnPropertyNames = function getOwnPropertyNames(obj){
    let temp = obj_name.apply(this, arguments)
    if ( obj== navigator){
        return []
    }
    // ...其他的需自己补
    return temp
}

ps:实测代码运行过程中 只对navigator的原型进行了输出,所以navigator的原型是必须补的。
【某OTA网站加密参数还原生成】_第30张图片

之后是document的属性
【某OTA网站加密参数还原生成】_第31张图片
也用类似navigator的操作就行了

这里要补下document.documentElement.getAttribute函数 返回null就行了
【某OTA网站加密参数还原生成】_第32张图片

【某OTA网站加密参数还原生成】_第33张图片

【某OTA网站加密参数还原生成】_第34张图片
这里发现 拿了Document的原型属性

然后把之前的['location', '__sn'] 添加到数组的前面

【某OTA网站加密参数还原生成】_第35张图片
这里又拿了Node的属性 放到数组的后面 232 + 47 = 279

【某OTA网站加密参数还原生成】_第36张图片
这里又拿了EventTarget的属性 加到数组后面

【某OTA网站加密参数还原生成】_第37张图片
【某OTA网站加密参数还原生成】_第38张图片
这里发现取了Image的原型属性

Object.getOwnPropertyNames(Image.prototype)
(28) ['alt', 'src', 'srcset', 'sizes', 'crossOrigin', 'useMap', 'isMap', 'width', 'height', 'naturalWidth', 'naturalHeight', 'complete', 'currentSrc', 'referrerPolicy', 'decoding', 'name', 'lowsrc', 'align', 'hspace', 'vspace', 'longDesc', 'border', 'x', 'y', 'decode', 'fetchPriority', 'loading', 'constructor']

二、node 环境检测

【某OTA网站加密参数还原生成】_第39张图片
如果你用的是nodejs的话 那么这里就会被检测到了, 浏览器上是没有这个process的
这里就需要 delete process;

当然这只是一小部分 肯定还有其他检测的地方

比如require 等等

所以不推荐使用node

三、加密参数的数组
【某OTA网站加密参数还原生成】_第40张图片

在这里插入图片描述
在代码运行过程中 有一个数组 逐渐在往里面添加数字

直到数组到64位时 这个值就生成了

五、不可改变的对象

挂上代理之后 能发现 对navigatoruserAgent,appCodeName,platform进行赋值操作

set  Navigator {plugins: Proxy, appCodeName: 'Mozilla', appName: 'Netscape', platform: 'Win32', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWeb…KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',} appCodeName string ctrip.com
set  Navigator {plugins: Proxy, appCodeName: 'Mozilla', appName: 'Netscape', platform: 'Win32', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWeb…KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',} appCodeName string Mozilla
set  Navigator {plugins: Proxy, appCodeName: 'Mozilla', appName: 'Netscape', platform: 'Win32', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWeb…KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',} platform string ctrip.com
set  Navigator {plugins: Proxy, appCodeName: 'Mozilla', appName: 'Netscape', platform: 'Win32', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWeb…KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',} platform string Win32
set  Navigator {plugins: Proxy, appCodeName: 'Mozilla', appName: 'Netscape', platform: 'Win32', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWeb…KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',} userAgent string ctrip.com
set  Navigator {plugins: Proxy, appCodeName: 'Mozilla', appName: 'Netscape', platform: 'Win32', userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWeb…KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',} userAgent string Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36

这里就要注意了
【某OTA网站加密参数还原生成】_第41张图片
【某OTA网站加密参数还原生成】_第42张图片
运行过程中 会给document.cookie赋值

在浏览器上 类似window document navigator 这种 是不可被赋值的

所以我们在补完环境之后 最后加上这些代码 需要冻结这些对象

Object.freeze(navigator);

Object.freeze(document);

Object.freeze(location);
VM143 VM222:9 get  Window fbejkbakrbadskfe undefined undefined

这里取了window.fbejkbakrbadskfe 在其网站上这个值也是undefined 暂时不用管

总结:

主要是对原型函数 原型链的检测 dom操作的检测 node环境 检测 自动化工具检测
补的时候必须要细

文章的顺序可能有点乱 但是需要补的关键点都已经全部写出来,剩下的就需要自己踩坑了

附上生成参数结果:
【某OTA网站加密参数还原生成】_第43张图片

如有违规侵权 请联系我删除!!!!!!!
如有违规侵权 请联系我删除!!!!!!!
如有违规侵权 请联系我删除!!!!!!!

你可能感兴趣的:(javascript)