經過測試,在Post請求包裏面 user 和 hash 需要逆向。以及在headers頭部需要逆向 EUI
hash參數:
那麽開始分析咯,通過搜索關鍵詞找到這個位置斷點:
這段意思是v函數傳入原始密碼后加密最終全部大寫作爲加密後的值。
hash: v()(i.password).toUpperCase()
進入v函數發現 return n && n.asBytes ? r : n && n.asString ? i.bytesToString(r) : t.bytesToHex(r)
最終走的是 t.bytesToHex(r) ,然後e是傳入的密碼,那麽可以先進行測試,我傳入1,最終加密生成c4ca開頭,熟悉的朋友可能想到了,這就是標准的md5加密,沒錯就是這樣。
user參數:
往上翻就找到了這個位置,看樣子是aes加密。
跟進去,EUI也在這裏,總之最後交給gpt來分析與生成代碼。
最後是成品:
const crypto = require('crypto');
const NodeRSA = require('node-rsa');
function U(Username) {
t = {
user: Username,
};
// 1. 生成16位随机密钥字符串(与原浏览器代码完全一致)
const generateRandomKey = () => {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
let result = "";
for (let i = 0; i < 16; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
};
const e = generateRandomKey();
// 2. RSA加密配置(兼容浏览器实现)
const rsaEncrypt = (plainText) => {
const publicKey = new NodeRSA();
publicKey.setOptions({ encryptionScheme: 'pkcs1' }); // 重要:设置填充方案
publicKey.importKey(
`-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYEVrK/4Mahiv0pUJgTybx4J9P
5dUT/Y0PuwMbk+gMU+jrZnBiXGv6/hCH1avIhoBcE535F8nJQQN3UavZdFkYidso
XuEnat3+eVTp3FslyhRwIBDF09v4vDhRtxFOT+R7uH7h/mzmyA2/+lfIMWGIrffX
prYizbV76+YQKhoqFQIDAQAB
-----END PUBLIC KEY-----`,
'public'
);
return publicKey.encrypt(Buffer.from(plainText), 'base64');
};
const r = rsaEncrypt(Buffer.from(e).toString('base64'));
// 3. 处理AES加密参数(关键兼容性处理)
const iv = Buffer.from("0102030405060708", 'binary'); // 强制二进制解析
const aesKey = Buffer.from(e, 'utf8').subarray(0, 16); // 截取前16字节
// 4. 参数加密处理
const encryptedParams = {};
Object.entries(t).forEach(([key, value]) => {
// 创建加密器(使用与浏览器兼容的配置)
const cipher = crypto.createCipheriv('aes-128-cbc', aesKey, iv);
// 设置填充方式(兼容浏览器实现)
cipher.setAutoPadding(true); // PKCS7填充
// 执行加密
let encrypted = cipher.update(value, 'utf8', 'base64');
encrypted += cipher.final('base64');
encryptedParams[key] = encrypted;
});
return {
EUI: `${r}.${Buffer.from(Object.keys(t).join(','), 'utf8').toString('base64')}`,
encryptedParams
};
}
function password_hash(data) {
var md5 = crypto.createHash('md5').update(data).digest('hex').toUpperCase();
return md5;
}