js逆向——有道翻译
大家好啊,今天给大家分享一下自己逆向有道翻译的一个思路,如有不足,望各位大佬指出。其实在之前我也搞过,只不过后来好像更新了,现在的返回结果变为了一堆密文。话不多说,先分析一波。
首先要得到返回数据,就得请求对应的API,https://dict.youdao.com/webtranslate,但是,请求所需要携带的一些参数是加密的,如下:
经过对比发现,只有sign和mystictime是变化的,而mystictime很明显是一个时间戳。现在就只需要找到sign的加密位置。sign有32位,估计是MD5加密,到底是不是,还得打断点调试一下。
可以直接全局搜索sign:,加一个冒号可能好搜一点。搜索返回的结果比较少就美滋滋,多的话就每个sign都打上断点,点击翻译看看停在哪里。如果实在是太多了,就采用跟栈的方法,准确无误。
慢慢的,我们找到了sign的位置
t是个时间戳,方法就是(new Date).getTime()。e是个固定值"fsdsogkndfokasodnaso",b函数传入了t和e后就生成了sign,进入b函数,发现就在上面。而r和i这两个参数也是固定的。并且b函数里面有调用了一个p函数,进入p函数,原来p函数也在上面。这p函数太熟悉了啊,标准的MD5加密啊。
直接上代码:
这是用js实现的,然后用python调用js代码。
const crypto=require('crypto')
function p(e) {
return crypto.createHash("md5").update(e.toString()).digest("hex")
}
const time = (new Date).getTime()
function sign(e, t) {
return p(`client=${"fanyideskweb"}&mysticTime=${time}&product=${"webfanyi"}&key=${"fsdsogkndfokasodnaso"}`)
}
console.log(sign("fsdsogkndfokasodnaso"))
这是用python实现的,hashlib库中提供了MD5加密。
import hashlib import time localtime=str(int(time.time() * 1000)) data="client=fanyideskweb&mysticTime={}&product=webfanyi&key=fsdsogkndfokasodnaso".format(localtime) sign=hashlib.md5(data.encode(encoding='utf-8')).hexdigest() print(sign)
用哪种就看自己喜欢哪种了。这里有一个小坑,就是mysticTime本应传入时间戳,但实际上传入的是e,也就是“fsdsogkndfokasodnaso”,这两个玩意儿被交换了位置,所以自己写代码的时候要换回来。
OK,现在就是带上参数去发送请求,看看能不能拿到密文数据,
import requests import hashlib import time localtime = str(int(time.time() * 1000)) data = "client=fanyideskweb&mysticTime={}&product=webfanyi&key=fsdsogkndfokasodnaso".format(localtime) sign = hashlib.md5(data.encode(encoding='utf-8')).hexdigest()#python中的MD5 加密 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", "Referer": "https://fanyi.youdao.com/index.html" } cookies = { "OUTFOX_SEARCH_USER_ID": "-2094880112@10.108.162.135", "OUTFOX_SEARCH_USER_ID_NCOO": "86107500.53660281" } url = "https://dict.youdao.com/webtranslate" word = input('请输入翻译内容:') data = { "i": f"{word}", "from": "auto", "to": "", "dictResult": "true", "keyid": "webfanyi", "sign": sign, "client": "fanyideskweb", "product": "webfanyi", "appVersion": "1.0.0", "vendor": "web", "pointParam": "client,mysticTime,product", "mysticTime": localtime, "keyfrom": "fanyi.web" } response = requests.post(url=url, headers=headers, cookies=cookies, data=data).text print(response)
输入明天,成功拿到密文数据,接下来就是关键了。
我们用跟栈的方法看密文在哪里出现的和在哪里发生了变化。
一步一步往下跟,最先调用的函数放在最下面,我们只需要跟到明文出现的那一刻就行了。
很好,密文出现了,点击下一步,翻译结果出现,就是s。
接下来就是直接吧这段代码扣下来放到js文件中去执行。其实看到了c.a.createDecipheriv,就可以用node中内置的加密库crypto库去执行,当然也可以硬扣,就是有点费时间,而且还可能出现各种报错。
所以推荐使用加密库,方便又快捷。
然后m是MD5,好说好说,老朋友了。然后js代码如下:
const crypto=require('crypto') const o = 'ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl'; const n = 'ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4'; function datas(t){ const a = Buffer.alloc(16, crypto.createHash('md5').update(o).digest()) , r = Buffer.alloc(16, crypto.createHash('md5').update(n).digest()) , i = crypto.createDecipheriv("aes-128-cbc", a, r); let s = i.update(t, "base64", "utf-8"); return s += i.final("utf-8"), s } text='密文' console.log(datas(text))
然后我用的是execjs去执行js代码
import execjs with open('有道.js', 'r', encoding='utf-8') as po:#这里的有道.js就是自己创建的js文件的名字 text='Z21kD9ZK1ke6ugku2ccWu4n6eLnvoDT0YgGi0y3g-v0B9sYqg8L9D6UERNozYOHqpoAAdSA1hl_k4I9pMTqc5JX4Ren9M7iRcoedwRQwTkurrW9DnCngsfWNeaQq1NQfwSgSrBq4tpgfFLrbf0GigxPIvDZmCdTeHMx2L5988Ncib4kxvjXjlaYx5a9TnBQ0hgQVgDehw714FYb7ZFbFI4ovMNFdUgrs4XwosQL2zvIGG-gy1WGpSHZG-Pas6_0O7MJrYEGfRFfC_xwvlhgM4Rd4JhTrHDPC5yJyo5PRQwIRDBmLdqU8TjsZ73XwjUdx9yBCfi3u_9IoAVuwuxS2oehjAjMP9KzwwG3OfAJUEmGnr5qt-lQ-hgMeGa3B12Msd6UkVJLjT0auMo8p-xahxnANyvWoHDO9use3bWzT4QkDVWjnoVs8L922m7hpO7IiUXdtMAnyA4uV-Oacs-T8GIrkm76JWmQU-__Mm89llzbQsN2zWLir_iG4ek43gZ4TPWghhqMkaAJFReEgjIJ8u1N6trOfcA7EEC_ZyyY6X6PLlviWfz2TB1hdRFr57DsxyPq4RYzXJ13pPlrc54ZtY2y7q2_rKIBcrSa1UsS-Ma66gIyC3G_pYVO4gfy3wHXpbg0qWFO_ObU_E13BtA-QDj9hFrvgIEZMOX0Sy1jgLrDHFVICNoxCzzvPFiEcjNQfXaldgqAESW6EiRRYqIG_KzKtRhJGzACigZI2-Y9RbbM=' signs = execjs.compile(po.read()).call('datas', text) print(signs)
不知道什么原因,结果老是报错,查了许久百度后解决了问题,修改后的代码如下:
import subprocess from functools import partial subprocess.Popen = partial(subprocess.Popen, encoding='utf-8') import execjs with open('有道.js', 'r', encoding='utf-8') as po: text='Z21kD9ZK1ke6ugku2ccWu4n6eLnvoDT0YgGi0y3g-v0B9sYqg8L9D6UERNozYOHqpoAAdSA1hl_k4I9pMTqc5JX4Ren9M7iRcoedwRQwTkurrW9DnCngsfWNeaQq1NQfwSgSrBq4tpgfFLrbf0GigxPIvDZmCdTeHMx2L5988Ncib4kxvjXjlaYx5a9TnBQ0hgQVgDehw714FYb7ZFbFI4ovMNFdUgrs4XwosQL2zvIGG-gy1WGpSHZG-Pas6_0O7MJrYEGfRFfC_xwvlhgM4Rd4JhTrHDPC5yJyo5PRQwIRDBmLdqU8TjsZ73XwjUdx9yBCfi3u_9IoAVuwuxS2oehjAjMP9KzwwG3OfAJUEmGnr5qt-lQ-hgMeGa3B12Msd6UkVJLjT0auMo8p-xahxnANyvWoHDO9use3bWzT4QkDVWjnoVs8L922m7hpO7IiUXdtMAnyA4uV-Oacs-T8GIrkm76JWmQU-__Mm89llzbQsN2zWLir_iG4ek43gZ4TPWghhqMkaAJFReEgjIJ8u1N6trOfcA7EEC_ZyyY6X6PLlviWfz2TB1hdRFr57DsxyPq4RYzXJ13pPlrc54ZtY2y7q2_rKIBcrSa1UsS-Ma66gIyC3G_pYVO4gfy3wHXpbg0qWFO_ObU_E13BtA-QDj9hFrvgIEZMOX0Sy1jgLrDHFVICNoxCzzvPFiEcjNQfXaldgqAESW6EiRRYqIG_KzKtRhJGzACigZI2-Y9RbbM=' signs = execjs.compile(po.read()).call('datas', text) print(signs)
成功拿到结果。
完整代码:
import requests import subprocess import json from functools import partial import hashlib import time subprocess.Popen = partial(subprocess.Popen, encoding='utf-8') import execjs localtime=str(int(time.time() * 1000)) data="client=fanyideskweb&mysticTime={}&product=webfanyi&key=fsdsogkndfokasodnaso".format(localtime) sign=hashlib.md5(data.encode(encoding='utf-8')).hexdigest() headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", "Referer": "https://fanyi.youdao.com/index.html" } cookies = { "OUTFOX_SEARCH_USER_ID": "-2094880112@10.108.162.135", "OUTFOX_SEARCH_USER_ID_NCOO": "86107500.53660281" } url = "https://dict.youdao.com/webtranslate" word = input('请输入翻译内容:') data = { "i": f"{word}", "from": "auto", "to": "", "dictResult": "true", "keyid": "webfanyi", "sign": sign, "client": "fanyideskweb", "product": "webfanyi", "appVersion": "1.0.0", "vendor": "web", "pointParam": "client,mysticTime,product", "mysticTime": localtime, "keyfrom": "fanyi.web" } response = requests.post(url=url, headers=headers, cookies=cookies, data=data).text with open('有道.js', 'r', encoding='utf-8') as po: signs = execjs.compile(po.read()).call('datas', response) text = json.loads(signs) try: print(text['dictResult']['ce']['word']['trs'][0]['#text']) except: print(text['translateResult'][0][0]['tgt'])
好了,关于有道翻译的逆向到这里也结束了,逆向是一个循序渐进的过程,需要耐心,有时候突然出现的报错都要查好久的资料。但是,坚持就对了。