跳到主要内容

补环境的今生前世

补环境的产生原因

JS的运行环境分为浏览器环境,Node环境。

不管是什么环境,都是JS,想要运行JS,务必需一个容器,这个容器就是JS的运行环境。但是一个情况是每个环境里面执行JS代码的可能会有轻微的实现不一样,比如在JS浏览器环境中具有DOM等,Node环境没有DOM。 还有一些BOM,BOM是浏览器的BOM。但是呢,Node环境没有BOM。

用等式表达是如下,

JS浏览器运行环境 = V8虚拟机 + DOM + BOM(如Window对象) + 程序员写的JS代码

JS的Node运行环境 = V8虚拟机 + Node内置的API(如FS文件操作) 程序员写的JS代码

看到这些公式后,就能明白一个时期,假如一个程序员写了一个加密函数,然后在浏览器中运行,然后在算法中,调用了BOM对象里面的某个属性,因此在逆向的时候即使看到了加密函数,能复制出来,结果发现运行的时候是Node环境,直接因为找不到BOM对象的属性直接报错了。

提示

在Web逆向中,必定是给前端浏览器扣代码运行调试的,因此其实补环境其实就是在把BOM和DOM的内置的一些对象给补充完整,需要哪个补哪个对象,没有太多神秘的。 BOM方面是Window对象的内部补充,DOM方面是document对象内部补充。

另外,补环境突出一个补字,并不是完全补全,比如一个加密函数,用到了一个Window对象下面的Location对象里面的属性,因此我只需在本地把Window对象下面的Location对象里面的属性补全,然后运行,就可以得到结果了。就这个意思啦。意思就是需要什么补什么,而不是一股脑把所有的对象都塞进来。

还有一个重点是,加密函数经常会有这样的代码

if(是不是浏览器){
正常代码执行逻辑
}else{
直接报错; 就认为是攻击,爬虫来了。执行逻辑
}

这样,在逆向的时候,如果发现加密函数,直接判断是不是浏览器,不是浏览器,直接报错,就认为攻击,爬虫来了。

补环境究竟在补什么

  1. 补Window对象
  2. 补document对象
  3. 删Node环境的内置API,如FS,IO等等

基本使用

补环境的工作逻辑如下,补环境相当于自己写了一个浏览器,一个抽象的说法是,这个浏览器运行在Node环境中,因此需把window和document对象添加到运行的Node环境中,同时把Node的内置API没有用的给屏蔽掉删掉。 有时候会很好奇,为什么要删掉,因为可能会有这样的加密函数代码。

if(发现了Node的内置API,如FS文件操作){
直接报错
}else{
才会执行正常逻辑
}

补环境分类

很好理解,第一阶段是在补BOM和DOM,也就是在补充window和document,以及去掉Node的内置的影响结果的API。

不好理解的是,第二阶段要补充某些对象的原型链,试想为什么要补充原型链? 原因就是有时候,加密函数会这么写判断,如下

if(Obj.__proto__ === Array.prototype) {
new Obj.push(1)
}else{
环境有问题,返回错误
}

prototype 是一个对象,这个对象有proto属性,这个属性是一个对象,这个对象有push方法,因此这个判断就是判断这个对象是不是数组。 那如果没找到,那我就认为你这不是浏览器环境,直接就认为你是爬虫。

框架原理和框架

补环境的框架很多,看得再多没用,这里直接把他们的补环境的框架原理直接写出来即可。这样子,即使别人的补环境框架不好用,自己还能实现自己的补环境框架。

危险

最推荐的是自己写自己的补环境,原因是,无法确定别人的补环境代码里面放入了什么恶意病毒。

原理

这里给一个通用一点的框架填充模型。

框架填充模型框架填充模型

补环境框架

市面上有很多常用的

比较好点的是https://github.com/bnmgh1/node-sandbox,他用的是JSDOM

