文章目录

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



前言

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

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

java接入易签宝 e签宝接口文档_javascript


看了下接口 会发现有个testab参数 (以前叫eleven)

那么这参数怎么生成的呢?

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

java接入易签宝 e签宝接口文档_Chrome_02


然后直接点击进入代码查看

java接入易签宝 e签宝接口文档_Windows_03


可以发现这里就是这个接口的地址然后断点

进入调试

java接入易签宝 e签宝接口文档_Chrome_04


然后发现这个参数就是这个e的值 通过 e=e()这个函数返回的

那么这个参数怎么生成的呢找下调用栈

java接入易签宝 e签宝接口文档_java接入易签宝_05


在这里 我直接在控制台运行了这一行代码 发现返回undefined

然后试着看看里面的参数 去掉外面的函数_bot_098b后 运行了下里面这个函数

发现这个就是ajax请求的接口地址至于为什么会有两个一样的testdb参数 是因为我第一行代码也执行了一次函数,把地址拼接起来了

如下图

java接入易签宝 e签宝接口文档_Chrome_06


我再运行的话 会发现又多了一个testab参数

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

到这里

既然我们已经知道这个函数的作用 那么不妨看看它的参数

java接入易签宝 e签宝接口文档_java接入易签宝_07


发现这个ref是个对象

再看看这个args 是一个array 里面的元素是window对象和一个函数

java接入易签宝 e签宝接口文档_Windows_08


接着我们试着运行下这个args里面的函数

java接入易签宝 e签宝接口文档_Windows_09

二、JS代码

既然已经找到了生成testab的函数,

java接入易签宝 e签宝接口文档_Chrome_10


跟下调用栈

java接入易签宝 e签宝接口文档_javascript_11


到这里发现 这段js代码是自调用函数 传了一个window,和一个对象{"b":"xxx", "d":"xxx"} 其实这个b,d两个参数就是和生成testab挂钩的 ,每次请求根据b,d的值来生成不同testab值那么问题来了 现在我们还没有找到这段JS代码是从哪来的

继续

java接入易签宝 e签宝接口文档_Chrome_12


到这里 发现这是一个用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
            };

java接入易签宝 e签宝接口文档_Chrome_13

java接入易签宝 e签宝接口文档_javascript_14

没错正是这段js 代码

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

三、 环境

新开一个窗口 把代码扔到控制台

java接入易签宝 e签宝接口文档_Win32_15

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

'519398dc3f8944c29bb52f95e109b4e911caae7f40142f11c7276006fe2ac74c'

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

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

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

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

首先是window

java接入易签宝 e签宝接口文档_Win32_16


补上 报错

java接入易签宝 e签宝接口文档_Windows_17


这里用了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环境下跑下

java接入易签宝 e签宝接口文档_Chrome_18

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

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

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

按照日志输出顺序来

appendChild方法的检测

java接入易签宝 e签宝接口文档_Chrome_19


java接入易签宝 e签宝接口文档_Windows_20

这里发现被检测到了

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

这里我们就要注意

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

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

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

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

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

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

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

java接入易签宝 e签宝接口文档_Win32_21


这里相当于 以下这种方式添加 是没问题的

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

接下来看看第二次调用appendChild

java接入易签宝 e签宝接口文档_Windows_22


d2.appendChild(d1)

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

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

浏览器出错逻辑如下图;

java接入易签宝 e签宝接口文档_Chrome_23


所以我们的appendChild方法也要抛异常

改好之后 看看

java接入易签宝 e签宝接口文档_java接入易签宝_24


之前日志输出的true 也变成false

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

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

继续 offsetHeight

浏览器上是false

java接入易签宝 e签宝接口文档_Windows_25


vm2 是ture

java接入易签宝 e签宝接口文档_javascript_26

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")
})

java接入易签宝 e签宝接口文档_javascript_27

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

Object.keys方法获取属性检测

java接入易签宝 e签宝接口文档_javascript_28


hook Object.keys 函数

java接入易签宝 e签宝接口文档_Windows_29

Object.getOwnPropertyDescriptor检测

java接入易签宝 e签宝接口文档_javascript_30


浏览器上:

java接入易签宝 e签宝接口文档_Win32_31


本地:

java接入易签宝 e签宝接口文档_Win32_32


所以 我们需要hook这个函数toString检测

java接入易签宝 e签宝接口文档_java接入易签宝_33


补上!

一、原型属性检测

Object.getOwnPropertyNames检测

java接入易签宝 e签宝接口文档_Chrome_34


这里取了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的原型是必须补的。

java接入易签宝 e签宝接口文档_java接入易签宝_35

之后是document的属性

java接入易签宝 e签宝接口文档_javascript_36


也用类似navigator的操作就行了这里要补下document.documentElement.getAttribute函数 返回null就行了

java接入易签宝 e签宝接口文档_Win32_37

java接入易签宝 e签宝接口文档_Chrome_38

java接入易签宝 e签宝接口文档_Win32_39


这里发现 拿了Document的原型属性

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

java接入易签宝 e签宝接口文档_Chrome_40


这里又拿了Node的属性 放到数组的后面 232 + 47 = 279

java接入易签宝 e签宝接口文档_javascript_41


这里又拿了EventTarget的属性 加到数组后面

java接入易签宝 e签宝接口文档_java接入易签宝_42


java接入易签宝 e签宝接口文档_java接入易签宝_43


这里发现取了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 环境检测

java接入易签宝 e签宝接口文档_Chrome_44


如果你用的是nodejs的话 那么这里就会被检测到了, 浏览器上是没有这个process的

这里就需要 delete process;

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

比如require 等等

所以不推荐使用node

三、加密参数的数组

java接入易签宝 e签宝接口文档_javascript_45

java接入易签宝 e签宝接口文档_Windows_46


在代码运行过程中 有一个数组 逐渐在往里面添加数字

直到数组到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

这里就要注意了

java接入易签宝 e签宝接口文档_Windows_47


java接入易签宝 e签宝接口文档_Chrome_48


运行过程中 会给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环境 检测 自动化工具检测
补的时候必须要细

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

附上生成参数结果:

java接入易签宝 e签宝接口文档_Windows_49

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