前言

现在一些网站对 JavaScript 代码采取了一定的保护措施,比如变量名混淆、执行逻辑混淆、反调试、核心逻辑加密等,有的还对数据接口进行了加密,这次的案例就是对一种 MD5 加密方式的破解。

MD5 对数据进行有损压缩,结果不可逆无法还原,不能算为加密算法,是摘要算法,不论数据有多长,都会生成固定的 128 位的散列值,但是可以检测数据是否被篡改,因为只要改动了任何一个 bit 的数据,摘要结果都会不一样。

案例目标

网址:aHR0cHM6Ly9mYW55aS55b3VkYW8uY29tLw==

翻译接口:aHR0cHM6Ly9mYW55aS55b3VkYW8uY29tL3RyYW5zbGF0ZV9vP3NtYXJ0cmVzdWx0PWRpY3Qmc21hcnRyZXN1bHQ9cnVsZQ==

以上均做了脱敏处理,Base64 编码及解码方式:

import base64
# 编码
# result = base64.b64encode('待编码字符串'.encode('utf-8'))
# 解码
result = base64.b64decode('待解码字符串'.encode('utf-8'))
print(result)

常规做法直接访问接口,会显示 errorCode 50,证明网站存在一定的反爬机制

常规 JavaScript 逆向思路

一般情况下,JavaScript 逆向分为三步:

  1. 寻找入口:逆向在大部分情况下就是找一些加密参数到底是怎么来的,关键逻辑可能写在某个关键的方法或者隐藏在某个关键的变量里,一个网站可能加载了很多 JavaScript 文件,如何从这么多的 JavaScript 文件的代码行中找到关键的位置,很重要
  2. 调试分析:找到入口后,我们定位到某个参数可能是在某个方法中执行的了,那么里面的逻辑是怎么样的,调用了多少加密算法,经过了多少赋值变换,需要把整体思路整理清楚,以便于断点或反混淆工具等进行调试分析
  3. 模拟执行:经过调试分析后,差不多弄清了逻辑,就需要对加密过程进行逻辑复现,以拿到最后我们想要的数据

接下来开始正式进行案例分析:

寻找入口

首先随便输入一个单词,可以看到在网页没有刷新的情况下翻译结果就显示出来了,这里初步推断为 Ajax 异步加载数据的结果,一般情况下,我们在爬虫中使用 requests 方法直接获取到的网页响应数据(response) 是 HTML 页面的原始文档,现在网页的实现大多数都采用前后端分离的模式,浏览器中的页面是 JavaScript 渲染后生成的,这样能减少服务器直接渲染页面带来的压力,我们可以简单的测试一下,右击网页选择查看网页源代码:

以下看到的就是 HTML 网页的原始文档,CTRL + F 搜索我们刚刚输入待翻译的词汇 Rose,可以看到没有筛选到任何结果,这就进一步验证了我们的猜想:

F12 打开开发者人员工具,我们第一步要获取的是翻译的接口,而翻译的数据是通过 Ajax 加载的,Ajax 有特殊的请求类型 XHR,我们可以直接在开发者人员工具的筛选栏选择 XHR,抓包到的内容就全部是 Ajax 加载的数据,可以看到抓报到一条数据:

我们点击进去查看一下内容,通过 preview(控制台会把发送过来的 json 数据自动转换成 javascript 的对象格式,response 为原始响应数据)预览中可以看到,smartResult 为智能翻译的结果,translateResult 是直接翻译显示出来的结果,这样我们就成功找到了翻译的入口,接下来就可以进行第二部调试分析了:

调试分析

观察 Headers 中的信息,可以发现是以 POST 方式提交的数据,Headers 往下滑(Chrome 浏览器相关内容在新功能 Payload 中)可以看到 Form Data 是以表单形式提交的数据,其中是 JSON 格式的参数数据:

通过观察我们可以大概分析出对应的数据的含义:

  • i:待翻译的字符串
  • version:版本
  • action:实时翻译 FY_BY_REALTlME、手动点击翻译 FY_BY_CLICKBUTTION

以上内容不足以让我们知道哪些参数是固定值,哪些参数是经过加密得到的值,我们可以重新输入一个单词,这样就会抓包到一个新的数据,通过观察两个 Form Data 中的数据,可以知道,saltsign、lts 的值每次会改变,其他的皆为固定值:

所以我们可以通过全局搜索(如下图)寻找这几个变量出现的位置:

例如搜索 salt,这里没什么干扰项,只存在于一个 js 文件 fanyi.min.js 中:

点击进去查看会发现整个 js 文件内容被压缩成了一行,不利于我们进行分析研究,可以点击左下角的 {} 对其进行格式化操作,得到的就是标准格式便于观察的 js 文件:

我们可以通过 CTRL+F 进一步定位 salt 参数的位置,由上可知,请求数据是以 JSON 格式提交的,所以我们可以直接搜索 salt+冒号(英文冒号)定位,可以看到筛选出了更少的结果:

接下来我们可以通过对照 Form Data 中的参数内容,逐一对比找到所有参数定义及加密的位置,可以看到在 8974 - 8986 行全部匹配:

此时我们可以打下断点进行调试分析,再次点击翻译,可以发现在断点处停住了,证明这就是翻译参数生成的位置:

我们可以看到,加密的几个参数全部是由 r 定义生成的,这时候进一步跟踪 r 的构造位置:

鼠标悬停在 n 上,可以发现 n 就是我们待翻译的字符串,选中整行代码,鼠标悬停后可以观察到,这个方法生成了所有的加密参数值:

所以跟进函数 generateSaltSign() 就可以找到关键的 js 加密位置:

点击以上链接,会跳转到函数的构造位置:

由上图可以明显看到,t 和 sign 是经过 MD5 加密的,我们进一步分析这段代码的其他加密参数的含义,打下断点进行调试,可以看到 e 就是待翻译的字符串:

var r = function(e) {# navigator.appVersion 浏览器的版本号# t:浏览器版本号经过 MD5 加密的结果var t = n.md5(navigator.appVersion)# r:时间戳, r = "" + (new Date).getTime()# i:ts 的值加上一个 0-9 的随机整数, i = r + parseInt(10 * Math.random(), 10);return {ts: r,bv: t,salt: i,# 两个固定的字符串 + e(待翻译的字符串)+ salt 值sign: n.md5("fanyideskweb" + e + i + "Y2FYu%TNSbMCxc3t2u^XT")}
};
  • bv:浏览器版本号经过 MD5 加密的结果
  • ts:时间戳
  • salt:ts 的值加上一个 0-9 的随机整数
  • sign:两个固定的字符串 + e(待翻译的字符串)+ salt 值

以上找到的加密方法的具体位置,就可以通过代码进行复现了,一般复现的方式有两种:

  1. 通过 python 直接复现
  2. JavaScript 文件写入本地调用复现

这里使用第二种更常规的方式进行逻辑复现:

JavaScript 代码:

// 引用 crypto-js 加密模块
// Crypto 谷歌开发的一个纯 JavaScript 的加密算法类库,可以非常方便的在前端进行其所支持的加解密操作
// require 是 node 用来加载并执行其它文件导出的模块的方法
var CryptoJS = require('crypto-js')function getParams(input, ua) {var bv = CryptoJS.MD5(ua).toString(),lts = "" + (new Date).getTime(),salt = lts + parseInt(10 * Math.random(), 10),sign = CryptoJS.MD5('fanyideskweb' + input + salt + ']BjuETDhU)zqSxf-=B#7m').toString()return { bv: bv, lts: lts, salt: salt, sign: sign }
}

以上 sign 中的 salt 相当于 MD5 的加盐操作 :

加盐(the-Salt):常用口令的 MD5 值 + 复杂字符串,防止黑客通过彩虹表(反推表,简单密码口令的 MD5 值进行对比),加强账户保护。

我们需要获取的是页面上看到的翻译出来的内容,从 Preview 中层层打开获取到的 json 响应内容,可以看到需要的内容在 translateResult 第二层的 tgt 中:

模拟执行

完整代码(url、Referer 均经过脱敏处理,代码不可以直接运行,解密方式在文章开头):

# @Author  :  Y
# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import execjs
import requestsurl = 'aHR0cHM6Ly9mYW55aS55b3VkYW8uY29tL3RyYW5zbGF0ZV9vP3NtYXJ0cmVzdWx0PWRpY3Qmc21hcnRyZXN1bHQ9cnVsZQ=='
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'def get_translation_result(parameters):headers = {'User-Agent': user_agent,'Referer': 'aHR0cHM6Ly9mYW55aS55b3VkYW8uY29tLw==','Cookie': 'OUTFOX_SEARCH_USER_ID="-1848382357@10.169.0.84"; ___rl__test__cookies=1625907853887; OUTFOX_SEARCH_USER_ID_NCOO=132978720.55854891'}response = requests.post(url=url, headers=headers, data=parameters)result = response.json()['translateResult'][0][0]['tgt']return resultdef get_parameters_by_javascript(query):with open('youdao_encrypt.js', 'r', encoding='utf-8') as f:youdao_js = f.read()params = execjs.compile(youdao_js).call('getParams', query, user_agent)parameters = {'i': query,'from': 'AUTO','to': 'AUTO','smartresult': 'dict','client': 'fanyideskweb','salt': params['salt'],'sign': params['sign'],'lts': params['lts'],'bv': params['bv'],'doctype': 'json','version': '2.1','keyfrom': 'fanyi.web','action': 'FY_BY_REALTlME'}return parametersdef main():query = input('请输入要翻译的内容:')param = get_parameters_by_javascript(query)result = get_translation_result(param)print('翻译的结果为:', result)if __name__ == '__main__':main()

总结

以上是对某道翻译的翻译接口逆向分析,如有见解欢迎评论区指正交流~

