瑞数4代JS逆向分析,如何改写为长尾词?
- 内容介绍
- 文章标签
- 相关推荐
本文共计4382个文字,预计阅读时间需要18分钟。
明确+原文章节内容仅提供学习交流使用,不用于其他目的,不提供完整代码,不包含敏感信息、敏感网址、数据接口等,严格禁止商业用途和非法用途。如不遵守,由此产生的后果由使用者自行承担。
声明本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号联系作者立即删除!
前言瑞数动态安全 Botgate(机器人防火墙)以“动态安全”技术为核心,通过动态封装、动态验证、动态混淆、动态令牌等技术对服务器网页底层代码持续动态变换,增加服务器行为的“不可预测性”,实现了从用户端到服务器端的全方位“主动防护”,为各类 Web、HTML5 提供强大的安全保护。
瑞数 Botgate 多用于政企、金融、运营商行业,曾一度被视为反爬天花板,随着近年来逆向大佬越来越多,相关的逆向文章也层出不穷,真正到了人均瑞数的时代了,这里也感谢诸如 Nanda、懒神等逆向大佬,揭开了瑞数神秘的面纱,总结的经验让后来人少走了不少弯路。
过瑞数的方法基本上有以下几种:自动化工具(要隐藏特征值)、RPC 远程调用、JS 逆向(硬扣代码和补环境),本文介绍的是 JS 逆向硬扣代码,尽可能多的介绍各种细节。
瑞数特征以及不同版本的区别对于绝大多数使用了瑞数的网站来说,有以下几点特征(可能有特殊版本不一样,先仅看主流的):
1、打开开发者工具(F12)会依次出现两个典型的无限 debugger:
2、瑞数的 JS 混淆代码中,变量、方法名大多类似于 _$xx,有众多的 if-else 控制流,新版瑞数还可能会有 jsvmp 以及众多三目表达式的情况:
3、看请求,会有典型的三次请求,首次请求响应码是 202(瑞数3、4代)或者 412(瑞数5代),接着单独请求一个 JS 文件,然后再重新请求页面,后续的其他 XHR 请求中,都带有一个后缀,这个后缀的值是由 JS 生成的,每次都会变化,后缀的值第一个数字为瑞数的版本,比如 MmEwMD=4xxxxx 就是4代瑞数,bX3Xf9nD=5xxxxx 就是5代瑞数:
4、看 Cookie,瑞数 3、4 代有以 T 和 S 结尾的两个 Cookie,其中以 S 开头的 Cookie 是第一次的 201 那个请求返回的,以 T 开头的 Cookie 是由 JS 生成的,动态变化的,T 和 S 前面一般会跟 80 或 443 的数字,Cookie 值第一个数字为瑞数的版本(为什么可以通过第一个数字来判断版本?难道相同版本第一个数字不会变吗?这些问题我们在分析 JS 的时候可以找到答案),比如:
FSSBBIl1UgzbN7N80T=37Na97B.nWX3....:数字 80 是 www.脱敏处理.com.cn/new_house/new_house_detail.html", "origin": "www.脱敏处理.com.cn", "protocol": "http:", "host": "www.脱敏处理.com.cn", "hostname": "www.脱敏处理.com.cn", "port": "", "pathname": "/new_house/new_house_detail.html", "search": "", "hash": "" } document = { "scripts": ["script", "script"] }观察
$_ts的 key 和 value,和浏览器中得到的是一样的:注意事项:
扣代码c.FxJzG50F.dfe1675.js外链 JS 如果你直接下载下来用编辑器打开可能会被自动编码,和原始数据有出入,导致运行报错,这里建议直接在浏览器在线访问这个文件,手动复制过来,或者在抓包软件里将响应内容复制过来,观察以下两种情况,第一种情况就可能会导致运行出错,第二种是正常的:前面说了这么多,现在终于可以进入主题了,那就是扣代码,找个好椅子,准备把屁股坐穿,此时你的键盘只有 F11 有用,不断单步调试,只需要亿点点细节,就完事儿了!
扣代码步骤太多,不可能每一步都截图写出来,只写一下比较重要的,如有遗漏的地方,那也没办法,首先先在我们替换的 202 页面里,自执行代码开始的地方手动加个 debugger,一进入页面就断下,方便后续的分析:
通过前面我们的分析,已经知道了入口在 call 的地方,快速搜索并下断点:
通过前面我们的分析,我们也知道了有两次生成 Cookie 的地方,快速搜索
假 Cookie 生成逻辑(5),搜索结果第二个即为入口:首先单步跟假 Cookie,虽然是假的,但是后续生成真 Cookie 中会用到,在跟的时候你会走到这个逻辑里面:
有一步会调用
_$8e()方法,而_$8e = _$Q9,_$Q9又嵌套在_$d0里的,搜索一下哪里调用了_$d0,发现是代码开头:那么传入的参数
_$Wn是啥呢?单步跟入,是一个方法,作用就是取 202 页面的 content 内容,那么我们在本地就直接删掉这个_$Wn方法,直接传入 content 的值即可,如下图所示:另外,我们发现,代码有非常多的在数组里面按索引取值的情况,比如上图中的
_$PV[68]的值,实际上就是字符串 content,很显然我们要把这个数组的来源找到,直接搜索_$PV =,可以找到疑似定义和赋值的地方:所以我们得看看这个
_$iL方法,传入了一个非常长的字符串,打断点进去看看,果然生成了_$PV,是一个 725 位的数组:接下来在扣代码的过程中,你会经常遇到一个变量,在本文中是
_$sX:有没有很熟悉?这个值就是我们前面拿到的
$_ts变量,在开头就可以看到是将window.$_ts赋值给了_$sX:继续走,会走到以下逻辑中:
这里会遇到六个数组,他们都已经有值了,所以我们得找到他们是咋来的,任意搜索其中一个数组名称,会找到定义和赋值的地方:
赋值明显是调用了
_$rv方法,再搜_$rv方法,发现是开头就调用了:后续没有什么特别的,一直单步,最后有个
join('')操作,就生成了假 Cookie:接下来是生成 Cookie 的名字
真 Cookie 生成逻辑FSSBBIl1UgzbN7N80T,然后将 Cookie 赋值给document.cookie,然后又向localStorage里面的$_ck赋了个值,localStorage的内容可以直接复制下来,没有太大影响。单步跟真 Cookie,在本文中也就是
_$ZN(768, 1);,可以看到开始进入了无穷无尽的if-else控制流:这里本地应该怎样处理呢?我的做法是以
取假 Cookie_$Hn和其值命名函数,function _$Hn768(){}就表示所有走 768 号控制流的方法,继续跟,生成真 Cookie 的方法基本上在 747 号控制流,后续我们主要以 747 号控制流的各个步骤来看,747 号控制流扣出来的代码大致如下:单步跟 747 号控制流,会有个进入第 709 号控制流的步骤,会取先前生成的假 Cookie,经过一系列操作之后返回一个数组:
至此我们在本地同步扣的代码,如果正常的话,返回的数组也应该是一样的(后续的数据就不一样了,有一些时间戳之类的参数参与运算):
自动化工具检测继续跟 747 号控制流,会进入 268 号控制流,接着进入 154 号控制流,这里面会针对自动化工具做一些检测,如下图所示:
这里定义了一个变量
20 位核心数组_$iL,检测不通过就是1,后续又把这个变量赋值给了_$aW,所以我们本地保持一致,也为 false 即可(其实我们不用自动化工具的话,这一段检测就不用管直接返回 false 就行):继续跟 268 号控制流,会进入 668 号控制流,668 号控制流就两个操作,一是生成一个 16 位数组,二是取
$_ts里面的 4 个变量,加到前面的 16 位后面,组成一个 20 位数组,这 20 位数组的最后 4 位是瑞数核心,其中的映射关系搞错了请求是通不过的,在五代中这部分的处理逻辑会更加复杂。这里不是单纯的取
$_ts里的键值对,你在扣代码的时候,你也许会发现怎么本地到这里取值的时候,取出来的不是数字,而是字符串呢?就像下面这种情况:实际上我们最开始得到的
$_ts值,是经过了二次处理的,我们以第一个_$sX._$Xb为例,直接搜索_$sX._$Xb,可以发现这么一个地方:很明显这里给
_$sX._$Xb重新赋值了一遍,我们可以看到等号右边,先取了一次_$sX._$Xb,其值为_$Rm,这和我们初始$_ts里面对应的值是一样的,然后我们就得再看看_$sX["_$Rm"]又是何方神圣,直接搜索发现是开头赋值了一个方法,通过调用这个方法来生成新的值:另外其他三个值也是同样的套路,赋值的代码分别为:
_$sX._$Xb = _$sX[_$sX._$Xb](_$BH, _$DP); _$sX._$oI = _$sX[_$sX._$oI](_$ZJ, _$DS) _$sX._$EN = _$sX[_$sX._$EN](); _$sX._$D9 = _$sX[_$sX._$D9](_$iL);实际上应该是:
_$sX._$Xb = _$sX["_$Rm"](_$BH, _$DP); _$sX._$oI = _$sX["_$Nw"](_$ZJ, _$DS) _$sX._$EN = _$sX["_$Uh"](); _$sX._$D9 = _$sX["_$ci"](_$iL);进一步来说,实际上是:
_$sX._$Xb = _$1k(_$BH, _$DP); _$sX._$oI = _$jH(_$ZJ, _$DS) _$sX._$EN = _$9M(); _$sX._$D9 = _$oL(_$iL);静态分析没问题,我们可以先固定下来,但是实际应用当中这些值都是动态的,那我们应该怎么处理呢?先来多看几个对比一下找找规律:
可以发现每次对应的位次都不一样,但是实际上相同位置的方法点进去都是一样的,也就是说,变的只有方法名和变量名,实现的逻辑是不变的,所以我们只要知道了这四个值分别对应的位置,就能够拿到正确的值,在本地,我们就可以这样做:
1、先利用正则匹配出这四个值,如:
[_$sX._$Xb, _$sX._$oI, _$sX._$EN, _$sX._$D9];2、再匹配出 VM 代码开头的 20 个赋值的语句,如:
_$sX._$RH = _$wI; _$sX._$i5 = _$n5;等;3、然后通过
$_ts取这四个值对应的值,相当于:_$sX._$Xb = _$ts._$Xb = _$Rm;然后再找这四个值所定义的方法在 20 个赋值语句中的位置,相当于:查找_$sX._$Rm = _$1k;在 20 个赋值语句中的位置为 7(索引从 0 开始)4、我们知道了这四个方法在 20 个赋值语句中的位置,那么我们直接匹配本地对应位置的名称,进行动态替换即可,当然前提是咱们本地已经扣了一套代码出来了:
经过这样处理后,就能够保证这四个值的准确性了。
其他用到 $_ts 值的地方除了上面说的 20 位数组里用到了 4 个
注意事项$_ts的值以外,还有其他地方有 7 个值也用到了,直接搜索就能定位,这 7 个值相对较简单,每次都是固定取$_ts里面的第 2、3、4、15、16、17、19 位的值,同样的,找到对应位置,进行动态替换即可:特别注意 VM 代码开头,会直接调用执行一些方法,某些变量的值就是通过这些方法生成的,当你一步一步跟的时候发现某些参数不对,或者没有,那么就得注意开头这些方法了,可能一开始就已经生成了。
后缀 MmEwMD 生成逻辑后续的其他 XHR 请求中,都带有一个后缀,这个后缀的值同样是由 JS 生成的,每次都会变化,当然不同网站,后缀名不一定都是一样的,本例中是
MmEwMD,先下一个 XHR 断点,当 XHR 请求中包含了MmEwMD=时就断下,然后刷新网页:可以看到后传入
l.open()的 URL 还是正常的,断下后到l.send()就带有后缀了,再看l.open()其实就是xhr.open(),明显和正常的有区别,同样这个方法也在 VM 代码里,应该是重写了方法,可以和正常的做对比:跟到 VM 代码里去看看,经过了
_$sd(arguments[1])方法就变成了带有后缀的完整链接了:跟进
善用 Watch 跟踪功能_$sd方法,前面都是对 url 做一些处理,后面有个进入第 779 号控制流的流程,实际上就是原来我们生成 Cookie 的步骤,跟一下就行了。开发者工具的 Watch 功能能够持续跟踪某个变量的值,对于这种控制流很多的情况,设置相应的变量跟踪,能够让你知道你现在处于哪个控制流中,以及生成的数组的变化,不至于跟着跟着不知道到哪一步了。
结果验证如果整个流程没问题,代码也扣得正确,携带正确的 Cookie 和正确的后缀,就能成功访问:
本文共计4382个文字,预计阅读时间需要18分钟。
明确+原文章节内容仅提供学习交流使用,不用于其他目的,不提供完整代码,不包含敏感信息、敏感网址、数据接口等,严格禁止商业用途和非法用途。如不遵守,由此产生的后果由使用者自行承担。
声明本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号联系作者立即删除!
前言瑞数动态安全 Botgate(机器人防火墙)以“动态安全”技术为核心,通过动态封装、动态验证、动态混淆、动态令牌等技术对服务器网页底层代码持续动态变换,增加服务器行为的“不可预测性”,实现了从用户端到服务器端的全方位“主动防护”,为各类 Web、HTML5 提供强大的安全保护。
瑞数 Botgate 多用于政企、金融、运营商行业,曾一度被视为反爬天花板,随着近年来逆向大佬越来越多,相关的逆向文章也层出不穷,真正到了人均瑞数的时代了,这里也感谢诸如 Nanda、懒神等逆向大佬,揭开了瑞数神秘的面纱,总结的经验让后来人少走了不少弯路。
过瑞数的方法基本上有以下几种:自动化工具(要隐藏特征值)、RPC 远程调用、JS 逆向(硬扣代码和补环境),本文介绍的是 JS 逆向硬扣代码,尽可能多的介绍各种细节。
瑞数特征以及不同版本的区别对于绝大多数使用了瑞数的网站来说,有以下几点特征(可能有特殊版本不一样,先仅看主流的):
1、打开开发者工具(F12)会依次出现两个典型的无限 debugger:
2、瑞数的 JS 混淆代码中,变量、方法名大多类似于 _$xx,有众多的 if-else 控制流,新版瑞数还可能会有 jsvmp 以及众多三目表达式的情况:
3、看请求,会有典型的三次请求,首次请求响应码是 202(瑞数3、4代)或者 412(瑞数5代),接着单独请求一个 JS 文件,然后再重新请求页面,后续的其他 XHR 请求中,都带有一个后缀,这个后缀的值是由 JS 生成的,每次都会变化,后缀的值第一个数字为瑞数的版本,比如 MmEwMD=4xxxxx 就是4代瑞数,bX3Xf9nD=5xxxxx 就是5代瑞数:
4、看 Cookie,瑞数 3、4 代有以 T 和 S 结尾的两个 Cookie,其中以 S 开头的 Cookie 是第一次的 201 那个请求返回的,以 T 开头的 Cookie 是由 JS 生成的,动态变化的,T 和 S 前面一般会跟 80 或 443 的数字,Cookie 值第一个数字为瑞数的版本(为什么可以通过第一个数字来判断版本?难道相同版本第一个数字不会变吗?这些问题我们在分析 JS 的时候可以找到答案),比如:
FSSBBIl1UgzbN7N80T=37Na97B.nWX3....:数字 80 是 www.脱敏处理.com.cn/new_house/new_house_detail.html", "origin": "www.脱敏处理.com.cn", "protocol": "http:", "host": "www.脱敏处理.com.cn", "hostname": "www.脱敏处理.com.cn", "port": "", "pathname": "/new_house/new_house_detail.html", "search": "", "hash": "" } document = { "scripts": ["script", "script"] }观察
$_ts的 key 和 value,和浏览器中得到的是一样的:注意事项:
扣代码c.FxJzG50F.dfe1675.js外链 JS 如果你直接下载下来用编辑器打开可能会被自动编码,和原始数据有出入,导致运行报错,这里建议直接在浏览器在线访问这个文件,手动复制过来,或者在抓包软件里将响应内容复制过来,观察以下两种情况,第一种情况就可能会导致运行出错,第二种是正常的:前面说了这么多,现在终于可以进入主题了,那就是扣代码,找个好椅子,准备把屁股坐穿,此时你的键盘只有 F11 有用,不断单步调试,只需要亿点点细节,就完事儿了!
扣代码步骤太多,不可能每一步都截图写出来,只写一下比较重要的,如有遗漏的地方,那也没办法,首先先在我们替换的 202 页面里,自执行代码开始的地方手动加个 debugger,一进入页面就断下,方便后续的分析:
通过前面我们的分析,已经知道了入口在 call 的地方,快速搜索并下断点:
通过前面我们的分析,我们也知道了有两次生成 Cookie 的地方,快速搜索
假 Cookie 生成逻辑(5),搜索结果第二个即为入口:首先单步跟假 Cookie,虽然是假的,但是后续生成真 Cookie 中会用到,在跟的时候你会走到这个逻辑里面:
有一步会调用
_$8e()方法,而_$8e = _$Q9,_$Q9又嵌套在_$d0里的,搜索一下哪里调用了_$d0,发现是代码开头:那么传入的参数
_$Wn是啥呢?单步跟入,是一个方法,作用就是取 202 页面的 content 内容,那么我们在本地就直接删掉这个_$Wn方法,直接传入 content 的值即可,如下图所示:另外,我们发现,代码有非常多的在数组里面按索引取值的情况,比如上图中的
_$PV[68]的值,实际上就是字符串 content,很显然我们要把这个数组的来源找到,直接搜索_$PV =,可以找到疑似定义和赋值的地方:所以我们得看看这个
_$iL方法,传入了一个非常长的字符串,打断点进去看看,果然生成了_$PV,是一个 725 位的数组:接下来在扣代码的过程中,你会经常遇到一个变量,在本文中是
_$sX:有没有很熟悉?这个值就是我们前面拿到的
$_ts变量,在开头就可以看到是将window.$_ts赋值给了_$sX:继续走,会走到以下逻辑中:
这里会遇到六个数组,他们都已经有值了,所以我们得找到他们是咋来的,任意搜索其中一个数组名称,会找到定义和赋值的地方:
赋值明显是调用了
_$rv方法,再搜_$rv方法,发现是开头就调用了:后续没有什么特别的,一直单步,最后有个
join('')操作,就生成了假 Cookie:接下来是生成 Cookie 的名字
真 Cookie 生成逻辑FSSBBIl1UgzbN7N80T,然后将 Cookie 赋值给document.cookie,然后又向localStorage里面的$_ck赋了个值,localStorage的内容可以直接复制下来,没有太大影响。单步跟真 Cookie,在本文中也就是
_$ZN(768, 1);,可以看到开始进入了无穷无尽的if-else控制流:这里本地应该怎样处理呢?我的做法是以
取假 Cookie_$Hn和其值命名函数,function _$Hn768(){}就表示所有走 768 号控制流的方法,继续跟,生成真 Cookie 的方法基本上在 747 号控制流,后续我们主要以 747 号控制流的各个步骤来看,747 号控制流扣出来的代码大致如下:单步跟 747 号控制流,会有个进入第 709 号控制流的步骤,会取先前生成的假 Cookie,经过一系列操作之后返回一个数组:
至此我们在本地同步扣的代码,如果正常的话,返回的数组也应该是一样的(后续的数据就不一样了,有一些时间戳之类的参数参与运算):
自动化工具检测继续跟 747 号控制流,会进入 268 号控制流,接着进入 154 号控制流,这里面会针对自动化工具做一些检测,如下图所示:
这里定义了一个变量
20 位核心数组_$iL,检测不通过就是1,后续又把这个变量赋值给了_$aW,所以我们本地保持一致,也为 false 即可(其实我们不用自动化工具的话,这一段检测就不用管直接返回 false 就行):继续跟 268 号控制流,会进入 668 号控制流,668 号控制流就两个操作,一是生成一个 16 位数组,二是取
$_ts里面的 4 个变量,加到前面的 16 位后面,组成一个 20 位数组,这 20 位数组的最后 4 位是瑞数核心,其中的映射关系搞错了请求是通不过的,在五代中这部分的处理逻辑会更加复杂。这里不是单纯的取
$_ts里的键值对,你在扣代码的时候,你也许会发现怎么本地到这里取值的时候,取出来的不是数字,而是字符串呢?就像下面这种情况:实际上我们最开始得到的
$_ts值,是经过了二次处理的,我们以第一个_$sX._$Xb为例,直接搜索_$sX._$Xb,可以发现这么一个地方:很明显这里给
_$sX._$Xb重新赋值了一遍,我们可以看到等号右边,先取了一次_$sX._$Xb,其值为_$Rm,这和我们初始$_ts里面对应的值是一样的,然后我们就得再看看_$sX["_$Rm"]又是何方神圣,直接搜索发现是开头赋值了一个方法,通过调用这个方法来生成新的值:另外其他三个值也是同样的套路,赋值的代码分别为:
_$sX._$Xb = _$sX[_$sX._$Xb](_$BH, _$DP); _$sX._$oI = _$sX[_$sX._$oI](_$ZJ, _$DS) _$sX._$EN = _$sX[_$sX._$EN](); _$sX._$D9 = _$sX[_$sX._$D9](_$iL);实际上应该是:
_$sX._$Xb = _$sX["_$Rm"](_$BH, _$DP); _$sX._$oI = _$sX["_$Nw"](_$ZJ, _$DS) _$sX._$EN = _$sX["_$Uh"](); _$sX._$D9 = _$sX["_$ci"](_$iL);进一步来说,实际上是:
_$sX._$Xb = _$1k(_$BH, _$DP); _$sX._$oI = _$jH(_$ZJ, _$DS) _$sX._$EN = _$9M(); _$sX._$D9 = _$oL(_$iL);静态分析没问题,我们可以先固定下来,但是实际应用当中这些值都是动态的,那我们应该怎么处理呢?先来多看几个对比一下找找规律:
可以发现每次对应的位次都不一样,但是实际上相同位置的方法点进去都是一样的,也就是说,变的只有方法名和变量名,实现的逻辑是不变的,所以我们只要知道了这四个值分别对应的位置,就能够拿到正确的值,在本地,我们就可以这样做:
1、先利用正则匹配出这四个值,如:
[_$sX._$Xb, _$sX._$oI, _$sX._$EN, _$sX._$D9];2、再匹配出 VM 代码开头的 20 个赋值的语句,如:
_$sX._$RH = _$wI; _$sX._$i5 = _$n5;等;3、然后通过
$_ts取这四个值对应的值,相当于:_$sX._$Xb = _$ts._$Xb = _$Rm;然后再找这四个值所定义的方法在 20 个赋值语句中的位置,相当于:查找_$sX._$Rm = _$1k;在 20 个赋值语句中的位置为 7(索引从 0 开始)4、我们知道了这四个方法在 20 个赋值语句中的位置,那么我们直接匹配本地对应位置的名称,进行动态替换即可,当然前提是咱们本地已经扣了一套代码出来了:
经过这样处理后,就能够保证这四个值的准确性了。
其他用到 $_ts 值的地方除了上面说的 20 位数组里用到了 4 个
注意事项$_ts的值以外,还有其他地方有 7 个值也用到了,直接搜索就能定位,这 7 个值相对较简单,每次都是固定取$_ts里面的第 2、3、4、15、16、17、19 位的值,同样的,找到对应位置,进行动态替换即可:特别注意 VM 代码开头,会直接调用执行一些方法,某些变量的值就是通过这些方法生成的,当你一步一步跟的时候发现某些参数不对,或者没有,那么就得注意开头这些方法了,可能一开始就已经生成了。
后缀 MmEwMD 生成逻辑后续的其他 XHR 请求中,都带有一个后缀,这个后缀的值同样是由 JS 生成的,每次都会变化,当然不同网站,后缀名不一定都是一样的,本例中是
MmEwMD,先下一个 XHR 断点,当 XHR 请求中包含了MmEwMD=时就断下,然后刷新网页:可以看到后传入
l.open()的 URL 还是正常的,断下后到l.send()就带有后缀了,再看l.open()其实就是xhr.open(),明显和正常的有区别,同样这个方法也在 VM 代码里,应该是重写了方法,可以和正常的做对比:跟到 VM 代码里去看看,经过了
_$sd(arguments[1])方法就变成了带有后缀的完整链接了:跟进
善用 Watch 跟踪功能_$sd方法,前面都是对 url 做一些处理,后面有个进入第 779 号控制流的流程,实际上就是原来我们生成 Cookie 的步骤,跟一下就行了。开发者工具的 Watch 功能能够持续跟踪某个变量的值,对于这种控制流很多的情况,设置相应的变量跟踪,能够让你知道你现在处于哪个控制流中,以及生成的数组的变化,不至于跟着跟着不知道到哪一步了。
结果验证如果整个流程没问题,代码也扣得正确,携带正确的 Cookie 和正确的后缀,就能成功访问:

