js逆向——2024最新金山词霸(练习二)

首先还是看响应,返回了一串加密数据

继续放大招hook JSON,详细流程在上一篇文章

 

然后直接跟栈找到解密位置

 var t = 1 === (null === e || void 0 === e ? void 0 : e.status) ? A(A({}, e), {}, {
                        content: JSON.parse((0,
                        _.B6)(e.content))
                    }) : e;

t是解密之后的结果

然后就是解密函数:

经过测试是标准的AES-ECB解密模式

function f(e) {
            var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "aahc3TfyfCEmER33"
              , r = n.enc.Utf8.parse(t)
              , o = n.AES.decrypt(e, r, {
                mode: n.mode.ECB,
                padding: n.pad.Pkcs7
            });
            return o.toString(n.enc.Utf8)
        }

然后我们只需正确请求接口就ok了

简单看一下加密参数,就sign是比较可疑的

 

对于XHR请求的包,直接跟栈就对了!

 

就是跟栈的时候注意看一下url对不对,别跟错接口了😂😂 

一直跟到找不到sign的踪迹为止

 

找到位置之后打断点,观察sign生成的全过程

经过分析sign的生成,是先经过md5然后AES加密生成

注:当看到加密函数传入字符串的时候,一定要先用123456测试一下,不要上来就扎入细节当中

整个加密参数的生成流程我们都清除了,下面就是扣代码环节了

 

经过调试已经可以生成正确的sign了 

 然后就是解密数据了,过程相对简单,就是应该普通的AES-ECB解密

 

 完整的vscode代码:

// 加密参数sign生成算法
var CryptoJS = require('crypto-js');

s = function(e) {
    e = decodeURIComponent(e);
    for (var t = String.fromCharCode(e.charCodeAt(0) - e.length), r = 1; r < e.length; r++)
        t += String.fromCharCode(e.charCodeAt(r) - t.charCodeAt(r - 1));
    return t
};

function aes_encode(e) {
    var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "%5C%C2%80%C2%9A%C2%A8%C2%B6%C2%B8y%C2%9B%C2%B2%C2%8F%7C%7F%C2%97%C3%88%C2%A9d"
      , r = CryptoJS.enc.Utf8.parse(s(t))
      , o = CryptoJS.AES.encrypt(e, r, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return o.toString()
}

function get_sign(query){
    var LI = '6dVjYLFyzfkFkk'
    var con_str = "6key_web_new_fanyi".concat(LI).concat(query.replace(/(^\s*)|(\s*$)/g, ""));
    var r = CryptoJS.MD5(con_str).toString().substring(0,16)
    console.log(r)
    return aes_encode(r)
}

/*var ret = get_sign('早上好')
console.log(ret)
console.log('over')*/

//解密响应数据算法

function aes_decode(e) {
    var t = "aahc3TfyfCEmER33"
      , r = CryptoJS.enc.Utf8.parse(t)
      , o = CryptoJS.AES.decrypt(e, r, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return o.toString(CryptoJS.enc.Utf8)
}

/*var ret = aes_decode('nCRjxZwyh/7P3ee74BIU0r+VpYqC1/VewPqzx0un7jyNV2TcReI50gWyVhig1cg85spz3Z+vU9BuH+MZ9gpZDbFxsl6nE06WcFjQ1vllnHa/X9uvHGHQl4tTYa3B3DlS1qukVA9HNWk0rAyvPSnz68Wkf6p5bUFNBfLUvZKMQVy3FmCWe/NkT0FSRS3EL7WediKsKpF8Gq+m/NsT9zVE3sDqIe64/a4F9twH0KVZc+bCH+1eiXP29Po0pKMNkmuhWZN8biNTndn7IEkD1zJKhpTXSl0tJRb87q/u9/l51U5yjeiVxoTCwlOzoZygtiv55xamsuOEWt92DpT0dPSH1bl+XyrchrkYbYi+K6HJgVw=')
console.log(ret)
console.log('over')*/

最后就是python代码的编写了:

经过测试,也拿到正确的响应数据,并成功解密

解析具体的json串的时候报错:TypeError: string indices must be integers

解决: 将json字符串解析为字典即可》response_json = json.loads(decrypt_text)

完整的python代码:

import requests
import execjs
import json
headers = {
    "authority": "ifanyi.iciba.com",
    "pragma": "no-cache",
    "cache-control": "no-cache",
    "accept": "application/json, text/plain, */*",
    "content-type": "application/x-www-form-urlencoded",
    "sec-ch-ua-mobile": "?0",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.253.400 QQBrowser/12.6.5678.400",
    "origin": "https://www.iciba.com",
    "sec-fetch-site": "same-site",
    "sec-fetch-mode": "cors",
    "sec-fetch-dest": "empty",
    "referer": "https://www.iciba.com/",
    "accept-language": "zh-CN,zh;q=0.9"
}
url = "https://ifanyi.iciba.com/index.php"
# query = input('请输入需要查询的单词:')
query = '早上好'
with open('金山词霸.js','r',encoding='utf-8') as f:
    ctx = execjs.compile(f.read())
sign = ctx.call('get_sign',query)
params = {
    "c": "trans",
    "m": "fy",
    "client": "6",
    "auth_user": "key_web_new_fanyi",
    "sign": sign
}
data = {
    "from": "zh",
    "to": "en",
    "q": query
}
response = requests.post(url, headers=headers, params=params, data=data)
encry_text = response.json()['content']
print(encry_text)
decrypt_text = ctx.call('aes_decode',encry_text)
print(decrypt_text)
print(type(decrypt_text))
# 将 JSON 字符串解析为字典
response_json = json.loads(decrypt_text)
print(response_json['out'])

ok,今天的你就到此为止吧,明天还要接着狼🐺啊! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值