最新yd翻译webtranslate接口分析
摘要:本文详细介绍了如何分析某翻译的webtranslate自动翻译接口,并通过Python实现自动翻译。作者从接口分析、获取密钥、算法还原三个方面展开,揭示了请求参数加密合返回的数据解密,包括AES加密、解密,MD5摘要算法等基础关键技术。
【作者主页】:js进阶之路
【作者介绍】:一位刚接触JS逆向的入门级选手,希望通过分享js逆向文章一起交流,学习,进步,并找到一份属于自己的写代码工作。
1.写在前面
某翻译难度属于入门级,就用这个开启我的csdn第一篇生涯,希望在今后的工作学习中一起变强。
分析目标:
aHR0cHM6Ly9mYW55aS55b3VkYW8uY29tL2luZGV4Lmh0bWw/a2V5ZnJvbT1iYWlkdXZpcGRjIy9UZXh0VHJhbnNsYXRl
2.接口分析
yd接口也是很好找的,找到自动翻译接口如下图所示,是一个POST请求。
找一下请求头和请求体发现sign参数和mystieTime参数每次请求都会发生变化,如下图所示:
还有返回的数据也是加密的如下图所示:
3.请求体加密参数分析
找到了接口,和加密的参数,现在就去找加密的位置,看是如何生成参数的,首先我们还是用关键词搜索,这样如果运气好的话可以节省很多时间,在本文中先搜索关键字如sign和mystieTime,发现结果很多,不好确认加密位置,就转换思路搜索URL中的webtranslate试一下,结果就找到了两处加密位置,都打上断点,如下图所示:
接下来发包找到真的加密位置如下图所示,其实加密位置上面的接口返回的key,在MD5摘要中用到,aesKey,aesIv是解密数据的AES算法的key和iv,这里先透露一下,感兴趣的可以看一下这个接口。
找到k(t),如下图所示,sign就是这里生成的
t参数经过对比是固定的,就是前面接口返回的key,如下图所示
点进去k函数,发现a参数如下图所示,对比发现就是13位时间戳,e参数就是上面提到的key。
继续点进去S函数,如下图所示:
发现是一个MD5摘要,现在看一下是否标准算法,对下面的参数进行MD5摘要算法对比网站生成的。
_("client=fanyideskweb&mysticTime=1744455111770&product=webfanyi&key=Vy4EQ1uwPkUoqvcP1nIu6WiAjxFeA3Y3")
网站生成如下图所示:
自己代码生成如下图所示:
对比发现一致,是没有魔改的算法。到现在就可以还原sign参数了
4.返回数据解密分析
其实在上面这个接口https://dict.youdao.com/webtranslate/key返回的数据就是AES加密的key和iv,
如下图所示:
直接在全局搜索aes-找到数据返回解密的位置,额外提一嘴,这是Pronise嵌套Pronise结构。如下图所示:
到这里,yd逆向分析就结束了,这个b64不是标准的要替换一下,加一个参数altchars=b'-_'就好了,
这个AES是不是标准的,写一下代码发个包,测试一下就知道了,完整代码如下所示:
import requests import time from Crypto.Cipher import AES import base64 from Crypto.Util.Padding import unpad from hashlib import md5 import json session = requests.session() word = input("请输入要翻译的内容(自动检测):") mysticTime = str(int(time.time() * 1000)) s = f'client=fanyideskweb&mysticTime={mysticTime}&product=webfanyi&key=Vy4EQ1uwPkUoqvcP1nIu6WiAjxFeA3Y3' m = md5() m.update(s.encode()) sign = m.hexdigest() res = session.post("https://dict.youdao.com/webtranslate", data={ "i": 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": mysticTime, "keyfrom": "fanyi.web", "mid": "1", "screen": "1", "model": "1", "network": "wifi", "abtest": "0", "yduuid": "abcdefg", }, headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded", # 有没有没事 "Cookie": "UM_distinctid=189344f97c60-00175e127a49bd-26031d51-151800-189344f97c7edd; OUTFOX_SEARCH_USER_ID=-1211510370@10.112.57.88; OUTFOX_SEARCH_USER_ID_NCOO=39233718.02811328", "Referer": "https://fanyi.youdao.com/" } ) s = res.text encrypt_data= base64.b64decode(s.encode(), altchars=b'-_') # 解密数据 def get_md5(s): m = md5() m.update(s.encode()) return m.digest() key_str = 'ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl' iv_str = 'ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4' key = get_md5(key_str) iv = get_md5(iv_str) aes = AES.new(key,AES.MODE_CBC,iv) decrypt_data = aes.decrypt(encrypt_data) decrypt_data = unpad(decrypt_data, 16) #去除填充字节数据 jsonShuJu = decrypt_data.decode() dataDict = json.loads(jsonShuJu) print(dataDict)
5.总结
yd算是js逆向入门级,下一篇兄弟们想一起学什么,评论区可以留言,点个关注,一起学习逆向,欢迎大佬评论,指出不到之处,虚心学习。