记一个下午的美团官网的js逆向

您所在的位置:网站首页 逆向工程应用实例有哪些 记一个下午的美团官网的js逆向

记一个下午的美团官网的js逆向

2023-04-14 12:14| 来源: 网络整理| 查看: 265

首先什么是JS逆向?以下是来自ChatGPT的回答

JavaScript 逆向工程是一种通过对 JavaScript 代码进行分析和破解的技术,来了解和修改网站或应用程序的行为和功能的过程。

综上,个人理解就是查看网页的js源代码,分析出某些有价值的代码并提取出他们一部分来,从而实现想要的功能,例如美团的js逆向就是分析出当我们以正常的途径去登陆美团官网去查看某个地区的美食信息。首先正常的方式是先进行网站的登录,然后再去查看相关的美食信息。此次的js逆向就是分析我们在访问美食版块时会向服务器发送哪些请求,会携带哪些参数,会携带cookie吗,返回的信息是否有加密吗?

第一步抓包分析请求及返回内容

抓包截图

对网络请求逐个查看他的响应发现第5个网络请求的响应正好有在页面上显示的信息,且没有加密

观察下请求这个板块时,我们的请求参数都有哪些

这就是请求接口所携带的参数,其中最引人注意的就是_token,他仿佛是加密的某种信息,其他的请求参数可暂时不用理会,ps: uuid是标注了计算机中的系统信息,他的值可以直接复制使用。当我们想爬取相关信息的时候首先要搞懂这个_token是怎么来的,这样我们才能得到正确且有效的请求参数。

在该页面全局查找_token这个值

查找的结果显示在index.js的文件夹下有这个_token的这个值选中这个文件夹,让它在来源面板中打开。

在来源的这个页面查找这个_token 在js代码中的位置

发现是 window.Rohr_Opt.reload(reqUrlAndParams)这个方法把一个reqUrlAndParams的参数加工成了token,所以先看看这个reqUrlAndParams参数是什么。

发现它是把请求链接加上请求头的信息以某种格式的拼接连接在一起。

那么有一个假设就是我们可以使用这个链接,去修改某个拼接的值那就可以获得信息了,在同一浏览器的环境下,前提是在美团官网登录的前提下是可以的。

但是一旦关闭浏览器之后便不可以获取到数据了,在python中也是一样的,或者说换一浏览器去访问,返回的信息也是未登录的信息。

猜测下那就是说当我们在浏览器的环境下访问这个接口的时候,携带了某些信息,可能是cookie也有可能是token一旦离开了这个环境的话那么再去访问这个接口的时候就没有了这些登录的信息。

这种行为通常是由于网站应用程序的身份验证/会话管理方式所导致的。当你在浏览器中登录到网站时,网站通常会创建一个会话并为你分配一个会话ID。该ID存储在浏览器的cookie中或者在请求参数中作为一个标识符,以便网站能够识别并验证你的身份。

如果你在一个窗口中登录并创建了一个会话,然后在另一个窗口中打开该网站,你可以访问该网站的资源,因为你的浏览器已经在该网站上创建了一个有效的会话。但是,当你再打开一个新窗口并尝试访问该网站时,可能会出现问题,因为网站的会话管理策略可能会限制每个用户只能有一个会话或会话的数量。在这种情况下,当你尝试创建第三个会话时,网站可能会拒绝你的请求或者将你之前的会话终止,从而导致你需要重新登录才能访问该网站。

解决这个问题的一种方法是在一个窗口中打开多个选项卡而不是多个窗口,这样你只有一个会话,因此可以避免会话冲突。

那么这是不是也可以使用selenium去获取信息,使用selenium创建一个浏览器,然后手动登录,在这个浏览器的基础上新建窗口修改请求链接可以获得相关的信息。

要想使用python脚本来获取信息那就需要搞懂这个_token 是怎么来的,而且在脚本中在发起请求的时候带上它。

进入那个加工_token的那个方法。

这便是这个方法的全部面貌,我们需要注意这个jw的赋值的情况

首先这个jw就是上面那个请求的链接

判断传入的参数jv是不是string类型的,若是string类型的就把这个字符串按照?进行分割

接着进入了iJ这个方法

在这把上面分割好的字符串转化json对象之后

对json中的key进行了排序

然后便利这个json对象,把他们的kv以=进行了拼接

在这个方法的后面又把jd传入iI函数

初看这个方法是把iJ那个方法拼接好的字符串进行了某种的压缩

其关键字deflate,在JavaScript中,deflate是一种常见的数据压缩算法,用于将数据压缩成较小的大小以节省存储空间和传输时间。通常情况下,deflate算法会将输入数据转换成二进制格式,然后使用一系列算法对其进行压缩,最终生成压缩后的数据。

在实际开发中,可以使用多种JavaScript库和框架来实现deflate算法,例如zlib、pako等。这些库提供了各种deflate算法的实现方式,可以用来压缩和解压缩数据。

接下来又进入到iD方法中。

函数实现了一种Base64编码算法,将输入的字符串"cC"进行编码,并返回编码后的结果。

在函数中,首先定义了三个局部变量:"iH"、"dY"和"bs"。"iH"用于存储编码后的结果,"dY"用于记录当前处理的字符在3个字符块中的位置,"bs"则是输入字符串的长度。

接下来,函数使用一个循环遍历输入字符串的每一个字符,对每一个字符进行Base64编码。在处理每一个字符之前,函数会先将"dY"的值加1,并检查是否达到了3。如果"dY"等于3,说明当前已经处理了3个字符,可以开始编码了。

