我是靠谱客的博主 落寞铃铛,最近开发中收集的这篇文章主要介绍【瑞数5】浅谈某普期刊JS逆向的环境检测点前言JS加载流程AST简单解混淆环境检测运行结果总结鸣谢,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

【瑞数5】浅谈某普期刊JS逆向的环境检测点

  • 前言
  • JS加载流程
    • 第一个JS
    • 第二个JS
    • 第三个JS
  • AST简单解混淆
  • 环境检测
    • 前奏
    • 异步执行JS流程
    • 高潮
  • 运行结果
  • 总结
  • 鸣谢

前言

这几天把某期刊的rs5环境检测看差不多了,所以写篇文章简单聊下rs5会检测到的一些环境。我所用的方法基于浏览器“沙箱”的,可以做到边调试边补环境。
如果有想看算法运行逻辑的同学,出门左转看十一姐的文章。
RPC方案可以看看这个视频(陈不不大佬出品)。

https://www.bilibili.com/video/BV1PS4y127Mn

PS:我菜所以不会分析算法逻辑…

本文以某普期刊的高级检索接口作为示例,地址:aHR0cDovL3Fpa2FuLmNxdmlwLmNvbS9RaWthbi9TZWFyY2gvQWR2YW5jZT9mcm9tPWluZGV4

JS加载流程

第一步当然是,输入网址,F12,打上script断点调试,回车!
在这里插入图片描述

在这里插入图片描述访问网页先是返回一个这样的html代码,而不是维普首页的内容。并返回给我们一个Cookie,GW1gelwM5YZuS=xxxxxx。玩过某数都知道,我们需要在这个页面得到一个GW1gelwM5YZuT参数,然后写在cookie中,再次访问网址,即可得到首页的内容。

第一个JS

在这里插入图片描述
第一个JS是生成$_ts参数。我建议大家先copy一份源代码以供后续本地调试。
然后这个JS的链接是在html页面里的,用正则可以很快的匹配到。
在这里插入图片描述

第二个JS

在这里插入图片描述

我们点击跳过断点,进入第二个JS。JS在$_ts里push很多参数,供后续使用。这个JS也是比较重要的,然后这个JS是在html页面里的,是一个闭包函数。JS运行结束时会用eval函数进入第三个JS。
然后html标签的meta,它的content参数,后续也是有使用到的。

第三个JS

在这里插入图片描述
这里就是eval函数入口。我们直接搜索]](_$ 字符串就能很快定位到这里了。打上断点看一下。没做过的同学可以自己试试各种方法去找到这里哈,博主用了hook cookie的方式找到了这里,贴上hook代码(直接从v神插件里偷代码,大佬的代码用起来就是舒服,嘿嘿~)。

init_cookie(document.cookie)
function init_cookie(cookie){
  var cache = (cookie || "").trim();
  if (!cache){
    cache = ''
  }else if (cache.charAt(cache.length-1) != ';'){
    cache += '; '
  }else{
    cache += ' '
  }
  Object.defineProperty(Document.prototype, 'cookie', {
    get: function() {
      var r = cache.slice(0,cache.length-2);
      v_console_log('  [*] document -> cookie[get]', r)
      return r
    },
    set: function(c) {
      v_console_log('  [*] document -> cookie[set]', c)
      var ncookie = c.split(";")[0].split("=");
      if (!ncookie[1]){
        return c
      }
      var key = ncookie[0].trim()
      var val = ncookie[1].trim()
      var newc = key+'='+val
      var flag = false;
      var temp = cache.split("; ").map(function(a) {
        if (a.split("=")[0] === key) {
          flag = true;
          return newc;
        }
        return a;
      })
      cache = temp.join("; ");
      if (!flag) {
        cache += newc + "; ";
      }
      return cache;
    }
  });
}

在这里插入图片描述

  • 可以看到_$ya就是第三个JS了,并且这里的 $_ts已经init完成了。
  • 这时候,我把3份JS都保存到本地了,供后续本地调试。
  • 本地调试的时候,可以把入口注释掉,然后手动eval 格式化好的代码,这样调试会更轻松一些。
  • 博主这边不依赖Node环境,使用vm2模块构建沙箱进行调试,然后Promise需要手写,否则V8运行会报错。

AST简单解混淆

第三份JS是重点需要调试并且查看代码是如何检测环境的。我们可以用AST简单的脱个混淆。我是直接在调试的时候把这个数组值的拿出来,然后用AST直接匹配替换(这个混淆数组是由一个函数得到的,这里就不放出来了,很好找到)。效果如图~
在这里插入图片描述

环境检测

前奏

前奏是指上述3个js执行完毕之后,会得到一个比较短的cookie(是可以直接访问的首页,检测比较松),以及三个环境值,在localStorage里,分别是 nd、cDro、YWTU
这部分的dom检测比较松,没什么坑,很容易补出来。

在这里插入图片描述
这里它创建了一个div节点,并使用了div.getElementsByTagName(“i”)方法获取了一个值。不懂的同学可以去菜鸟教程里看看,或者在浏览器里输入这些代码查看返回值等。 并且还检测了msCrypto以及ActiveObject。

每次调用xhr的open方法时,都会走向这里。他创建了一个a 标签,并对a标签href进行赋值。这里有做参数值校验,并和location里的参数进行比对,但是是有差异的,如果有问题会导致后面搜索接口里的得到的拼接url错误。
在这里插入图片描述
我们去浏览器hook下 createElement 这个方法,然后进到这个地方的代码看下a标签下的 hrefpathname 等参数,将环境补的一模一样即可。

document.hookCreateElement = document.createElement;
document.createElement = function(tagName){
    if(tagName === "a"){
        debugger;
    }
    return document.hookCreateElement(tagName);
}

dir(标签a) 就能得到标签下的值了,下图是a标签下的值
在这里插入图片描述
location下的值还是有差异的,这里是有用的,对应的值必须要补的完全一样,然后这里其实有个小细节,通过对a标签的href进行赋值,a标签下的host hostname 等一些参数也会根据href的值来进行赋值,然后rs6也是有检测这个标签的。
在这里插入图片描述

在这里插入图片描述

这里就是使用了document.getElementsByTagName方法获取到了html页面里 meta 节点,得到了content参数,然后把这个节点删除掉了。

在这里插入图片描述
这里是把页面上 head下的所有script节点全部删除

在这里插入图片描述
检测了document.documentElement.style

在这里插入图片描述
页面上还有2个这样的函数,是在script节点下的,别漏掉了。这里的方法会再页面write一个节点出来,并删除所有script节点。
在这里插入图片描述

write了一个节点,若没有body节点,则会创建body节点并在body节点下加入一个子节点。
在这里插入图片描述

在这里插入图片描述
在这里获取他的名字 and 值
在这里插入图片描述

rs5 检测了location document navigator 等重要环境值,以及原型链toString检测。当我们使用代理(proxy)的时候(自行百度,不做介绍),就能监测到他使用了哪些环境变量。这里就不一一列举了,偏多~ 但是必须一致,否则会导致运行轨迹变化。

异步执行JS流程

前奏部分执行完毕后,开始异步执行最后的JS。这部分是得到localStorage里的 ff、f0 、f1 、fh1 环境变量,最后得到完整的cookie, 长度位279位。

下面是前奏的JS代码中,添加的一些异步方法(巨坑!!)

在这里插入图片描述
这里检测了navigator.getBattery方法,然后navigator.getBattery()后异步执行_$mg方法。

在这里插入图片描述
这里就是_$mg方法执行过程中会调用的一个地方,这里的 sy 再后续会用到,这里的level是一个环境值。Ap是BatteryManager。

然后是window.addEventListener 添加类型为 load 的监听事件,一共7个,在这过程中就有用到上面提到的 sy 参数, 若为undefined,就会导致JS运行轨迹变化。 异步执行方法的顺序需要注意!
在这里插入图片描述
然后再执行监听事件JS中,再次添加setTimeout 来实现异步执行JS。

在这里插入图片描述
_$_w就是setTimeout , 后面则是要执行的方法。

高潮

这部分尤其残暴。检测了各种节点操作,添加删除,寻找子节点 等等

在这里插入图片描述
这部分关系到 fh1 参数的形成。_$UC 是后续进行加密时会用到的数组。 创建div节点,通过设置innerHTML添加子节点,然后将div 加入到 body节点下。通过不断修改style来改变节点的高度、宽度,若修改style后的 宽、高 与一开始的宽高不一致,就把style样式的名称存入数组。

检测了 window 下的 matchMedia
在这里插入图片描述
这里是个小细节,window instanceof Window 结果是true。
在这里插入图片描述

这里就是webgl指纹了
在这里插入图片描述

在这里插入图片描述

还有很多坑,需要同学们自己去踩了才知道。博主这篇文章只放了一些踩到的坑~ 并不是全部。再多说一点,就不礼貌了~

运行结果

附上运行结果

在这里插入图片描述
在这里插入图片描述
其中ff是动态的(环境检测)。f0,f1在不同浏览器下会不一样,2个值的变化取决于 canvas指纹、webgl指纹,fh1可能在别的浏览器中不存在。YWTU(每份JS生成的不同),cDro都是静态的。

2022.7.7 补充
目前鼠标事件分析的七七八八了,比较重要的是move、leave、enter、down。至于事件流程,大家先在代码中找到赋值数组的位置,然后在浏览器上进行断点,查看是哪个鼠标事件触发之后会走到这。最后经过一系列的鼠标事件过后,cookie的xxxT参数以及url的后缀长度都会和浏览器一致。下面是运行结果测试,大致已经算是完结了,撒花~
请添加图片描述

2022.7.21 补充
由于沙箱是v8环境,我之前用execjs库运行js,无法动态缓存一些环境,所以是手动在v8环境中调用获取值来进行访问测试。然后就在今天,群里的泰迪佬告诉我py_mini_racer这个库是可以执行js并缓存环境的(在这里感谢下泰迪佬,爱你么么)。测试下来,执行速度还不错,连续访问了20次都返回了200状态码。安利一波~
在这里插入图片描述
2022.8.29 补充
用了v神的插件之后,就自己写了个hook 浏览器dom节点的脚本,能实现dom节点自吐调用了哪些函数和值,写的还不是很好。然后顺带hook了鼠标事件之后我才发现,这样去定位js代码调用鼠标事件的位置会更快一点。当然如果用控制流去判断,也能定位到位置,这样去查看调用堆栈会更清晰些。hook 脚本代码已经放在新出的文章里了~
在这里插入图片描述

总结

  • 补环境当中,若遇到执行时的参数有问题,导致的运行轨迹变化,需要去浏览器上定位相同代码位置查找问题、或翻JS代码找到参数赋值的地方。

  • 补环境的话,主要在意的就是在控制流循环下运行的顺序是否与浏览器上的一致。

PS:博主主要就是在这里比对浏览器的运行顺序,进行问题排查(可以排查大部分,还有一些需要自己去想办法找)。
在这里插入图片描述

  • 博主文章写的少,可能排版看起来不舒服,还请见谅~

  • 本篇文章仅供学习参考,如有侵权,请立即联系博主删除。未经博主允许请勿私自转发文章~

鸣谢

在这里感谢陈不不大佬,在JS逆向之路上提供了不少帮助~
有兴趣的小伙伴们可以看看他在B站上发的视频,对JS逆向提升有一定的帮助~

我、陈不不、泰迪合作的星球:https://t.zsxq.com/06bIUvBEM

最后

以上就是落寞铃铛为你收集整理的【瑞数5】浅谈某普期刊JS逆向的环境检测点前言JS加载流程AST简单解混淆环境检测运行结果总结鸣谢的全部内容,希望文章能够帮你解决【瑞数5】浅谈某普期刊JS逆向的环境检测点前言JS加载流程AST简单解混淆环境检测运行结果总结鸣谢所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部