miboy 发表于 2020-9-22 08:45

03-有道翻译JS分析

本帖最后由 miboy 于 2020-9-22 09:45 编辑

本案例为初级JS解密
本案例仅供学习交流


在页面搜索“你好”,出现搜索结果:“hello”

https://ae05.alicdn.com/kf/Ha2e25b45a35f44598a7d2090caf58dd8k.png

页面发送了POST请求:
https://ae01.alicdn.com/kf/H577e9bbb5cca4aafaf907f9de2af6962H.png

其中看不懂的参数有:sign和bv,Its和salt看起来像13位时间戳,salt比Its多了一位,暂时不知道是什么。
全局搜索sign,查看是否有加密入口。共有15处关键词,其中有一处最为可疑,在此下个断点观察一下。
https://ae02.alicdn.com/kf/H40313710981b4ce0b3891d2326953bf1F.png

另外,由于页面发送Ajax请求也是从这里开始的(因为url是和抓到的一致),所以也在这里下个断点。
https://ae03.alicdn.com/kf/H676e03d0a3b747d4abf85794a62191caa.png


此时在翻译中查询“再见”,源代码中成功在ajax请求处触发断点。
https://ae04.alicdn.com/kf/Hbb929e53333241dba4230728481db0e4q.png

观察到,此时请求数据包中data:e 其实已经有加密过的数据了(bv和sign都已经加密过了)。因此我们需要向上查找入口。从右侧调用堆栈中依次向下寻找入口。

https://ae04.alicdn.com/kf/H54411fd3c51244f1969d7f4c4efc9701L.png
找到了这里,下个断点,再来一次上述流程。
https://ae05.alicdn.com/kf/H38f18b3cd4794df0a2763eddd0a00169F.png
发现数据再次断下,通过函数generateSaltSign,传入n,即待翻译的文字:你好返回给变量r。接下来进入函数generateSaltSign,看看它是如何加密的。
https://ae04.alicdn.com/kf/H907a70156eb94ba490b90f9b7b5546e1t.png

从下往上看参数ts="" + (new Date).getTime()
参数bv=n.md5(navigator.appVersion)navigator.appVersion="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4260.0 Safari/537.36 Edg/87.0.637.0"
参数salt=ts + parseInt(10 * Math.random(), 10)
参数sign=n.md5("fanyideskweb" + 你好 + salt + "]BjuETDhU)zqSxf-=B#7m")
翻译一下:参数ts=当前时间戳参数bv=浏览器版本的MD5加密参数salt=时间戳+随机一个0~9的数字参数sign=fanyideskweb" + 待翻译字 + salt + "]BjuETDhU)zqSxf-=B#7m
我们验证下结果,如何验证?同浏览器抓包的参数来对比验证。由于是MD5加密,不存在加密后变化。ts由于是时间戳,这个不需要考虑,先来看看bv。将我的浏览器版本进行MD5加密结果:

https://ae01.alicdn.com/kf/Haaae0be0ac804102b42e11c240d82615w.png
再来看看sign,都是没问题的。

https://ae02.alicdn.com/kf/H2a71a80d327b4b19b75e3a2591871ee4m.png
使用python仿写

https://ae05.alicdn.com/kf/H84a0ef35c8f34053aa44880faf0edcbcl.png

https://ae04.alicdn.com/kf/H3c4d29a342574295b3e6e5eccea4fa1cB.png

附Python文件

麦迪就是帅 发表于 2020-9-22 08:51

不错哦!感谢分享!!

461735945 发表于 2020-9-22 09:00

不错,不错,支持

ghy197674 发表于 2020-9-22 09:00

感谢分享!

BLUE-SKY 发表于 2020-9-22 09:01

不错哦!感谢分享!!

whitehack 发表于 2020-9-22 09:37

为啥图片在转圈...

ycuvuuui1L 发表于 2020-9-22 10:05

思路非常清晰,不错

寒疫 发表于 2020-9-22 10:54

分享的很好,可以很有精神

大侠在路上 发表于 2020-9-22 14:01

感谢楼主分享,学习了。

mikeee 发表于 2020-9-22 14:25

本帖最后由 mikeee 于 2020-9-22 14:51 编辑


```python
"""
https://www.52pojie.cn/thread-1272004-1-1.html
"""

import requests
import time
import random
import hashlib
from urllib import parse

USERAGENT = "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4260.0 Safari/537.36 Edg/87.0.637.0"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4260.0 Safari/537.36 Edg/87.0.637.0",
    "Referer": "http://fanyi.youdao.com/",
    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
}
# 此处的cookies是第一次访问http://fanyi.youdao.com/获得
# 如果访问失败,尝试重新获取cookie
cookies = {
    # "OUTFOX_SEARCH_USER_ID": "1816945418@10.169.0.83"
    "OUTFOX_SEARCH_USER_ID": "-1545285618@10.169.0.83"
}

sess = requests.session()
sess.get('http://fanyi.youdao.com/')
# cookies = dict(sess.cookies.items())
# cookies = sess.cookies

DATA_KEY = "i={keyword}&from=AUTO&to=AUTO&smartresult=dict&client=fanyideskweb&salt={salt}&sign={sign}<s={lts}&bv={bv}&doctype=json&version=2.1&keyfrom=fanyi.web&action=FY_BY_REALTlME"
SIGN_KEY = "fanyideskweb{keyword}{salt}]BjuETDhU)zqSxf-=B#7m"


def get_md5(value):
    md5 = hashlib.md5()
    md5.update(value.encode('utf-8'))
    md5_digest = md5.hexdigest()
    return md5_digest


def get_result(keyword):
    # 获取13位时间戳
    time_stamp = str(int(time.time()))
    lts = time_stamp
    salt = lts + str(random.randint(0, 9))
    # 获取sign和bv的md5加密值
    sign = get_md5(SIGN_KEY.format(keyword=keyword, salt=salt))
    bv = get_md5(USERAGENT)
    # 发起请求
    url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
    data = DATA_KEY.format(keyword=parse.quote(keyword), salt=salt, sign=sign, lts=lts, bv=bv)

    # response = requests.post(url=url, data=data, headers=headers, cookies=cookies)
    response = sess.post(url=url, data=data, headers=headers)

    if response.status_code == 200:
      json_dict = response.json()
      try:
            return json_dict.get("translateResult").get("tgt", None)
      except Exception as e:
            return json_dict
    else:
      return None


if __name__ == '__main__':
    print(get_result("你今天都做了什么"))
```

感谢无私分享

改成了用 requests.Session() 自动获取 cookies。好像可行。
页: [1] 2
查看完整版本: 03-有道翻译JS分析