上一篇我们破解了百度翻译的sign参数,今天我们来破解有道翻译结果的请求加密参数。由于之前写过几篇基础的js逆向分析文章,并且逆向过程写的非常详细,所以从这篇文章起以后的逆向分析只会写关键部分,如果大家对逆向的细节不熟可以看看之前的文章。
加密分析
通过抓包分析发现翻译结果在一个ajax请求中,该请求是post请求,需要提交几个加密参数:
通过
XHR/fetch Breakpoints
来调试,我们可以查看这些参数是如何产生的:可以看到有一些参数的值是固定字符串,其中
salt
、sign
、ts
和bv
这几个参数是需要我们去破解,其他几个参数虽然有的不是固定的,但是它是由js事件执行的结果,我们也可以通过调试发现这些参数的意思,至于我们需要破解的那几个参数,我们可以发现它调用了r函数
,我们找到r函数
接着分析:通过调试
r函数
很容易发现加密算法,ts
就是时间戳,bv
就是对UA请求头进行MD5加密后的结果,salt
就是时间戳加上一个0-10以内的随机数再乘以10,sign
就是两个特定的字符串和要翻译的词以及salt
组合然后再通过MD5加密后的结果。
破解代码
知道加密逻辑我们可以用python把加密逻辑实现,MD5加密我们可以用hashlib库,时间戳我们可以用time模块,随机数整数可以用random模块。至于用js执行库方式破解就没有必要了,需要的话可以看以前的文章。
import time, hashlib, random, requests
# 请求头的UA
ua = "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36"
# 要翻译的词
word = "程序员"
# 实例化MD5算法
md5 = hashlib.md5()
# 对ua进行MD5加密
md5.update(ua.encode('utf-8'))
# bv的值
bv = md5.hexdigest()
# 13位时间戳需要乘以1000
ts = int(time.time()*1000)
salt = int((ts + random.random())*10)
md5.update(("fanyideskweb" + word + str(salt) + "n%A-rKaT5fb[Gy?;N5@Tj").encode('utf-8'))
sign = md5.hexdigest()
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
headers = {
'accept': "application/json, text/javascript, */*; q=0.01",
'accept-encoding': "gzip, deflate",
'accept-language': "zh-CN,zh;q=0.9",
'content-type': "application/x-www-form-urlencoded",
'host': "fanyi.youdao.com",
'origin': "http://fanyi.youdao.com",
'proxy-connection': "keep-alive",
'referer': "http://fanyi.youdao.com",
'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
'x-requested-with': "XMLHttpRequest",
'cookie': 'OUTFOX_SEARCH_USER_ID_NCOO=112293474.88458891; OUTFOX_SEARCH_USER_ID="-1292669460@10.108.160.17"; ___rl__test__cookies=1571623355849'
}
formdata = {
"i": word,
"from":"AUTO",
"to":"AUTO",
"smartresult":"dict",
"client":"fanyideskweb",
"salt":salt,
"sign":sign,
"ts":ts,
"bv":bv,
"doctype":"json",
"version":"2.1",
"keyfrom":"fanyi.web",
"action":"FY_BY_CLICKBUTTION",
}
response = requests.post(url,headers=headers,data=formdata)
print(response.text)