js逆向--反爬介绍(1)

一.介绍:

  近几年大数据的发展,各个公司的数据保护意识越来越强,随着前端技术的发展,前端代码的打包技术,混淆技术,加密技术层出不穷,使各公司可以在前端对js代码采取一定的保护,比如变量名混淆,执行逻辑混淆,反调试,核心逻辑加密等,使得我们没法轻易地找出js代码中包含的执行逻辑。

  对于反爬网站复杂的,没有办法破解就只能用Selenium等工具模拟浏览器,所见及所得。其实还有一种解决方案就是js 逆向代码,找出其中的加密逻辑,这个方案难度很大,但比Selenium等工具爬取的效率会大幅提高。

  后面会介绍一些常见的js逆向技巧,包含浏览器工具的使用,Hook技术,AST技术,特殊混淆技术的处理,WebAssembly技术的处理。

 

  1.1 网站加密和混淆技术

    1)网站的URL带有一些看不懂的长串加密参数,要抓取就必须懂得这些参数是怎么构造的。比如digikey的分页参数s:

https://www.digikey.cn/zh/products/filter/multiple-conductor-cables/473?s=N4IgrCBcoA5QTAGhDOl5gL6aA

    2)网站的Ajax接口时,有的url参数也是加密的,或者request Headers里面也可能带有一些加密的。

      以上二者都属于url参数加密。 有的客户端和服务端约定一种接口校验逻辑,客户端在每次请求服务端接口的时候都会附带一个加密sign参数,客户端通过加密算法来构造sign, 服务端会根据约定好的算法和请求的数据对sign进行校验。

      加密和编码的算法,如Base64,Hex编码,MD5,AES,DES,RSA等对称或非对称加密。客户端和服务器肯定也都有对应的sdk实现这些算法,如js的CryptoJS,python的hashlib,crypto等等

    3)查看网站的js源码,发现很多压缩了或者看不太懂的字符,比如js文件名被编码,文件内容被压缩,变量是单个字符或者一些十六进制的字符。

      上面1,2点的参数加密的确是一个不错的解决方案,但还需要将js代码进行压缩、混淆和加密,这样才不会轻易被破解。

      现在js混淆的主流实现是javascript-obfuscator和terser这两个库,使得js代码的可读性大大降低。 

 

  1.2 javascript混淆

    javascript混淆完全是在javascript上面进行的处理,目的就是使的js变得难以阅读和分析,是一种很实用的js保护方案。javascript的混淆技术(通过javascript-obfuscator库)主要有以下几种:

    1)变更名混淆:将带有含义的变量名,方法名,常量名随机变为无意义的类乱码字符串,降低代码的可读性,如转成单个字符或十六进制字符串。

#方法名混淆,应该是十六进制
592648: function(e, t) {
        "use strict";
        t.Z = function(e) {
            return e && e.__esModule ? e : {
                default: e
            }
        }
    }
#方法名混淆, 单个字符串
n: function(e, t) {
        "use strict";
        t.Z = function(e) {
            return e && e.__esModule ? e : {
                default: e
            }
        }
    }

    2)字符串混淆:将字符串进行MD5或Base64加密存储,便代码中不会出现明文字符串,这样可以避免使用全局搜索字符串的方式定位到入口

    3)  控制流平坦化:打乱函数原有代码的执行流程及函数调用关系,使代码逻辑变得混乱无序。

      参考:js常见入门加密技术之控制流平坦化

    4)无用代码注入: 随机在代码中插入不会被执行到的无用代码,进一步使代码看起来更混乱。 

#比如这里有一段代码:
const a = function () {
  console.log("hello world");
};
const b = function () {
  console.log("nice to meet you");
};
a();
b();

#注入后
const _0x16c18d = function () {
  if (!![[]]) {
    console.log("hello world");
  } else {
    console.log("this");
    console.log("is");
    console.log("dead");
    console.log("code");
  }
};
const _0x1f7292 = function () {
  if ("xmv2nOdfy2N".charAt(4) !== String.fromCharCode(110)) {
    console.log("this");
    console.log("is");
    console.log("dead");
    console.log("code");
  } else {
    console.log("nice to meet you");
  }
};

_0x16c18d();
_0x1f7292();

    5)禁用控制台输出

      可以使用disableConsoleOutput 来禁用掉 console.log 输出功能,加大调试难度,示例如下:      

const code = `
console.log('hello world')
`;
const options = {
  disableConsoleOutput: true,
};

      混淆后,看不到明文的disableConsoleOutput,混淆后的代码,去浏览器控制台执行,会发现没有任何输出,这里实际上就是将console的一此功能禁用了。

    6)调试保护

      如果在代码多个位置都加入 debugger 这个关键字,或者定义某个逻辑来反复执行 debugger,那就会不断进入断点调试模式,原本的代码无法就无法顺畅地执行了。这个过程可以称为调试保护。 

setInterval(() => {
  debugger;
}, 3000);

      这样就会干扰到正常的调试流程。

     7)域名锁定

      通过控制 domainLock 来控制 JavaScript 代码只能在特定域名下运行,这样就可以降低代码被模拟或盗用的风险。

    8)特殊编码

      另外还有一些特殊的工具包,如使用 aaencode、jjencode、jsfuck 等工具对代码进行混淆和编码。

      参考:下面的文献

 

 

文献:

    崔庆才 Python3 爬虫教程 - JavaScript 网站加密和混淆技术简介      

 

posted on 2023-07-11 17:54  花阴偷移  阅读(418)  评论(0编辑  收藏  举报

导航