JsRpc+Galaxy 实现网站HTTP报文自动加解密+自动更新签名
字数 1759 2025-08-22 22:47:30
JsRpc+Galaxy 实现网站HTTP报文自动加解密与签名更新技术指南
一、技术背景与工具简介
1.1 技术背景
现代Web应用常对HTTP请求/响应进行加密处理,并添加签名验证机制,这给安全测试带来挑战:
- 请求/响应数据加密,BurpSuite无法直接查看明文
- 签名机制导致无法直接重放请求
- 手动解密/加密效率低下
1.2 工具组合
Galaxy:
- BurpSuite插件,可在请求/响应流转过程中插入自定义处理逻辑
- 支持请求/响应自动加解密
- GitHub: https://github.com/outlaws-bai/Galaxy
JsRpc:
- 通过WebSocket与浏览器客户端通信
- 可直接调用浏览器中的JavaScript函数
- 避免逆向复杂的加密逻辑
- GitHub: https://github.com/jxhczhl/JsRpc
二、环境准备
2.1 测试环境
- 靶场地址: http://39.98.108.20:8085/
- 加密特征:
- 请求头包含三个关键参数:requestId、timestamp、sign
- POST请求体使用AES CBC模式加密
- 签名机制:MD5(请求数据 + timestamp + requestId)
2.2 工具安装
- 安装BurpSuite
- 安装Galaxy插件
- 部署JsRpc服务端
- 在目标网站注入JsRpc客户端脚本
三、技术实现步骤
3.1 JS逆向分析
-
定位加密相关JavaScript代码:
requestId由函数p()生成timestamp通过Date.parse(new Date)获取sign使用a.a.MD5函数处理- 数据加密使用
l(n)函数(AES CBC)
-
关键加密参数:
key = "1234567891234567" iv = "1234567891234567"
3.2 JsRpc客户端注入
-
在浏览器控制台注册关键函数:
window.requestId = p; // requestId生成函数 window.v1 = v; // 数据处理函数 window.sign = a.a.MD5; // 签名函数 -
注册JsRpc调用接口:
demo.regAction("hello", function(resolve, param) { n = JSON.stringify(v1(param)); var time = Date.parse(new Date); var id = requestId(); var sg = sign(n + id + time).toString(); var data = { "time": "", "id": "", "sign": "" }; data["time"] = time.toString(); data["id"] = id; data["sign"] = sg; resolve(data); });
3.3 Galaxy配置与脚本编写
3.3.1 基础配置
ALGORITHM = "AES/CBC/PKCS5Padding"
secret = b"1234567891234567"
iv = b"1234567891234567"
paramMap = {"iv": iv}
jsonKey = "data"
3.3.2 关键Hook函数
-
请求到达Burp时解密 (
hook_request_to_burp):def hook_request_to_burp(request): if (request.getMethod() == "GET"): return request else: encryptedData = CodeUtil.b64decode(request.getBody()) data = decrypt(encryptedData) request.setContent(data) return request -
请求发送到服务器前加密 (
hook_request_to_server):def hook_request_to_server(request): if (request.getMethod() == "GET"): burpRequestBody = '' url = "http://127.0.0.1:12080/go?group=zzz&action=hello¶m=" jsrpcUrl = url + burpRequestBody jsrpcRequest = request.of(jsrpcUrl) jsrpcRespone = HttpClient.send(jsrpcRequest) jsrpcResponeJson = jsrpcRespone.getJson() headData = jsrpcResponeJson["data"] headData = json.loads(headData) time = headData["time"] requestId = headData["id"] sign = headData["sign"] head = request.getHeaders() head.put("sign", sign) head.put("requestId", requestId) head.put("timestamp", time) request.setHeaders(head) return request else: data = request.getContent() burpRequestBody = request.getBody() url = "http://127.0.0.1:12080/go?group=zzz&action=hello¶m=" jsrpcUrl = url + burpRequestBody jsrpcRequest = request.of(jsrpcUrl) jsrpcRespone = HttpClient.send(jsrpcRequest) jsrpcResponeJson = jsrpcRespone.getJson() headData = jsrpcResponeJson["data"] headData = json.loads(headData) time = headData["time"] requestId = headData["id"] sign = headData["sign"] head = request.getHeaders() head.put("sign", sign) head.put("requestId", requestId) head.put("timestamp", time) request.setHeaders(head) encryptedData = encrypt(data) body = CodeUtil.b64encode(encryptedData) request.setContent(body) log.info("header2: {}", request) return request -
响应到达Burp时解密 (
hook_response_to_burp):def hook_response_to_burp(response): encryptedData = CodeUtil.b64decode(response.getBody()) data = decrypt(encryptedData) response.setContent(data) return response -
响应返回客户端前加密 (
hook_response_to_client):def hook_response_to_client(response): data = response.getContent() encryptedData = encrypt(data) body = CodeUtil.b64encode(encryptedData) response.setContent(body) return response
3.4 加解密函数
def decrypt(content):
return CryptoUtil.aesDecrypt(ALGORITHM, content, secret, paramMap)
def encrypt(content):
return CryptoUtil.aesEncrypt(ALGORITHM, content, secret, paramMap)
四、技术实现原理
4.1 工作流程
-
请求流程:
- 客户端发送加密请求 → Burp(Galaxy解密) → 测试人员查看明文
- 测试人员修改请求 → Galaxy调用JsRpc获取新签名 → Galaxy加密请求 → 发送到服务器
-
响应流程:
- 服务器返回加密响应 → Burp(Galaxy解密) → 测试人员查看明文
- 测试人员修改响应 → Galaxy加密响应 → 返回给客户端
4.2 关键技术点
-
签名自动更新:
- 通过JsRpc调用浏览器中的原始签名函数
- 确保每次请求的签名有效
-
加解密处理:
- Galaxy使用与客户端相同的加密算法和密钥
- 自动识别GET/POST请求差异处理
-
请求头更新:
- 自动更新timestamp、requestId和sign
- 保持请求头与签名的一致性
五、注意事项与优化建议
-
性能考虑:
- JsRpc调用会增加请求处理时间
- 可缓存短时间内有效的签名
-
错误处理:
- 添加JsRpc调用失败的回退机制
- 记录加解密失败日志
-
扩展性:
- 可支持多种加密算法
- 可配置不同API的签名规则
-
安全考虑:
- 保护JsRpc服务端,防止未授权访问
- 加密密钥应妥善保管
六、完整脚本示例
参见原文提供的完整Galaxy hook脚本,包含所有必要函数和导入声明。
七、参考资料
- Galaxy文档: https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md
- JsRpc项目: https://github.com/jxhczhl/JsRpc
- Galaxy基础教程: https://xz.aliyun.com/t/15051
通过本方案,安全测试人员可以高效处理加密API的测试工作,无需手动解密/加密或担心签名失效问题,大幅提升测试效率。