在js中的iF和iE

iF() 和 iE() 函数都是 Base64 编码算法的一部分,它们分别用于将数值转换为 Base64 码表示的字符和将字符串中指定位置的字符转换为 Unicode 编码值。

iE(s, i) 函数将字符串 s 中位置为 i 的字符转换为 Unicode 编码值。它首先判断 i 的值是否小于 0 或大于等于字符串的长度,如果是,则返回 0;否则,返回字符串中位置为 i 的字符的 Unicode 编码值。

举个🌰

这是说把 abcd 这个字符串中第3个字符进行Unicode编码,会发现编码的结果是100,这和ASCII编码好像是一样的,以下是来自ChatGPT的解释。

ASCII 码表中的字母和 Unicode 中的字母在它们的编码范围内,其编码值是相同的,例如 ASCII 码表中的字母 a 的编码值是 97,而 Unicode 中的字母 a 也是 97。因此,在这个意义上说,它们的字母编码码值是相同的。

然而,Unicode 编码比 ASCII 编码更为广泛,可以表示更多的字符,包括各种语言的字母、符号、表情符号、数学符号等等,而 ASCII 编码只能表示 128 种字符。Unicode 编码和 ASCII 编码的编码范围和字符集是不同的。所以在表示非 ASCII 字符时,Unicode 编码的编码值与 ASCII 编码的编码值就不同了

如果"dY"等于0,则需要编码两个字符。编码的方法是将前两个字符的组合按照规定进行转换,然后将转换后的结果添加到"iH"数组中。具体转换规则可以参考Base64编码的定义。

如果"dY"等于1,则需要编码一个字符。编码的方法是将当前字符的前两位转换成Base64码,并将转换后的结果添加到"iH"数组中。

如果"dY"等于2,则需要编码一个字符。编码的方法是将前一个字符和当前字符的前四位组合起来按照规定进行转换,然后将转换后的结果添加到"iH"数组中。

最后,如果当前处理的字符是输入字符串的最后一个字符,并且"dY"的值大于0,则说明需要补充相应数量的Base64填充符号。填充符号的具体形式也可以参考Base64编码的定义。

最后,函数将"iH"数组中的所有元素拼接成一个字符串,并将其返回作为编码结果。

到目前为止我们的方法是从 Ip.reload()➡️iJ➡️iI➡️iD

一系列的把我们最开始的请求参数加工处理完成后给IP的sign属性赋值

处理后的结果

在赋值完成之后,又对iP中的cts属性又设定了当时的时间戳,这便导致了在初始化创建iP对象的时候对cts的赋值进行了覆盖

重新赋值cts时间戳,接着再把iP进行同请求链接相同方式进行加密压缩,最后把iP加密完成后的信息返回作为请求头的_token 使用。

这便是处理请求链接的载荷中的_token 中的流程,我们要想逆向出相同处理逻辑的_token,那就要仿照上面的步骤来在自己的脚本中实现。

复现部分

在访问这个接口时携带的参数有,以上这些除了_token 之外都可以拿来直接复制使用用来加工后面的_token 

userId就是当正常登录之后的账号,uuid是系统自己生成的,在此不必深究他是怎么来的。

接下来就是截取上面的代码块,生成_token,便于我们在爬虫系统中模拟浏览器访问的请求。

在这个过程中我们可以借助一个第三方的工具 https://curlconverter.com/,生成cookies和headers

复制cURL信息在工具中粘贴

这就生成了访问接口的cookies和headers,在程序中直接使用便可,但是当从网站上退出账号的时候cookie也就失效了,再次登录的时候需要重新替换程序中cookie的值便可。

这个是访问接口使用的python文件,我们还需要截取的代码片段组成一个js文件

需要注意的是原js代码中的有些变量是采用的数组变量

在提取代码块的时候要把他们变成对应的值,具体的值可以在控制台中把它们打印出来

🌰

在代码中替换它们即可,上面分析流程的代码都要截取下来,在这过程中会有一个方法会报错。

他是一个压缩算法在 JavaScript 中,可以使用 zlib 库来实现 deflate 算法。zlib 库提供了多种压缩和解压缩函数,在js代码中需要我们自己手动引入zlib库来使用它的方法来进行压缩。

首先导入 zlib 库。然后,使用 JSON.stringify 方法将 jc 对象序列化为 JSON 字符串。最后,使用 zlib.deflateSync 方法对 JSON 字符串进行压缩,可替换源代码中的deflate方法,其他的js代码片段就都截取下来,控制台显示的出错信息缺啥就去原js代码中寻找它复制下来,要注意代码中的某些变量和方法显示未定义的时候要去原js代码中找到,并去控制台打印他的值,在代码中进行替换即可。

最后需要自己写一个方法用于传入请求参数

至此,js代码块补充完成,外部访问参数设置好之后js文件就设置好了。

接下来,我们需要使用 Python 模拟执行 JavaScript,这里我们使用的库叫做 PyExecJS

一些用到的三方库

file是同级目录下的js文件,执行js文件,并且使用其中的test_1的方法也就是上面,我们在js文件中留的外部访问的接口,传入参数,这里的参数也就是访问的链接那些信息,其中包括链接,页面之类的信息,如下图所示。

在把这些信息传入js脚本后,返回的便是_token的值,在请求链接之前要把这个token的值加入请求参数中。

这样便可以正常访问了。

访问的结果,一页上的信息只有15条,把数据进行整理,便可提取出有效的信息了。

本文仅供学习交流使用(未含有代码),不做任何商业或者非法用途。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3