Skip to content

Latest commit

 

History

History
277 lines (187 loc) · 31.5 KB

js逆向案例-某rs5.md

File metadata and controls

277 lines (187 loc) · 31.5 KB

本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com

提示!本文章仅供学习交流,严禁用于非法用途,文章如有不当可联系本人删除!

一、rs5特点

① 关于4代的介绍可以看这篇文章,有些流程和4代是差不多的本文章就省略介绍了

② 服务器响应状态码202或者412返回第一个cookie_S(或者cookie_O);然后js混淆生成了第二个cookie_T(或者cookie_P),只有携带有效的cookie_T(或者cookie_P)才能正确请求页面状态码才是200

③ 如何区分是几代版本,看cookie_T(或者cookie_P)的第一个数字,绝大多数通过该数字就可以确定是几代;cookie_T(或者cookie_P),其区别含义P代表(https)、T代表(http)其实是区别协议的,常见的有:gOEoYMGvg36yT、neCYtZEjo8GmP、9CKCOkIaqzqET、DLjfPow8PDr4T;
图片

④ 加载vm的1万多行代码入口特性有3种,如图4代、旧版5代、新版5代,更多详细版本区分介绍看这篇文章
图片
图片
图片

二、cookie正式逻辑分析

① 开始大致是图片这么个流程,先定位到call,然后进入vm代码里面分析

已关注 关注 重播 分享 赞 切换到竖屏全屏 退出全屏 逆向OneByOne 已关注 分享 点赞 在看 已同步到看一看写下你的评论 分享视频 ,时长 00:20

0 / 0

00:00 / 00:20 切换到横屏模式 继续播放 原创 , js逆向案例-某rs5 逆向OneByOne 已关注 分享 点赞 在看 已同步到看一看写下你的评论 进度条,百分之0 播放 00:00/00:20 00:20 全屏

倍速播放中 0.5倍 0.75倍 1.0倍 1.5倍 2.0倍 超清 高清 流畅

继续观看

js逆向案例-某rs5

视频详情

