【2023最新教程】超详细!!!有道翻译js逆向
前言
有道翻译两个加密
第一个是表单的sign 用MD5加密
可以点击目录的 加密字段实现 直接跳转
第二个是返回值AES加密,而且AES的密匙他还用md5加密了一下
可以点击目录的 函数实现解密返回值 直接跳转
一 表单sign字段加密
确定加密字段
表单根据多次请求发现 sign这个字段不断变化,所以是加密了
mysticTime一看就是时间戳,不管他
破解加密字段
在右上角点击搜索
输入sign:
要加英文的冒号,这样结果更精准
可以看到有4个文件含有sign
接着我们打开 发起程序
可以看到app这个文件也是程序发起之一,而且都是排在前面 ,很可疑 ,直接从他开始一个一个查找
可以看到,这段代码可疑,很多字段表单中都有,打个断点测试一下
记得打两个断点,开始一个断点,结束一个断点
因为这样可以直接运行到这段代码的结束位置,这样就可以查看中间的值,不至于直接跳出断点
很明显,K(o,e)返回的值就是 sign,这里直接运行退出去看下是不是
很明显,就是他 ,一模一样,所以我们直接找到 k函数就行
点击跳转
看着这里,已经非常明显了,
k(o,e) 函数解读
o 是时间戳
e是一个固定的字符串
k函数的作用 就是组成一个 除了时间戳 不一样,其他都一样的字符串
然后交给 j函数 进行MD5加密
digest(‘hex’)的意思就是返回16进制的值
最后返回的结果,就是 sign的值
加密字段实现
我们直接上实战
先把md5加密写出函数
我们先使用之前的时间戳,看看和表单上的是否一样
看的出来,我们sign值就破解成功了
直接写成函数装进请求头中
这五个请求头都是要的
import time
import requests
import hashlib # 导入hash库函数
# 时间戳
ti = str(int(time.time() * 1000))
def sign():
str_md5 = f'client=fanyideskweb&mysticTime={str(ti)}&product=webfanyi&key=fsdsogkndfokasodnaso'
sign = hashlib.md5(str_md5.encode("utf-8")).hexdigest()
return sign
headers = {
"Origin": "https://fanyi.youdao.com",
"Referer": "https://fanyi.youdao.com/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.61",
'Host':'dict.youdao.com',
'cookie':'OUTFOX_SEARCH_USER_ID=-2034389685@10.110.96.157; OUTFOX_SEARCH_USER_ID_NCOO=1994625046.2245197',
}
url = "https://dict.youdao.com/webtranslate"
data = {
"i": '狗' ,
"from": "auto",
"to": "",
"domain": "0",
"dictResult": "true",
"keyid": "webfanyi",
"sign":sign(),
"client": "fanyideskweb",
"product": "webfanyi",
"appVersion": "1.0.0",
"vendor": "web",
"pointParam": "client,mysticTime,product",
"mysticTime": str(ti),
"keyfrom": "fanyi.web",
"mid": "1",
"screen": "1",
"model": "1",
"network": "wifi",
"abtest": "0",
"yduuid": "abcdefg"
}
response = requests.post(url, headers=headers,data=data )
print(response)
print(response.text)
看的出来,我们确实请求成功,并且返回了值,但是,这个值加密了
二 返回值AES解密
跟踪堆栈
首先呢,还是先打上断点,在sign那里
运行到最后一步就可以开始跟踪了,我们点击调用堆栈,现在是E, 我们往下点 ,点击 I
看的出来,调用sign值的时候先调用的这里,所以调用完sign后会往下执行, 所以 我们接着往下打断点
在return的地方打断点,因为都是返回值
打完断点后继续往后运行
可以看到t的值,这不就是加密后的返回值吗
我们直接从头开始打断点,精准点
断点之后继续查看
可以确定t是加密后的值
s就是解密后的值
找到解密后的返回值
我们在回过头好好看看这段代码
我们仔细看过之后也是很明显了,这是一个AES加密 CBC模式
先把密匙和偏移量进行md5加密 digest()是返回二进制的值
然后在进行解密就行,而且我看密匙 和 偏移量都是固定的值
使用全局搜索 ,可以看到就是固定的值,所以这段也不用扣js代码
函数实现解密返回值
def result(text_AES):
# 偏移量
decodeiv = "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4"
# 秘钥
decodekey = "ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl"
# 先把密匙和偏移量进行md5加密 digest()是返回二进制的值
key = hashlib.md5(decodekey.encode(encoding='utf-8')).digest()
iv = hashlib.md5(decodeiv.encode(encoding='utf-8')).digest()
# AES解密 CBC模式解密
aes_en = AES.new(key, AES.MODE_CBC, iv)
# 将已经加密的数据放进该方法
data_new = base64.urlsafe_b64decode(text_AES)
# 参数准备完毕后,进行解密
result = aes_en.decrypt(data_new).decode('utf-8')
return result
先使用网页上返回的数据进行测试
可以看到,没有问题
语言转换
我们搜索 zh-CHS,可以看到我们想要转换的语言 代码 code可以转换
我们提取出来就行
太多语言了,我这里就简单选几个,并且写出函数
接下来合并代码
三 完整代码
import base64
import time
from Crypto.Cipher import AES
import requests
import hashlib
ti = str(int(time.time() * 1000))
# sign值加密
def sign():
str_md5 = f'client=fanyideskweb&mysticTime={str(ti)}&product=webfanyi&key=fsdsogkndfokasodnaso'
sign = hashlib.md5(str_md5.encode("utf-8")).hexdigest()
return sign
# 返回值解密
def result(text_AES):
# 偏移量
decodeiv = "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4"
# 秘钥
decodekey = "ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl"
# 先把密匙和偏移量进行md5加密 digest()是返回二进制的值
key = hashlib.md5(decodekey.encode(encoding='utf-8')).digest()
iv = hashlib.md5(decodeiv.encode(encoding='utf-8')).digest()
# AES解密 CBC模式解密
aes_en = AES.new(key, AES.MODE_CBC, iv)
# 将已经加密的数据放进该方法
data_new = base64.urlsafe_b64decode(text_AES)
# 参数准备完毕后,进行解密
result = aes_en.decrypt(data_new).decode('utf-8')
return result
headers = {
"Origin": "https://fanyi.youdao.com",
"Referer": "https://fanyi.youdao.com/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.61",
'Host':'dict.youdao.com',
'cookie':'OUTFOX_SEARCH_USER_ID=-2034389685@10.110.96.157; OUTFOX_SEARCH_USER_ID_NCOO=1994625046.2245197',
}
# 语言字典
dic_code = {0: '自动识别', 'code0': 'auto', 1: '阿拉伯文', 'code1': 'ar', 2: '冰岛文', 'code2': 'is', 3: '波兰文', 'code3': 'pl', 4: '德文', 'code4': 'de', 5: '俄文', 'code5': 'ru', 6: '法文', 'code6': 'fr', 7: '芬兰文', 'code7': 'fi', 8: '弗里西文', 'code8': 'fy', 9: '菲律宾文', 'code9': 'tl', 10: '韩文', 'code10': 'ko', 11: '荷兰文', 'code11': 'nl', 12: '蒙古文', 'code12': 'mn', 13: '缅甸文', 'code13': 'my', 14: '尼泊尔文', 'code14': 'ne', 15: '挪威文', 'code15': 'no', 16: '葡萄牙文', 'code16': 'pt', 17: '日文', 'code17': 'ja', 18: '瑞典文', 'code18': 'sv', 19: '世界文', 'code19': 'eo', 20: '土耳其文', 'code20': 'tr', 21: '乌克兰文', 'code21': 'uk', 22: '西班牙文', 'code22': 'es', 23: '希腊文', 'code23': 'el', 24: '夏威夷文', 'code24': 'haw', 25: '英文', 'code25': 'en', 26: '意大利文', 'code26': 'it', 27: '中文', 'code27': 'zh-CHS'}
# 获取输入语言
def get_from():
print('选择数字,输入为什么语言:')
# 判断是否报错
try:
from_data = int(input(f'{dic_code}:'))
code_from = dic_code.get(f"code{from_data}")
if code_from == None:
get_from()
print(f'输入为{dic_code.get(from_data)}')
return code_from
# 报错函数回调
except:
get_from()
# 翻译成语言
def get_to():
print('选择数字,翻译成什么语言:')
try:
from_data = int(input(f'{dic_code}:'))
code_from = dic_code.get(f"code{from_data}")
if code_from == None:
get_from()
print(f'翻译为为{dic_code.get(from_data)}')
return code_from
except:
get_from()
get_from1 = get_from()
# 判断是不是选择了自动选择
if get_from1 == 'auto':
to = ''
else:
to = get_to()
word = input('请输入语句')
data = {
"i": word ,
"from": str(get_from1),
"to": str(to),
"domain": "0",
"dictResult": "true",
"keyid": "webfanyi",
"sign":sign(),
"client": "fanyideskweb",
"product": "webfanyi",
"appVersion": "1.0.0",
"vendor": "web",
"pointParam": "client,mysticTime,product",
"mysticTime": str(ti),
"keyfrom": "fanyi.web",
"mid": "1",
"screen": "1",
"model": "1",
"network": "wifi",
"abtest": "0",
"yduuid": "abcdefg"
}
url = "https://dict.youdao.com/webtranslate"
response = requests.post(url, headers=headers,data=data )
print(response)
print(response.text)
result1 = result(response.text)
print(result1)
四 效果展示
教程有什么不明白的地方,欢迎评论