如果傻瓜式操作的话,就用这个,安装一下谷歌浏览器插件即可。https://github.com/cilame/v_jstools

jstools的安装视频和使用视频,多看看,如下:https://www.bilibili.com/video/BV1Ap4y1K7F3/?spm_id_from=333.337.search-card.all.click&vd_source=5a6807a0a4854971729727460870310a

如果是自己仅仅想在Node中执行,那么就选https://github.com/pysunday/sdenv

关于vm2

npm install vm2

# 浏览器方式执行
node --inspect-brk vm2test.js

vm2框架指纹处理 vm2/lib/setup-sandbox.js

  • global ->window

  • 框架填充模型框架填充模型
  • VMError注释

  • Buffer注释

  • host.INTERNAL_STATE_NAME

  • vm2/lib/transformer.js acornWalkFull删除

框架填充模型
  • 本质是检测这个 shopee也有检测框架填充模型

说说扣代码

对于js逆向来说,这是两种常规且实用的手段,也各有优劣势;

不管使用哪种方式,我们都是先从网站中将加密JS代码扣出,然后再选择是继续扣代码,将使用到的浏览器环境api进行逻辑替换;还是使用补环境,让加密JS代码仿佛在浏览器环境中运行。

扣代码与补环境都依赖对JS的熟练度,扣代码更侧重js语法和代码逻辑,补环境更侧重原型链及BOM、DOM对象的模拟。

扣代码熟练度依赖逆向经验,补环境几乎只依赖JS熟练度。

扣代码需要调试跟踪大量逻辑,对于rs,如果不解混淆的话,屁股得坐出痔疮;

扣代码需要替换环境检测逻辑,所以也需要知道哪里使用了浏览器环境; 补环境框架可以只用于监测浏览器环境的使用,可以当做扣代码的一个辅助工具。

由于瑞数是动态的,扣代码只能扣一份静态的,所以需要找到vm中使用到的所有动态属性进行映射。而补环境是通用的,补的越多,可通杀的网站就越多。

扣代码比补环境执行效率高,毕竟补环境的代码数比扣代码多很多,可以通过剔除不需要的环境来缩小差距;

扣代码人工耗时远高于补环境。

扣代码侧重js语法和代码逻辑,其熟练度依赖于逆向经验,对不同网站要扣的不一样,难以通用,人工效率低,但是程序执行效率高。

补环境侧重原型链及浏览器环境模拟,熟练度几乎只依赖对JS的原理掌握程度,对于不同网站补的越多可通杀的网站越多,人工效率巨高,但是程序执行效率不高。

补环境的其他内容

这里可以提前看看,JS逆向之补环境过瑞数详解,看不懂不要紧。https://blog.csdn.net/qq_36291294/article/details/128600583

Docker是一种虚拟技术,他是直接模拟一台服务器,因此,并且可以提供完整的JS调用接口,很多配置都可以自己一劳永逸的配好,未来可以替代补环境。补环境一个缺点是碰到比较厉害的网站后,会出现一种情况,即使用了补环境也无法绕过,因为他通过浏览器的API获取了操作系统的基本配置,经过浏览器返回的信息也生成了操作系统的指纹,因此,补环境只是把运行这块给绕过了,有些函数执行过一次,里面会发生系统级别,更改指纹并不能解决,因此只能换电脑,但是换电脑是很麻烦的,所以如果用Docker,经过每次传入的基本信息都不一样,可以做到完全匿名自己,减少自己的风险。

JSRPC

解决一切补环境困难,既不用写补环境代码,也有不用关注Docker的容器镜像,只需明白HTTP过程调用,那么就能完整的过JS加密函数等内容。

https://github.com/jxhczhl/JsRpc

JSRPC是一个基于HTTP的RPC框架,可以快速实现JS加密函数的解密。可以看他的github的readme文件。

一定要看JSRPC,可以拿着JSRPC试试,可以提高自己的技术水平的,跟别人交流的时候,彰显自己能力。