JS逆向爬虫----响应结果加密②

抓包定位js文件

刷新抓包

抓包流程

  1. f12打开开发者模式,点击网络
  2. 刷新页面

搜索关键字 json.parse定位

  1. 点击搜索,输入关键词,回车。定位到了四个js文件;
  2. 选择textTranslate文件,在来源打开

搜索全部包定位js文件如下:

  1. 在textTranslate的js文件内,点{}美化代码
  2. ctrl+f搜索关键字
  3. 查看搜索结果,定位到以下位置

js中定位关键字如下:

代码断点调试

输入傻狗搜索,找到了网络响应的数据加载到断点所在数据

输入需要翻译的数据后,响应数据被加载到断点位置,通过断点内的函数运行,我们可用获取到了结果json

const a = tt["a"].decodeData(o, za["a"].state.text.decodeKey, za["a"].state.text.decodeIv)

这一行代码运行结束后,我们获取到a为最后需要的结果,同时参数o为待解密的响应结果,za[“a”].state.text.decodeKey,
za[“a”].state.text.decodeIv 为固定字符串。

查看解密之后的数据如下:



关键的解密函数为tt[“a”].decodeData

加密函数定位

在断点处,我们选择tt[“a”].decodeData*函数,点击来源位置,进入函数定义的js代码处。
函数定义代码如下:

逆向

函数定义代码:

 V = (t,o,n)=>{
                if (!t)
                    return null;
                const a = e.alloc(16, j(o))
                  , c = e.alloc(16, j(n))
                  , i = r.a.createDecipheriv("aes-128-cbc", a, c);
                let s = i.update(t, "base64", "utf-8");
                return s += i.final("utf-8"),
                s
            }

根据函数内的关键字,我猜测数据是由aes解密的,需要的解密密钥和填充为上面固定的字符串。
![在这里插入图片描述](https://img-blog.csdnimg.cn/fa5b3dd5f327428d8e269396e825c3ec.pngJS逆向爬虫----响应结果加密②_第1张图片
上面的t,o,n都为已知的数据

我们使用在线的AES测试一下

AES解密在线测试与解密测试

JS逆向爬虫----响应结果加密②_第2张图片
解密失败,这里解密失败的原因可能是输入的key和填充有问题。
JS逆向爬虫----响应结果加密②_第3张图片
我们抓包的断点位置,输入的解密数组a,c与在线测试的通过字符串转换的数组不一致。
JS逆向爬虫----响应结果加密②_第4张图片
我们定位a,c生成的方法,输出a,c,查看他们到底是什么?
JS逆向爬虫----响应结果加密②_第5张图片
在 JavaScript 内,上面提供的 JSON 结构表示一个包含字节数据的 Buffer 对象。该对象的属性 type 表示数据类型为 “Buffer”,而属性 data 包含了实际的字节数据。
要在 JavaScript 中定义一个类似的 Buffer 对象 a,可以按照以下方式进行:

const a = Buffer.from([8, 20, 157, 167, 60, 89, 206, 98, 85, 91, 1, 233, 47, 52, 232, 56]);

创建一个名为 a 的 Buffer 对象,其中包含与提供的字节数据相同的字节值。可以通过这种方式重写解密过程,直接用于解密,不需要函数上面的

const a = e.alloc(16, j(o))
                  , c = e.alloc(16, j(n))

根据以上的思路,我重写了解密函数如下:

// 响应结果解密,nodejs版本
const crypto = require('crypto');
function youdaoAesDecrypt(data_to_decrypy){
        // 假设 a 和 c 是 16 字节的 Buffer,t 是 Base64 编码的密文
        const a = Buffer.from([8, 20, 157, 167, 60, 89, 206, 98, 85, 91, 1, 233, 47, 52, 232, 56]);
        const c = Buffer.from([
                210,
                187,
                27,
                253,
                232,
                59,
                56,
                195,
                68,
                54,
                99,
                87,
                183,
                156,
                174,
                28
            ]);

        // 创建解密器
        const decipher = crypto.createDecipheriv("aes-128-cbc", a, c);

        // 解密 Base64 编码的密文 t,输出为 UTF-8 编码的明文 s
        let s = decipher.update(data_to_decrypy, "base64", "utf-8");
        s += decipher.final("utf-8");
        return s
};

const t = 'Z21kD9ZK1ke6ugku2ccWuwRmpItPkRr5XcmzOgAKD0GcaHTZL9kyNKkN2aYY6yiOzZfdN-5c7PrKP9hcDVlpmVY5ADRIOHQ1z0Xgq87U89X1E9keibqZiFlJGoBKo3ammj0kDfzS0BYOFrPdmoMot5FGqXPmGpoNmGC1BSt8hvSKL37_g_DVloKqsDBquM8W';
result = youdaoAesDecrypt(t);
console.log(result);

运行以上代码,结果如下:

JS逆向爬虫----响应结果加密②_第6张图片
解密出需要的结果,逆向成功。

代码回溯

解密函数内有以下代码,通过给定的密钥与填充,我们获取到了a,c两个buffer对象用于解密。

const a = e.alloc(16, j(o))
                  , c = e.alloc(16, j(n))

再次调试,我们定位j函数与e.alloc函数的运行结果。

j函数

JS逆向爬虫----响应结果加密②_第7张图片

function j(e) {
                return r.a.createHash("md5").update(e).digest()
            }

这个代码运行过后,是将e加密为了一个buffer对象,用于解密的数据。

根据输入的字符串与输出的buffer对象,构造生成代码
const md5Hash = crypto.createHash('md5').update(key).digest().slice(0, 16);
const ivBuffer = crypto.createHash('md5').update(iv).digest().slice(0, 16);

以下为改造后的解密函数,使用密钥与填充:

const crypto = require('crypto');

function aesDecrypt(key, iv, encryptedData) {
    // 将密钥进行 MD5 哈希,并取前 16 个字节作为密钥
    const md5Hash = crypto.createHash('md5').update(key).digest().slice(0, 16);
    const ivBuffer = crypto.createHash('md5').update(iv).digest().slice(0, 16);
    // 创建解密器
    const decipher = crypto.createDecipheriv('aes-128-cbc', md5Hash, ivBuffer);
    // 使用 base64 编码的密文进行解密
    let decryptedData = decipher.update(encryptedData, 'base64', 'utf-8');
    decryptedData += decipher.final('utf-8');
    return decryptedData;
}

// 使用示例
const key = "ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl";
const iv = "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4";
const encryptedData = "Z21kD9ZK1ke6ugku2ccWuwRmpItPkRr5XcmzOgAKD0GcaHTZL9kyNKkN2aYY6yiOzZfdN-5c7PrKP9hcDVlpmVY5ADRIOHQ1z0Xgq87U89X1E9keibqZiFlJGoBKo3ammj0kDfzS0BYOFrPdmoMot5FGqXPmGpoNmGC1BSt8hvSKL37_g_DVloKqsDBquM8W";

const decryptedData = aesDecrypt(key, iv, encryptedData);
console.log("origin data",encryptedData)
console.log("result==>",decryptedData);

运行过后,结果正常。

你可能感兴趣的:(python爬虫综合,爬虫)