② cookie生成起始位置,如搜索(772, 1

图片

③ cookie结束位置,如搜索'\\b'

图片

④ vm当中128位数组生成起始位置生成位置搜索(128)

图片

⑤ vm当中128位数组结束位置,结束位置搜索([]

图片

⑥ 以下流程你可以理解是带你单步调试扣代码的过程,vm思路扣代码分析前可以先看看这篇文章 ;cookie思路可以看本文档末尾推荐的一篇文章

1、先打上script断点再刷新网页,首先会先加载外链的js文件(暂且称之为version.js),此处可能稍卡等一会儿就好,并将js文件的内容赋值给全局变量$_ts这个对象
图片

2、继续跟着script断点走,会跳到源码的一段自执行函数js这里,暂且称之为main.js
图片

3、main.js执行到call的位置,只做了两件事:$_ts对象有了很多属性,version.js文件被解密成VM可执行的js代码,进入call函数对于已解密到vm的js代码,我们简称其为vm.js
图片
图片

4、接着通过hook_cookie + 堆栈回溯定位我们知道生成cookie的入口是vm代码里的_$6p(); ===》 _$co(772, 1) ===》 _$co(742, _$TI, false);这个位置,到742的控制流就开始生成cookie的逻辑了
图片
图片
图片

5、所以我们下次直接搜索(772, 1)去找cookie的入口生成逻辑(注意重点:从此刻开始你需要保存一份静态的文件用fiddler替换或者overrides替换开始静态分析,防止每次刷新函数变量名都是动态的不好分析,也不好扣)
图片
图片
图片

6、742控制流的第一步代码是跳到这里,首先生成了一个时间戳差值,在后面的128位数组里会转成8位数组push进去
图片

7、742控制流的第二步代码是跳到这里,将_$$d变量赋给了另一个变量_$$E,(中间的_$Wp变量只是用来判断改变控制流走哪个if ~else的,接下来好多流程都会用到类似的判断改变控制流方向,此处直接忽略)
图片
图片

8、742控制流的第三步代码是跳到这里,进入279的新的控制流,核心主逻辑在279控制流里
图片

9、279控制流第一步,先定义了一个局部变量如下
图片

10、279控制流第二步代码是跳到了这里 _$co(157);,是一些自动化工具特征检测(msCrypto、ActiveXObject、_Selenium_IDE_Recorder,_selenium,callSelenium)等,如果有的话,会有3个全局变量会被改变,默认不发生任何改变,所以这里不用进控制流调试了
图片

11、279控制流第三步代码是跳到了这里_$Sc(4, _$t2); 会有个全局变量会改变,在稍后的128位数组里会push进去,其中_$t2这个如果是true的话会改变25165824,默认undefined
图片
图片

图片

12、279控制流第四步代码是跳到了这里,生成了_$qC,一个128位空数组
图片

13、279控制流第五步代码是跳到了这里,非常重要,695的控制流将$_ts的5个值生成了20位数组,其中有4个值的顺序非常重要需要映射
图片
图片

14、695控制流第一步代码将$_ts的第一个值生成16位数组,第二步代码将16位数组和4个值连接起来
图片
图片

15、279控制流第六步代码是跳到了这里,对前面时间戳差值转成了8位数组
图片
图片

16、279控制流第七、八、九、十步代码是跳到了这里,_$qC128位空数组已经push了6个进去了
图片
图片
图片
图片
图片

17、279控制流第十一步,push了一个_$34的四位数组,这个4位数组是在初始化流程中取_$ts其中一个值生成的数组
图片
图片
图片

18、279控制流第十二、十三步,push了一个_$CL的八位数组,这个8位数组暂且可以写死;然后push了个0也先写死
图片
图片

19、279控制流第十四、十五、十六步,然后push了3代表是Chrome;然后push了一个8位数组(这里用到了一个_$bJ=25165824,如果前面selenium等被检测到了,这个值是会发生改变的);然后push了14固定值
图片
图片
图片
图片

20、279控制流第十八步,索引_$1g先占位,push了一个undefined,后面会有值覆盖这个undefined,目前_$qC128位数组已经push了13个了
图片
图片
图片

21、279控制流第十九步,_$co(58)这个控制流会返回与localStorage相关的值,如果有值的话,则会push一个20位数组,本次未push
图片
图片
图片

22、279控制流第二十步,_$co(247, _$_j[580]);这个控制流会返回localStorage["$_f0"]的值,如果有值的话,则会push一个20位数组,本次未push
图片

23、279控制流第二十一步,_$co(247, _$_j[154]);这个控制流会返回localStorage["$_fh0"]的值,如果有值的话,则会push一个20位数组,本次未push
图片

24、279控制流第二十二步,_$co(247, _$_j[636]);这个控制流会返回localStorage["$_f1"]的值,如果有值的话,则会push一个20位数组,本次未push
图片

25、279控制流第二十三步,_$Jk是网络状态对应的值NetworkInformation.type,本次返回是0,然后_$ty进行或运算
图片
图片
图片

图片

26、279控制流又来一波判断,返回localStorage相关值,一如既往的undefined,如果有值的话,则会push一个20位数组,本次未push
图片
图片
图片

27、279控制流第二十四步,push一个固定值4,是在初始化777的控制流生成的,然后_$ty进行或运算
图片
图片==》图片
图片
图片

28、279控制流第二十五步,_$ty进行或运算,然后push了一个'https:443'.length,然后同时将这个协议端口返回9位数组再次push
图片
图片
图片
图片

29、279控制流第二十五步,_$1g先占位的索引,在这里将多次或运算的_$ty给转成4位数组补上了,至此128位数组push完了,17位长度(localStorage有值的话会更长)
图片
图片
图片

30、279控制流第二十五步,保留截取128位数组前17位已经赋值的
图片
图片

31、279控制流第二十六步返回128位数组最终17位全部合并拼接的数组,至此279控制流对128位数组的操作结束,继续走742的控制流逻辑
图片

32、742控制流当时入279控制流的入口,生成的结果给了_$ty图片

33、742控制流第四步代码,生成了一个32位数组
图片

34、742控制流第五步代码,
图片

35、742控制流第六步代码,那个由17位合并的数组现在又连接了一个_$ts的值,计算出一个大数值,然后大数值再转成4位数组再连接到了17位合并的数组上
图片
图片
图片

36、742控制流第七步代码,对时间戳,时间戳差值进行了转数组操做,并转成了cookie的前缀字符串
图片
图片
图片
图片
图片
图片
图片

37、742控制流第八步代码,生成了cookie,将即 5 + 时间戳数组字符串 + (128位数组合并的 + 32位数组合并的)转成的数组字符串,至此742控制流已结束,回到772的控制流
图片

38、772控制流进入742控制流的入口,生成了_$$d即cookie
图片

39、772控制流接着把_$$d即cookie赋给了document.cookie,至此(772,1)控制流结束
图片
图片
图片

40、最后扣代码逻辑流程大概如下
图片

三、cookie生成后的操作

1、_$6p()函数执行生成cookie后,剩余2个函数然后给一些全局对象绑定函数,然后就返回到cookie到前面的main.js了图片
图片

2、其中_$6p()函数生成完cookie后,还给_$ts的属性绑定了一个函数;然后就是修改xhr对象了,如图xhr.open以被改成另一个函数;修改xhr对象后就是改Storage.$_nd值,这个参数在后缀生成可能用到
图片
图片
图片

四、后缀生成分析

1、后缀生成推荐先看看本文档末尾推荐的两篇文章,首先确定哪个请求以及什么后缀,如这里search请求,两个后缀参数,其实和4代后缀一样都是xhr.open被修改了函数
图片

已关注 关注 重播 分享 赞 切换到竖屏全屏 退出全屏 逆向OneByOne 已关注 分享 点赞 在看 已同步到看一看写下你的评论 分享视频 ,时长 02:20

0 / 0

00:00 / 02:20 切换到横屏模式 继续播放 原创 , js逆向案例-某rs5 逆向OneByOne 已关注 分享 点赞 在看 已同步到看一看写下你的评论 进度条,百分之0 播放 00:00/02:20 02:20 全屏

倍速播放中 0.5倍 0.75倍 1.0倍 1.5倍 2.0倍 超清 高清 流畅

继续观看

js逆向案例-某rs5

视频详情

2、在页面已经加载完成,打开控制台会跳出无限debugger,然后never pause here过掉无限debugger,然后xhr下断点,然后点击搜索按钮触发xhr请求,则会自动断到如下页面,然后开始分析
图片

3、_$9v函数是生成后缀的具体逻辑部分,先对url参数转数组,然后生成后缀hKHnQfLv,再然后生成后缀8X7Yi61c
图片

4、最后后缀逻辑流程大概如下
图片

五、本案例类似好文章分享

1、通过扣函数推荐以下篇文章

① Cookie思路详细分析:https://blog.csdn.net/qq_35491275/article/details/117390671?spm=1001.2014.3001.5501

② 后缀查找详细思路:https://blog.csdn.net/qq_35491275/article/details/117307069?spm=1001.2014.3001.5501

③ 后缀生成思路:https://blog.csdn.net/weixin_44772112/article/details/122507622?spm=1001.2014.3001.5502

④ VM代码加密流程分析

⑤ 指纹位置生成分析