网站建设杭州,外贸网站一般用什么框架,wordpress上传乱码,做网站学哪些语言文章日期#xff1a;2024.12.24 使用工具#xff1a;Python#xff0c;Node.js 逆向类型#xff1a;webpack类型 本章知识#xff1a;sign模拟生成#xff0c;密文的解密(webpack)#xff0c;全程扣代码#xff0c;仅供学习参考 文章难度#xff1a;低等#xff08;没… 文章日期2024.12.24 使用工具PythonNode.js 逆向类型webpack类型 本章知识sign模拟生成密文的解密(webpack)全程扣代码仅供学习参考 文章难度低等没难度 文章全程已做去敏处理 【需要做的可联系我】 AES解密处理直接解密即可crypto-js.js 标准算法在线AES加解密工具 仅供学习仅供测试仅供参考
声明本文逆向的所有内容文件仅供学习从网站扣的代码不会公开但博主自己写的代码内容将会公开在文章最底部望谅解
先看成品图效果就是这个样子可以直接翻译支持多种不同语言没有试过高并发 给大家提前讲一下比较简单的内容我将会快速讲解不会很细小白可能会不懂不懂只能去看我之前的逆向文章或者留言都可以有志向的人一起学习发展。
1、打开某某网站使用文章开头的AES在线工具解密)
OI1Y7IeHDHWVFvw4Yo05CnrGOzxG4b5OFpdZvnuG2WEWj/TsHjdLb2bzhvR/PvI
2、【sign】我们打开页面后随便输入中文进行翻译然后找到刻意的接口我们打开看一下没想到一上来就有个sign而且返回的数据还是密文 3、【sign】别着急我们把这个接口的请求先转移到python文件内然后经过我不断的测试发现他的cookie必须要加【OUTFOX_SEARCH_USER_ID】参数而且这个参数是通过服务器返回的而且有效期为20年我决定直接生成我从来没见过一个cookie有效期为20年的纯扯淡他一定不是在服务器存储着所以我们直接随机生成即可
其次是载荷data里【from】【to】这两个参数我就不多介绍了看注释即可。
剩下的就是sign和一个时间戳直接全局搜索
4、【sign】全局搜索接口的链接路径发现搜索到了两个直接点进去都打上断点然后再次触发翻译 5、【sign】断住了看图说话直接跟进去。 6、【sign】跟进来后发现了sign而且加密方法就在头上。这就不用多说了口算就能知道是md5加密。 7、【sign】直接用 python 模拟出来标准的MD5,就不用讲太多了 8、【密钥】接下来看一下那个密钥这个也不用多说他是另一个请求返回的而且这个请求里也有一个sign用的也是md5加密只是加密的内容有点不一样直接看结果吧没什么难度 9、【代码整理】我将代码进一步整合方便下一步的调试 10、【解密密文】接下来重点来了解密返回的密文本次全程扣代码文章结尾我将会附上模拟解密的代码并非扣下来的代码供大家参考学习
注意文章结尾的代码并非官网扣下来的放心测试学习
11、遇到这种密文解密其实也没多难我接下来用两种方法帮大家找到这个加密位置。
12、【找加密位置1】我们找到返回密文的接口复制一下链接路径然后ctrlshiftf全局搜索搜索到后对第二个打上断点第一个不用打断点因为第一个很明显他的链接路径和我要找到不一样直接排除 13、【找加密位置1】我们打上断点后随便输入内容使其触发翻译然后会自动断住这时候我们就一步一步跟进 14、【找加密位置1】大约跟进了5次左右看到了一个加密方法虽然目前没有看到密文在此处解密但我的职业素养告诉我“有疑问直接打上断点好了”记住做逆向只要看到疑似加解密的位置直接打断点就好这是找解密位置或加密位置的一种方法。我们直接打上断点然会放开运行 14、【找加密位置2】使用HOOK大法配合油猴插件会更方便好用)将HOOK代码直接在控制台执行然会再次输入内容触发翻译你会发现断住了HOOK代码在文章结尾
HOOK原理首先我们要知道他解密密文要做什么事情像这种一般都是字典传输那么他在解密内容后一定会执行【JSON.parse】将字符串的字典转为格式化后的字典如果他不执行转换那他就读取不了内容所以我们用这个HOOK代码进行拦截相当于这个HOOK代码就是中间商你所做的事情要经过这个中间商后这个中间商在觉定是拦截还是放行这个中间商把别人替代了所以你不得不经过他这就是大概的HOOK的原理有些场景的HOOK需要搭配油猴 15、【找加密位置2】我们一边放行一遍观察他的内容参数才走了几步就看到了解密后的密文数据我们在堆栈里看他上一步的操作看看都干了什么点击上一个堆栈嘿成功找到加密位置。 16、【解密密文】接下来我们开始解密我们将他的解密函数在控制台运行他会自动暴露源函数这时我们点进去 17、【解密密文】点击进来后可以看到他解密的方法我们直接转移到本地js文件内然会尝试运行看缺少什么发现缺少【l】函数我们直接去源代码里找 18、【解密密文】找到了直接看图直接复制到文件内然后再次运行发现缺少a函数我们直接去找 19、【解密密文】我们对当时找到的参数位置的a打上断点然后刷新页面会发现断住了然后我们控制台输出一下然后点击进去会发现他是一个webpack加载器文件直接把当前js全部复制到js内 20、【解密密文】复制到了本地js文件内运行后发现缺少两个环境我直接补上了就不细讲了。然后我看出来这个加载器的主函数是a所以直接把他的主运行函数导出全局让外部可以访问既然a已经被导出为jzq了那么下面的两个函数也有修改一下都改为jzq即可然后再次运行看看缺少什么 21、【解密密文】运行发现报错了找到报错的行然后打印一下他运行什么导致的报错打印结果发现他缺少方法加载器没有找到这个方法无法调用那我们直接去找 22、【解密密文】我们回到浏览器控制台运行一下图片里的函数然后随便打开任意字段点击链接进到加载器的函数里 23、【解密密文】进来后我们直接搜索缺少的方法找到后直接放入到本地js里可以让加载器读取但要注意了看下面第二张图你的加载器需要修改一下代码否则他不会读取你导入的方法 24、【解密密文】这次运行成功了他已经能正常读取到91565了但他缺少另一个方法我们继续去搜索一种重复这种方法。由于太多我就不一个一个尝试了我直接把全部都复制过来 25、【解密密文】我把所有的都复制过来运行后发现没有问题了成功解密了。一般情况不要无脑全部复制这会导致卡顿具体怎么复制还是根据大家的个人习惯 26、【全部代码整理】直接看成品
注意没有用扣下来的代码做解密是因为文件量太大而且扣代码是教程并不是一定要用扣下来的代码要懂得变通 【AES-128-CBC.js】 js文件用于解密扣下来的代码不能用于公开只能给大家展示模拟出来的源代码
// 导入 crypto 模块
const crypto require(crypto);
// 安装 express 服务包
// npm install express --save
const express require(express);const app express();
app.use(express.json());// AES-128-CBC 解密函数
function aesDecrypt(ciphertext, key, iv) {try {// 创建解密器const decipher crypto.createDecipheriv(aes-128-cbc, key, iv);// 执行解密操作let decrypted decipher.update(ciphertext, base64, utf-8);decrypted decipher.final(utf8);return decrypted;} catch (error) {console.error(解密失败:, error);}
}function generateMD5Hash(input) {// 创建 MD5 哈希const hash crypto.createHash(md5);// 更新哈希对象内容hash.update(input);// 输出结果为 Buffer 对象return hash.digest(); // 默认是二进制 Buffer 格式
}app.post(/, (req, res) {const {text, key, iv} req.body;decrypt_data aesDecrypt(text,generateMD5Hash(key),generateMD5Hash(iv))console.log(【解密结果】 - ,decrypt_data)res.status(200).json({code: 1, data: JSON.parse(decrypt_data)});
});// 检测服务是否已打开
app.get(/run, (req, res) {res.status(200).json({code: 1});
});app.listen(4000, () {console.log(Node.js 服务监听端口 127.0.0.1:4000);
});【翻译请求.py】运行此代码前请先运行js文件js文件运行后会启动接口python要调用接口实现解密
import json
import random
import requests
import time
import hashlib
import base64# base64 解密
def base64_decode(str):# print(base64.b64decode(MTIz.encode()))return base64.b64decode(str).decode(utf-8)
# 这个是链接被base64加密了此步骤只用于去敏无其他作用
URL base64_decode(aHR0cHM6Ly9kaWN0LnlvdWRhby5jb20)class youdao:# MD5 - SHA3_512 加密def md5_encrypt(self, string):md5, sha1, sha224, sha256, sha384, sha512,blake2b, blake2s,sha3_224, sha3_256, sha3_384, sha3_512,shake_128, shake_256md5 hashlib.md5()md5.update(string.encode(utf-8))return md5.hexdigest()# 获取 secretKey / aesKey / aesIvdef obtain_key(self):获取 secretKey / aesKey / aesIvheaders {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36,}url URL /webtranslate/key# 13位时间戳mysticTime time.time()# 立马的key是官网固定的sign self.md5_encrypt(fclientfanyideskwebmysticTime{mysticTime}productwebfanyikeyasdjnjfenknafdfsdfsd)params {keyid: webfanyi-key-getter,sign: sign,client: fanyideskweb,product: webfanyi,pointParam: client,mysticTime,product,mysticTime: f{mysticTime},}response requests.get(url, paramsparams, headersheaders).json()[data]# sign密钥self.secretKey response[secretKey]# key密钥self.aesKey response[aesKey]# iv向量self.aesIv response[aesIv]# 翻译请求 返回密文def translate(self, text, froms, tos):执行翻译请求返回密文headers {Accept: application/json, text/plain, */*,Content-Type: application/x-www-form-urlencoded,Referer: 1,User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36,}# 13位时间戳mysticTime time.time()sign self.md5_encrypt(fclientfanyideskwebmysticTime{mysticTime}productwebfanyikey{self.secretKey})# 随机伪装一下cookies {OUTFOX_SEARCH_USER_ID: f-{random.randint(10000000, 99999999)}{random.randint(1, 255)}.{random.randint(1, 255)}.{random.randint(1, 255)}.{random.randint(1, 255)}# 防封刷新一次可以使用20年有效期}url URL /webtranslatedata {i: text,# from: en, # 输入日文 en英文 ja日文 fr法语 zh-CHS中文 de德语 es西班牙语# to: zh-CHS, # 翻译为中文dictResult: true,keyid: webfanyi,sign: sign,client: fanyideskweb,product: webfanyi,appVersion: 1.0.0,vendor: web,pointParam: client,mysticTime,product,mysticTime: f{mysticTime},keyfrom: fanyi.web,}if froms:data[from] fromsif tos:data[to] tosresponse requests.post(url, headersheaders, cookiescookies, datadata).textself.ciphertext response.strip()# AES-128-CBC 解密def decrypt_AES_128_CBC(self):AES-128-CBC 解密import requestsheaders {Content-Type: application/json}data {text: self.ciphertext, key: self.aesKey, iv: self.aesIv}url http://127.0.0.1:4000/response requests.post(url, headersheaders, datajson.dumps(data)).json()text if response[code] 1:for data_list in response[data][translateResult]:text data_list[0][tgt]print(----- 翻译结果 -----\n text \n)main youdao()
# 获取 secretKey / aesKey / aesIv 只需要运行一次即可经过我的分析他每天返回的key都不一样
main.obtain_key()
# 发送翻译请求 # 输入日文 en英文 ja日文 fr法语 zh-CHS中文 de德语 es西班牙语
# froms当前输入的是什么语言 输入None则自动识别
# tos要翻译为什么语言 输入None则自动识别
main.translate(你是谁你叫什么名字?\n怎么称呼大哥\n我的名字是哈哈请叫我哈哈哥, fromsNone, tosNone) # 自动识别 翻译为 英文(默认)
# 解密请求内容
main.decrypt_AES_128_CBC()
【HOOK代码】
// 【json.parse 解密对象专用 JSON字符串转换为JS对象】
(function () {var parse_ JSON.parse;JSON.parse function (arg) {console.log([J] - 正在执行[*json.parse] - , arg);debugger;return parse_(arg); // 不改变原来的执行逻辑}
})();