python 简单js逆向之网易有道翻译

前言

这篇文章主要是讲一下简单的js逆向,包括分析过程与具体实施,这里以网易有道翻译为例,因为是我自己的笔记,所以比较低级。


分析过程

①打开网易有道翻译,并将开发者工具打开,选择网络

②选择Fetch/XHR

因为翻译的功能就是你把想要翻译的内容写上去,然后翻译网站再根据你写的内容返回结果,所以,很显然是AJAX异步传输的。

③使用翻译功能,获取AJAX异步传输的数据

可以看见多了一个链接,这就是我们想要的东西

④点开这个链接,找到想要的信息

url地址与请求头信息就不多说了,需要注意的是请求方式,这里用的post请求,既然是post请求,那么大概率需要在发起请求时添加参数

选择负载

表单数据那一部分就是我们所需要的,很显然这里面有一大部分的参数我们都不认识,那怎么办呢

⑤再次使用翻译功能,拿到另一组表单数据,对比一下

 就简单的对比一下,发现只有isaltsignlts这四个参数变了,其他的没有变,所以这么多参数里,我们需要关注的就是这四个,一下子工作量就少了不少。

i: dog                                          i: cat
from: AUTO                                      from: AUTO
to: AUTO                                        to: AUTO
smartresult: dict                               smartresult: dict
client: fanyideskweb                            client: fanyideskweb
salt: 16535704897543                            salt: 16535706770648
sign: 661ffcb66b7a5ca424797e338d7cf3ab          sign: 285c2aaac6d1a5b178dc91e6ff342000
lts: 1653570489754                             lts: 1653570677064
bv: 83432c74f0e40df76f477f4084335cd4            bv: 83432c74f0e40df76f477f4084335cd4
doctype: json                                   doctype: json
version: 2.1                                    version: 2.1
keyfrom: fanyi.web                              keyfrom: fanyi.web
action: FY_BY_REALTlME                          action: FY_BY_REALTlME

再仔细观察一下,i其实就是我们输入的内容,lts是一串数字,salt则是在lts的基础上又加了一位,sign最复杂,因为看不懂。

那么我们就准备破解吧


破解过程

①先从最简单的开始,复制lts,进行搜索

 可以看见lts在三个文件中出现了

第一个文件是jquery、第二个是自己写的js文件,第三个是跟样式有关的css文件,很显然我们要点击第二个文件

②点击js文件,继续查找lts

刚开始的时候,所以的内容都挤在一行,我们点击左下角的{}进行展开

 在第十个匹配项处,找到了与表单非常类似的内容

 分析一下,i对应的变量是n,而后面的都与一个叫r的变量或者对象有关

i: n,
salt: r.salt,
sign: r.sign,
lts: r.ts,

那么找到这个r很重要

③继续寻找,需要找到r

 这一步其实是非常枯燥乏味的,你有很多种方式,比如直接找r,但我运气不错

 注意看,这里有个函数赋值给了一个变量r,巧了的是这个函数的返回值恰巧有saltsignts

还需要注意一下我绿色箭头所指向的地区,恰巧就是这两个参数是怎么形成的

④分析参数是怎么形成的

r = "" + (new Date).getTime()
i = r + parseInt(10 * Math.random(), 10);

ts: r,
salt: i,
sign: n.md5("fanyideskweb" + e + i + "Ygy_4c=r#e#4EX^NUGUc5")

 r等于一个空字符串+一个方法的放回值,这个方法其实挺好判断的,根据方法名称就知道这是跟日期与时间相关的,而我们最后看到的lts是一串很长的字符串,那么这个方法会不会是返回当前时间的时间戳呢?另外就是这个方法看起来很像内置方法,我们去查一下JavaScript中有没有这个方法就好了。不做太多的赘述了,这个r就是""+当前时间的时间戳

i等于r+上一个方法的返回值,由于我们之前已经判断出来了salt比lts多了一位,很显然+号后面的方法只会是一位数字。另外这个也很眼熟,就是随机数,而且是[0,10)之间的随机整数。