【JavaScript 逆向】某道翻译接口逆向相关推荐

  1. 【JS 逆向百例】有道翻译接口参数逆向

    文章目录 逆向目标 逆向过程 抓包分析 参数逆向 完整代码 youdao_encrypt.js youdaofanyi.py 逆向目标 目标:有道翻译接口参数 主页:https://fanyi.you ...

  2. 【爬虫逆向案例】某道翻译js逆向—— sign解密

    声明:本文只作学习研究,禁止用于非法用途,否则后果自负,如有侵权,请告知删除,谢谢! [爬虫逆向案例]某道翻译js逆向-- sign解密 1.前言 2.步骤 3.源码 4.号外 1.前言 相信各位小伙 ...

  3. python有道自动翻译_Python 调用有道翻译接口实现翻译

    最近为了熟悉一下 js 用有道翻译练了一下手,写一篇博客记录一下,也希望能对大家有所启迪,不过这些网站更新太快,可能大家尝试的时候会有所不同. 首先来看一下网页 post 过去的数据 大家不难发现,我 ...

  4. 使用python对在线网易有道翻译接口进行分析及破解js加密

    文章目录 项目目标 温馨提示 项目分析 分析完毕,进行代码模拟加密过程,代码演示 项目目标 对网易有道翻译接口关键参数进行分析,并且进行js加密破解,实质上就是找出网易有道翻译接口对关键参数的加密的详 ...

  5. 有道翻译接口问题(续)

    原博文地址:https://blog.csdn.net/qq_40962368/article/details/80620817 自从写了上面的博文之后,很多人询问我关于有道翻译接口的问题,为什么不是 ...

  6. 使用Python调用有道翻译接口实现翻译任务

    使用Python调用有道翻译接口实现翻译任务 首先直接上代码,可以直接复制调用 import hashlib import random import timeimport requestsclass ...

  7. 最新官方有道翻译接口破解调用(详)

    以下是我从老师那学到的关于有道翻译接口破解调用的分析过程以及方法(截止更博前依旧有效): 1.首先进入有道翻译界面,在输入框尝试输入数据以获取请求,经过抓包后找到POST请求的接口 观察响应 这就是我 ...

  8. js逆向--有道翻译

    目录 1.前言 2.起因 3.经过 4.结果 1.前言 分类:js逆向 语言:python 2.起因 记录一下js逆向入门案例 3.经过 分析案例,有道翻译是通过ajax的post请求获得的响应结果, ...

  9. 逆向有道翻译[最新版本],包含解密部分

    前言 js逆向作者我也不是很有经验, 凭借写代码的经验加上一些主观上的猜测完成了此次逆向 后文提供python版本接口封装 模拟请求 打开开发者工具, 输入文字请求翻译 是这个请求了, 打开响应一看 ...

最新文章

  1. IDEA中添加类的创建者信息
  2. 【tensorflow-keras-BatchNormalization】BatchNormalization批量标准化层
  3. 深度思考 Spring Cloud + Alibaba Sentinel 源码原理
  4. 2022年有哪些值得学习的Java开源项目?这7个火爆了
  5. cookie 保存导航菜单的展开状态
  6. hdu 1083 Courses
  7. [NodeJS] Hello World 起步教程
  8. linux ssh客户端乱码,Win10专业版下Open ssh客户端乱码咋办?
  9. Ubuntu 16.04下安装SVN可视化客户端--RabbitVCS
  10. 希捷服务器硬盘格式化不了,希捷硬盘专用分区格式化Seagate DiscWizard16.0 官方版...
  11. java读取word pdf文件内容_JAVA读取WORD,EXCEL,POWERPOINT,PDF文件的方法
  12. CVPR2022论文速递(2022.4.15)!共16篇!内含2篇Oral!
  13. 2021-11-03 - 英文/英语简写 - 收集
  14. pandas_计算最大回撤
  15. (目录)微气候模型ENVI-met模拟的基本使用教程
  16. Ruby读excel写入mysql
  17. 1万+字原创读书笔记,机器学习的知识点全在这篇文章里了
  18. 朴素贝叶斯+Python3实现高斯朴素贝叶斯
  19. opencv3/C++ 将图片转换为视频
  20. ESP8266WiFi-begin调用储存在ESP8266的闪存系统中的WiFi设置

热门文章

  1. 广东省产业园区——清远华侨工业园
  2. do while“直到”型循环
  3. 【C++】面试题目,整理自牛客网
  4. 初级程序员Mysql最新安装步骤(安装,卸载,常见问题)
  5. 很有用的hosts 文件
  6. 2022美赛C题 预测模型
  7. cocos2dx 3.4 lua加密 setXXTEAKeyAndSign
  8. [牛客算法总结]:旋转字符串
  9. 语义激光SLAM论文阅读 Semantic Lidar_based SLAM paper Research
  10. 康拓排列以及全排列老年人听不懂系列