JS逆向
JS逆向简要介绍案例:模拟百度翻译请求
检查百度翻译请求
首先,对百度翻译的请求进行了检查。通过分析发现,百度翻译使用的是POST
请求方法。在翻译过程中的请求载荷内容进行了详细观察。
请求参数分析
在请求的脚本参数中,发现了from
和to
字段。通过模拟操作,可以推断出这些参数代表着翻译的源语言和目标语言,例如从中文翻译到英文。进一步观察表单数据,可以看到请求所携带的所有参数。
请求头
对于请求的表头参数也进行了检查,以便在模拟请求时能够更准确地伪装。
Sign参数
首先ctrl
+shift
+f
全局搜索sign
参数所在源代码
一个个查看这些sign
参数,对符合js模式的进行断点
重新执行翻译过程,可以发现断点停留在sign: b(e)
,即js方法调用处
在控制台输入参数可以看到sign
的值
跳转这个调用到其源代码
Python代码实现
爬虫代码
1 | import time |
以上代码首先导入了必要的模块,设置了请求的URL和头部信息。通过用户输入获取翻译内容,然后使用jsdata
模块来生成签名。随后构建表单数据,包括语言类型、查询词、时间戳等,并发送POST请求。最后,从返回的JSON数据中提取并打印翻译结果。
信息
"ts": str(int(time.time()*1000))
用于生成一个时间戳,这个时间戳是表单数据(form_data)的一部分,发送给百度翻译的服务器。下面详细解释这个时间戳的生成过程:
time.time()
: 这个函数来自Python的time
模块,用于获取当前时间。它返回的是一个浮点数,代表自1970年1月1日(称为Unix纪元或Epoch时间)以来的秒数。time.time() * 1000
: 由于time.time()
返回的是秒数,而通常服务器端需要的时间戳是以毫秒为单位的。因此,将其乘以1000,将秒转换成毫秒。int(...)
: 这个函数将浮点数转换为整数。在这里,它将乘以1000后的结果转换成整数形式,因为时间戳通常是整数形式的毫秒值。str(...)
: 最后,int
类型的时间戳被转换成字符串(str
),因为在构建表单数据时,需要的是字符串形式的时间戳。
综合来看,"ts": str(int(time.time()*1000))
这一行代码生成了一个表示当前时间的毫秒级时间戳,并将其转换为字符串格式,以便作为HTTP请求的一部分发送。
JS逆向代码
1 | function n(t, e) { |
对复制过来的调用JavaScript源代码进行适配修改:
- 去掉
t.exports
属性,不需要赋值,重新命名函数为test_JS_re_code
n
函数
这个函数对给定的整数t
和字符串e
进行一系列位操作。
t
: 初始整数值。e
: 用于操作的字符串,其字符用于决定如何变换t
。- 函数通过遍历字符串
e
并根据其字符执行位移和位异或操作来转换t
。 - 最后,返回转换后的整数
t
。
test_JS_re_code
函数
这个函数是主要的函数,用于生成百度翻译的sign
值。
t
: 要翻译的文本。gtk
: 百度翻译API的一个关键变量,用于生成签名的固定密钥之一。
这个函数的工作流程大致如下:
- 处理输入文本: 如果文本过长或包含特殊字符(比如表情符号),它会被适当地截断或转换。
- 字符编码处理: 文本
t
中的每个字符被转换为其ASCII或Unicode编码。 - 生成初始值: 通过某些固定字符和可能是密钥
gtk
的变量r
组合,生成一个初始整数值b
。 - 迭代处理: 对上一步得到的整数值
b
和文本的每个字符编码进行迭代处理,使用n
函数和特定的字符串(在变量w
和k
中定义)进行变换。 - 生成最终
sign
值: 最终的b
值经过一系列操作后,与gtk
的某个部分进行操作,生成最终的sign
值。
执行测试代码
1 | import execjs |
- 导入了
execjs
模块,这个模块允许Python运行JavaScript代码。 - 定义了一个名为
make_js_data
的函数,这个函数接受一个参数que
,这个参数是用户想要翻译的文本。 - 这段代码从
translate.js
文件中读取JavaScript代码。translate.js
包含了先前分析的那段JavaScript代码(包括n
函数和test_JS_re_code
函数)。execjs.compile
方法编译这段JavaScript代码,使其可以在Python环境中执行。 - 通过
execjs
对象的call
方法调用translate.js
中的test_JS_re_code
函数,传入要翻译的文本que
作为参数,生成并返回sign
值。 - 函数返回计算得到的
sign
值。
注意
gtk
和token
的实际值通常是动态生成的,可能会随着百度翻译网站的更新而变化。在实际应用中,这些值需要从网站的某些部分(如JavaScript代码或隐藏的表单字段)中动态获取。- 硬编码的值只用于示例和概念验证。如果要实现一个可靠和长期有效的解决方案,就需要实现一个方法来动态获取这些值。
- 使用硬编码的值可能会导致在百度翻译更新其验证机制后,代码无法正常工作。
gtk
: 这通常是一个固定的字符串,用于生成翻译请求中的sign
参数。sign
参数是基于要翻译的文本和gtk
值计算得出的,用于验证请求的合法性。token
: 这是另一个重要的验证参数,通常也是在发送翻译请求时必须包含的。它可能用于识别用户或会话,或者作为另一层的安全验证。gtk
为'320305.131321201'
,token
为2977c992c92eb0731d89f23d17b6edd7
- 标题: JS逆向
- 作者: Yiuhang Chan
- 创建于 : 2022-01-08 18:12:46
- 更新于 : 2024-02-28 18:35:10
- 链接: https://www.yiuhangblog.com/2022/01/08/20220108JS逆向/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论