至于sign嘛,这里有个东西叫md5,如果有所了解的其实也不难,其实sign就是将md5()括号里面的内容进行加密,而括号里面的内容一共分为4部分,分别是两个字符串,这个不用管,因为从某种程度上来讲,这两个字符串是静态的,万年不变的;另外两个变量分别是eii我们已经分析出来了,就差e了。

那么e是什么呢,这一步其实比较难,这个e我没有找到,最终尝试了一下断点调试,找到了

在这个位置点一下,打一个断点

再点击翻译,重新使用翻译功能

原来e就是我们输入的内容,也就是i。至此,所以的参数都已经找全了,尝试写代码


代码实现

①使用python获取当前时间的时间戳,模拟参数lts

import time
# 需要特别注意一下,表单那边获取的时间戳是13位的整数,使用python获取当前时间的时间戳时需要处理一下
lts = '' + str(int(time.time() * 1000))

 ②使用python实现随机数,模拟参数salt

import random

salt = lts + str(random.randint(0, 9))

 ③使用python实现md5加密,模拟参数sign

import time

sign_str = "fanyideskweb" + word + salt + "Ygy_4c=r#e#4EX^NUGUc5"
hl = hashlib.md5()
hl.update(sign_str.encode(encoding='utf-8'))
sign = hl.hexdigest()

至此所以参数都通过python创造出来了。

import hashlib
import random
import time

import requests

url = 'https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'

headers = {
	'Accept': 'application/json, text/javascript, */*; q=0.01',
	'Accept-Encoding': 'gzip, deflate, br',
	'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
	'Connection': 'keep-alive',
	'Content-Length': '237',
	'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
	'Cookie': 'OUTFOX_SEARCH_USER_ID=-105199357@10.110.96.154; OUTFOX_SEARCH_USER_ID_NCOO=553583338.8237487; fanyi-ad-id=305838; fanyi-ad-closed=1; ___rl__test__cookies=1653534055544',
	'Host': 'fanyi.youdao.com',
	'Origin': 'https://fanyi.youdao.com',
	'Referer': 'https://fanyi.youdao.com/',
	'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="101", "Microsoft Edge";v="101"',
	'sec-ch-ua-mobile': '?0',
	'sec-ch-ua-platform': '"Windows"',
	'Sec-Fetch-Dest': 'empty',
	'Sec-Fetch-Mode': 'cors',
	'Sec-Fetch-Site': 'same-origin',
	'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53',
	'X-Requested-With': 'XMLHttpRequest',
}


def get_youdaofanyi(url, headers, word, lts, salt, sign):
	data = {
		'i': word,
		'from': 'AUTO',
		'to': 'AUTO',
		'smartresult': 'dict',
		'client': 'fanyideskweb',
		'salt': salt,
		'sign': sign,
		'lts': lts,
		'bv': '83432c74f0e40df76f477f4084335cd4',
		'doctype': 'json',
		'version': '2.1',
		'keyfrom': 'fanyi.web',
		'action': 'FY_BY_REALTlME',
	}
	response = requests.post(url=url, headers=headers, data=data)
	print(response.json())


if __name__ == '__main__':
	word = input("请输入要翻译的内容:")

	# 模拟参数lts
	lts = '' + str(int(time.time() * 1000))
	# 模拟参数salt
	salt = lts + str(random.randint(0, 9))
	# 模拟参数sign
	sign_str = "fanyideskweb" + word + salt + "Ygy_4c=r#e#4EX^NUGUc5"
	hl = hashlib.md5()
	hl.update(sign_str.encode(encoding='utf-8'))
	sign = hl.hexdigest()

	get_youdaofanyi(url=url, headers=headers, word=word, lts=lts, salt=salt, sign=sign)

成功!


尾声

如果这篇文章对您有所帮助,那么这篇文章就有意义!


感谢您的观看!

posted @ 2022-05-26 21:37  Flower_and_you  阅读(149)  评论(0编辑  收藏  举报