🔗 网址
# 入口
https://dc.simuwang.com/
# 数据接口
https://sppwapi.simuwang.com/sun/ranking/fundRankV3
⏩ 需求
获取10页数据,主要是解密响应数据
🎲 逆向过程
解密的逆向,浏览器最常用的函数是JSON.parse,可用指定hook脚本来找解密位置
// JSON.parse Hook脚本
(function () {
var _parse = JSON.parse;
JSON.parse = function (value) {
debugger;
return _parse(value);
}
})()
停到这个位置
然后看作用域
找到解密位置
经测试,主要是AES加解密,无魔改,主要是key和iv与解密值有关联,需要逆向
现在我逐条解析相关代码
首先if条件语句不用看,因为既然知道了我们需要的结果在判断语句里面,那这条判断语句就一定是正确的
let e = MD5(key)
key是一段较短的字母加数字的字符串,然后通过MD5加密得到e,在下面的代码中,我们会得知e是AES解密中需要的key和iv生成的重要数据,这个key我们未知,是需要逆向的
接下来的代码用了代码混淆,还原代码如下
t = UTF8["parse"](e)
, r = UTF8["parse"](e[__Ox11208b[6]](16, 32))
, n = AES["decrypt"](window["atob"](datas), t, {
iv: r,
padding: pkcs7
}).toString(UTF8);
data = JSON["parse"](n)
下面我给出在nodejs环境下AES解密的代码
const CryptoJS = require("crypto-js");
var secretKey = "" // 十六字节密钥
var Iv = "" // 16字节初始向量
var ciphertext = "" // 解密值
// 将密钥和IV转换为CryptoJS支持的格式
var key = CryptoJS.enc.Utf8.parse(secretKey);
var iv = CryptoJS.enc.Utf8.parse(iv);
// 执行AES解密
const decrypted = CryptoJS.AES.decrypt(cipherText, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// 打印UTF8格式的原始字符串
console.log(decrypted.toString(CryptoJS.enc.Utf8));
对比以上代码,我将需要逆向的代码改写如下
const CryptoJS = require("crypto-js");
const md5 = require('md5');
var ciphertext = "";
var key1 = "";
var e = md5(key1);
var key = CryptoJS.enc.Utf8.parse(e);
var iv = CryptoJS.enc.Utf8.parse(e.slice(16, 32));
n = CryptoJS.AES.decrypt(ciphertext, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8)
result = JSON.parse(n);
// console.log(result);
接下来的任务就是逆向key值
这里发现一个疑似生成key值的地方
打个断点看一下结果
然后看一下最终的key值,判断以下是否对key值进行二次处理
数值不同,看来需要逆向了,其中重要的参数data,经测试发现是请求成功后返回的json数据
这个值我一开始觉得它是写死在全局对象里面,但我每次请求都是不一样的值,所以我就试者去找它的加密位置,window点后面加的是获取的数据中的id值
在下面的位置停,发现值已经生成了
接着在上面打一下断点
那就从这里开始,一直点步入
点了几下之后发现跳到了另一个虚拟文件中
不过这个值还是处于未生成的状态
当整个文件中的代码执行完毕之后,看一下最终生成的结果
这不就是我们需要找的值么,不过别急着去逆向代码,先观察以下我们获取到的数据
只要你把这个key值中的数据仔细看一下,就会发现就是刚才文件中的代码,哦,原来浏览器是先获取返回数据,在执行返回数据中携带的JS代码生成window.xxxxx值。
OK,思路分析清楚,直接上代码
如有爬虫相关问题,可关注wx公众号“小恰学逆向”,我们一起讨论学习。