python 简单js逆向之网易有道翻译
前言
这篇文章主要是讲一下简单的js逆向,包括分析过程与具体实施,这里以网易有道翻译为例,因为是我自己的笔记,所以比较低级。
分析过程
①打开网易有道翻译,并将开发者工具打开,选择网络
②选择Fetch/XHR
因为翻译的功能就是你把想要翻译的内容写上去,然后翻译网站再根据你写的内容返回结果,所以,很显然是AJAX异步传输的。
③使用翻译功能,获取AJAX异步传输的数据
可以看见多了一个链接,这就是我们想要的东西
④点开这个链接,找到想要的信息
url地址与请求头信息就不多说了,需要注意的是请求方式,这里用的post请求,既然是post请求,那么大概率需要在发起请求时添加参数
选择负载
表单数据那一部分就是我们所需要的,很显然这里面有一大部分的参数我们都不认识,那怎么办呢
⑤再次使用翻译功能,拿到另一组表单数据,对比一下
就简单的对比一下,发现只有i、salt、sign、lts这四个参数变了,其他的没有变,所以这么多参数里,我们需要关注的就是这四个,一下子工作量就少了不少。
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,巧了的是这个函数的返回值恰巧有salt、sign、ts
还需要注意一下我绿色箭头所指向的地区,恰巧就是这两个参数是怎么形成的
④分析参数是怎么形成的
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部分,分别是两个字符串,这个不用管,因为从某种程度上来讲,这两个字符串是静态的,万年不变的;另外两个变量分别是e和i,i我们已经分析出来了,就差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)
成功!
尾声
如果这篇文章对您有所帮助,那么这篇文章就有意义!
感谢您的观看!