Burp Suite 自定义加解密实战指南
一、前言
在实际渗透测试或接口调试中,我们常常会遇到一些应用对请求参数或响应内容进行了加密处理,常规的抓包分析手段难以直接阅读原始数据。本文将以 Burp Suite 为核心搭配Galaxy插件,介绍如何通过自定义脚本,实现对加密流量的自动解密与加密,从而提升调试效率与还原真实数据的能力
二、适用场景
- 某某系统需要前端加密参数
- 接口响应为密文格式
- 小程序或APP中的通信数据需还原
- ……(任意流量经过Burp需要二次数据处理的,均可适用)
三、原理说明
正常情况下,我们通过Burp代理进行渗透测试时,流量的流转情况如图所示。(下述内容截取Galaxy项目原理)

而本插件通过 Burp 的 Montoya API
在该流程中添加了 4 个 hook,使得流量流转的情况变成下图这样。

[!流程详细]
①:HTTP请求从客户端到达Burp时被触发。你需要在此处完成请求解密的代码,这样就可以在Burp中看到明文的请求报文。
②:HTTP请求从Burp将要发送到Server时被触发。你需要在此处完成请求加密的代码,这样就可以将加密后的请求报文发送到Server。
③:HTTP响应从Server到达Burp时被触发。你需要在此处完成响应解密的代码,这样就可以在Burp中看到明文的响应报文。
④:HTTP响应从Burp将要返回到Client时被触发。你需要在此处完成响应加密的代码,这样就可以将加密后的响应报文返回给Client。
四、使用示例
1 官方示例
1 2 3
| git clone https:
python312 rsa.py
|
示:
本地0.0.0.0:5000端口启动服务

示:
burp插件配置白名单

再次抓取数据包,会发现多1个请求步骤进行处理解密操作。
示:
自动解密

1.1 python代码实现
1
| hookRequestToBurp,hookRequestToServer,hookResponseToBurp,hookResponseToClient
|

2 实战示例 md5_Salt 单向加密
下述所以操作,只限于JS加解密研究,并非说明该系统存在问题。
某网站登录接口,使用的是md5+Salt,借助Galaxy插件,将流量发到本地的http 服务端进行二次数据处理,实现参数加密。
示:

1
| 123456 -> 5dfaf08496a0704f8d18652884a4662a
|
非默认md5加密,逆向分析js加密步骤,调试发现用了md5+Salt加密。分析了当前js未进行魔改,就是原版的md5。
示:
js调试

示:
md5加密js

本次测试,为方便后续遇到的一些复杂的js情况,直接把代码扣到本地文件,直接调用加密参数。根据python脚本实现的功能接口,使用Node.js起HTTP服务,方便后续环境中如果遇到复杂的js函数,可以直接调用函数。
示:

2.1 node.js代码实现
由于是单向加密,根据Burp Suite 和Galaxy的流程图,我们只需要在数据提交到server时(②步骤),进行处理即可,其他默认返回即可。
通过将加密相关的函数扣本地input.js文件,然后调用加密函数,替换参数。
示:

示:
数据二次处理加密

后面即可正常按照平时流程进行爆破密码。

2.2 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| const express = require('express'); const bodyParser = require('body-parser'); const app = express();
const fs = require('fs'); eval(fs.readFileSync('./input.js', 'utf-8'));
app.use(bodyParser.json({ type: '*/*' }));
app.post('/hookRequestToBurp', (req, res) => { res.json(req.body); });
app.post('/hookRequestToServer', (req, res) => { try { console.log(`传入数据:\n${JSON.stringify(req.body)}`)
const contentBase64 = req.body.contentBase64; const decodedContent = Buffer.from(contentBase64, 'base64').toString('utf-8');
const urlParams = new URLSearchParams(decodedContent); console.log(urlParams.toString());
const adminPassword = urlParams.get('nadmin_password'); console.log(`nadmin_password参数:${adminPassword}`)
combined = hex_md5(hex_md5(adminPassword + 'ncsp951753456852jdkmd') + adminPassword + 'zseqsc951753mhtvhu'); console.log(`nadmin_password参数加密后:${combined}`)
urlParams.set('nadmin_password', combined);
const encodedContent = urlParams.toString(); console.log(`封装后的内容:${encodedContent}`);
const base64Encoded = Buffer.from(encodedContent, 'utf-8').toString('base64');
req.body.contentBase64 = base64Encoded;
console.log(`二次处理数据:\n${JSON.stringify(req.body)}`) res.json(req.body); } catch (err) { res.status(500).json({ error: '加密处理失败', details: err.message }); } });
app.post('/hookResponseToBurp', (req, res) => { res.json(req.body); });
app.post('/hookResponseToClient', (req, res) => { res.json(req.body); });
const PORT = 5000; app.listen(PORT, () => { console.log(`Server running on http: });
|
五、核心代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| const express = require('express'); const bodyParser = require('body-parser'); const app = express();
app.use(bodyParser.json({ type: '*/*' }));
app.post('/hookRequestToBurp', (req, res) => { res.json(req.body); });
app.post('/hookRequestToServer', (req, res) => { res.json(req.body); });
app.post('/hookResponseToBurp', (req, res) => { res.json(req.body); });
app.post('/hookResponseToClient', (req, res) => { res.json(req.body); });
const PORT = 5000; app.listen(PORT, () => { console.log(`Server running on http: });
|
参考
https://github.com/outlaws-bai/Galaxy