Galaxy插件实战:Burpsuite加密流量自动化测试与Hook脚本编写指南

📅 2026/7/5 9:41:56
Galaxy插件实战:Burpsuite加密流量自动化测试与Hook脚本编写指南
1. 项目概述为什么你需要Galaxy这个“解密翻译官”如果你在渗透测试或者安全审计中遇到过这样的场景打开Burpsuite拦截到的请求和响应全是看不懂的密文像天书一样常规的SQL注入、XSS测试根本无从下手那你一定明白那种抓耳挠腮的无力感。现代Web应用尤其是金融、电商、游戏类应用为了对抗中间人攻击和流量分析普遍会对关键业务接口的通信数据进行加密。这就像给目标穿上了一层厚厚的盔甲你的扫描器和手动测试工具都成了“睁眼瞎”。Galaxy插件就是为了解决这个痛点而生的。你可以把它理解成Burpsuite和加密流量之间的“实时翻译官”。它的核心目标就是让你测试加密流量像测试明文一样简单高效。你不再需要手动复制密文到外部脚本解密再手动加密回填Galaxy能自动在Burpsuite内部完成这个加解密过程让你看到的、操作的始终是明文的请求和响应。这对于提升渗透测试效率尤其是面对复杂加密逻辑的应用时是革命性的。2. Galaxy核心工作原理与架构拆解要玩转Galaxy不能只停留在“点一下就用”的层面。理解它的工作原理能帮助你在遇到复杂场景时自己定位问题甚至写出更强大的Hook脚本。2.1 核心工作流插件如何“劫持”Burpsuite的数据流Galaxy本质上是一个Burpsuite Extender插件它通过实现Burp的IHttpListener、IScannerCheck等接口深度嵌入了Burpsuite的数据处理流程。其核心工作流可以概括为以下几个步骤流量拦截当HTTP/HTTPS流量经过Burpsuite的Proxy模块时Galaxy会首先拦截到原始的请求和响应数据。Hook脚本执行Galaxy会调用你预先编写并配置好的JavaScript Hook脚本。这个脚本是你定义加解密逻辑的地方。请求解密/响应加密对于从客户端发往服务器的请求Hook脚本执行beforeRequest函数将拦截到的密文请求体解密为明文。Galaxy会用这个明文替换掉原始的密文再转发给Burpsuite的后续模块如Scanner、Intruder或目标服务器。对于从服务器返回的响应Hook脚本执行beforeResponse函数将服务器返回的明文响应体按照约定加密成密文再返回给客户端浏览器或APP。双向透明化处理经过上述步骤在Burpsuite的界面如Proxy history、Repeater里你看到和编辑的始终是明文。而实际网络上流动的以及客户端和服务器收到的依然是符合预期的密文。整个过程对测试者和被测试应用都是“透明”的。注意这里有一个关键点Galaxy默认处理的是HTTP Body消息体。对于URL参数、Cookie、Header的加解密需要在Hook脚本中特别处理通常需要操作request或response对象的完整字节数组。2.2 Hook脚本加解密逻辑的“灵魂”Hook脚本是Galaxy能力的核心它是一段JavaScript代码定义了如何解密和加密。Galaxy通过内置的JavaScript引擎如Nashorn或GraalVM来执行它。一个最基本的Hook脚本结构如下// 定义全局变量或加解密函数例如一个简单的AES-ECB解密仅示例实际算法复杂得多 var CryptoJS require(crypto-js); // Galaxy内置了CryptoJS库 function decrypt(data, key) { // 你的解密逻辑data是Base64编码的密文字符串 var bytes CryptoJS.AES.decrypt(data, CryptoJS.enc.Utf8.parse(key)); return bytes.toString(CryptoJS.enc.Utf8); } function encrypt(data, key) { // 你的加密逻辑 var encrypted CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(data), CryptoJS.enc.Utf8.parse(key)); return encrypted.toString(); } // Galaxy约定的入口函数 function beforeRequest(plainRequest) { // plainRequest 是Galaxy提供的工具对象包含请求信息 var body plainRequest.getBodyAsString(); // 获取请求体此时已是Galaxy处理后的状态初次可能是密文 // 判断是否需要解密例如通过URL路径或Content-Type if (plainRequest.getUrl().contains(/api/secure)) { var decryptedBody decrypt(body, your-secret-key-here); plainRequest.setBody(decryptedBody); // 设置解密后的明文请求体 // 有时解密后需要更新Content-Length头 plainRequest.getHeaders().removeHeader(Content-Length); plainRequest.getHeaders().addHeader(Content-Length: decryptedBody.length); } return plainRequest; // 返回修改后的请求对象 } function beforeResponse(plainResponse) { var body plainResponse.getBodyAsString(); // 获取响应体服务器返回的明文 if (plainResponse.getUrl().contains(/api/secure)) { var encryptedBody encrypt(body, your-secret-key-here); plainResponse.setBody(encryptedBody); plainResponse.getHeaders().removeHeader(Content-Length); plainResponse.getHeaders().addHeader(Content-Length: encryptedBody.length); } return plainResponse; }关键理解beforeRequest和beforeResponse函数的参数plainRequest,plainResponse是Galaxy封装的对象它已经对原始HTTP报文进行了解析。你可以通过它们的方法getUrl(),getHeaders(),getBodyAsString()获取信息并通过setBody()等方法进行修改。你的加解密逻辑就作用在这些Body字符串上。3. 实战部署从安装到第一个Hook的完整流程理论懂了我们动手把它装起来并配置一个最简单的Hook来感受一下。3.1 环境准备与插件安装首先确保你的环境符合要求Burpsuite版本这是最重要的。Galaxy官方推荐使用Burp Suite Professional 2023.10.3.7 或更高版本。社区版由于功能限制部分高级特性如与Scanner模块的深度集成可能无法正常工作。建议使用官方正版或确保你的版本兼容。Java环境Burpsuite本身基于Java确保系统有合适的JREJava 8或更高版本推荐JDK 11。在终端输入java -version检查。下载Galaxy访问项目的GitHub Release页面通常搜索“Galaxy Burp plugin release”即可找到下载最新的.jar文件。不要从不明来源下载以防植入后门。安装步骤非常简单打开Burpsuite进入Extender标签页。点击Extensions子标签下的Add按钮。在弹窗中将Extension type选择为Java。点击Select file...找到你下载的Galaxy-xxx.jar文件并选中。点击NextBurpsuite会加载插件。如果一切正常你会看到输出区域显示加载成功并且在Extender的“Loaded”列表中出现“Galaxy”同时顶部菜单栏会多出一个Galaxy菜单项。实操心得安装后如果Burpsuite卡住或报错首先检查Burp版本是否过低。其次尝试重启Burpsuite。如果问题依旧可以去项目的GitHub Issues页面搜索相关错误信息大概率已有解决方案。3.2 编写你的第一个Hook脚本以Base64编码为例我们从一个最简单的“加解密”场景开始目标网站对请求体和响应体做了Base64编码。虽然Base64不是加密但Galaxy的处理流程完全一致非常适合入门。启用Galaxy并新建Hook点击顶部菜单栏的Galaxy-Config或直接在Extender标签页点击Galaxy插件的Output或Errors标签旁的Config按钮。这会打开Galaxy的主配置界面。点击下方的“”号按钮新建一个Hook配置。给它起个名字比如Demo_Base64。编写Hook脚本在配置界面的大文本框中输入以下JavaScript代码// 简单的Base64“加解密”Hook function beforeRequest(plainRequest) { var body plainRequest.getBodyAsString(); // 假设我们对 /api/data 接口的请求体进行Base64解码 if (plainRequest.getUrl().contains(/api/data) body) { try { // 将Base64编码的请求体解码为明文 var decodedBody java.util.Base64.getDecoder().decode(body); plainRequest.setBody(String(new java.lang.String(decodedBody, UTF-8))); // 更新Content-Length plainRequest.getHeaders().removeHeader(Content-Length); plainRequest.getHeaders().addHeader(Content-Length: plainRequest.getBody().length); } catch(e) { // 解码失败可能不是Base64原样返回 print([Galaxy Demo] Base64 decode error: e); } } return plainRequest; } function beforeResponse(plainResponse) { var body plainResponse.getBodyAsString(); if (plainResponse.getUrl().contains(/api/data) body) { // 将明文的响应体重新编码为Base64 var encodedBody java.util.Base64.getEncoder().encodeToString(body.getBytes(UTF-8)); plainResponse.setBody(encodedBody); plainResponse.getHeaders().removeHeader(Content-Length); plainResponse.getHeaders().addHeader(Content-Length: encodedBody.length); } return plainResponse; }这段代码做了两件事当请求URL包含/api/data时将请求体从Base64解码为明文将服务器的明文响应重新编码为Base64后返回给客户端。配置作用域Scope光有脚本还不够你需要告诉Galaxy这个Hook对哪些流量生效。在配置界面的Scope部分你可以选择“All traffic”或“Custom scope”。对于这个Demo建议先选择“Custom scope”并在包含规则中添加你目标测试站点的域名或URL例如*.example.com。这样可以避免插件处理所有流量减少不必要的性能开销和潜在错误。保存并启用点击Save保存配置。确保配置前面的复选框是勾选状态表示启用此Hook。关闭配置窗口。3.3 验证Hook是否生效现在你可以进行测试了。将浏览器或APP的代理设置为Burpsuite。访问目标网站触发一个/api/data的请求你可以用Burp的Repeater手动构造一个。在Burpsuite的Proxy - HTTP history中找到那条请求。观察Request和Response面板。如果配置正确你在这里看到的应该是解码后的明文。而通过点击“原始数据” (Raw)标签你看到的才是实际在网络上传输的Base64编码数据。恭喜你至此你已经完成了Galaxy最核心的闭环操作你成功地在Burpsuite内部建立了一条加解密通道。4. 进阶实战处理复杂加密与联动扫描器真实的加密远不止Base64。常见的可能是AES、RSA或是自定义的混淆算法。此外Galaxy的强大之处在于能让你的明文流量无缝对接其他安全工具。4.1 逆向加密算法并编写复杂Hook面对未知加密第一步是逆向。通常需要借助浏览器开发者工具F12的“源代码”(Sources)和“网络”(Network)标签或者使用Frida、Xposed等框架对移动端APP进行Hook定位到加密函数。假设通过逆向你发现目标使用AES-CBC模式加密密钥是固定的1234567890123456IV向量是abcdefghijklmnop并且数据在加密后还做了Hex编码。你的Hook脚本就需要升级// 引入Galaxy内置的CryptoJS库 var CryptoJS require(crypto-js); function decryptComplex(data) { // 假设原始数据是Hex编码的先Hex解码 var encryptedHex CryptoJS.enc.Hex.parse(data); // 转换为CryptoJS可识别的密文对象 var encryptedBase64 encryptedHex.toString(CryptoJS.enc.Base64); // AES-CBC解密参数 var key CryptoJS.enc.Utf8.parse(1234567890123456); // 16字节密钥 var iv CryptoJS.enc.Utf8.parse(abcdefghijklmnop); // 16字节IV // 解密 var decrypted CryptoJS.AES.decrypt(encryptedBase64, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 // 常见的填充方式 }); // 将解密结果转为UTF-8字符串 return decrypted.toString(CryptoJS.enc.Utf8); } function encryptComplex(data) { var key CryptoJS.enc.Utf8.parse(1234567890123456); var iv CryptoJS.enc.Utf8.parse(abcdefghijklmnop); // 加密 var encrypted CryptoJS.AES.encrypt(data, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); // 将密文从Base64格式转为Hex格式输出 return encrypted.ciphertext.toString(CryptoJS.enc.Hex); } function beforeRequest(plainRequest) { var body plainRequest.getBodyAsString(); if (isTargetApi(plainRequest.getUrl())) { // isTargetApi是你自己定义的判断函数 try { var decryptedBody decryptComplex(body); plainRequest.setBody(decryptedBody); updateContentLength(plainRequest); // 更新头部的辅助函数 } catch(e) { print([Galaxy] 请求解密失败: e); } } return plainRequest; } function beforeResponse(plainResponse) { var body plainResponse.getBodyAsString(); if (isTargetApi(plainResponse.getUrl())) { try { var encryptedBody encryptComplex(body); plainResponse.setBody(encryptedBody); updateContentLength(plainResponse); } catch(e) { print([Galaxy] 响应加密失败: e); } } return plainResponse; } // 辅助函数判断是否为需要处理的API function isTargetApi(url) { return url url.indexOf(/secure/) -1; } // 辅助函数更新Content-Length头 function updateContentLength(message) { message.getHeaders().removeHeader(Content-Length); message.getHeaders().addHeader(Content-Length: message.getBody().length); }4.2 与Sqlmap联动进行自动化SQL注入测试这是Galaxy的杀手级功能之一。当流量被解密成明文后你可以直接将这个明文请求交给Sqlmap进行自动化漏洞扫描。配置Sqlmap路径在Galaxy的配置界面Galaxy - Config找到或新建一个Hook配置。在配置底部通常会有“Sqlmap Path”的设置项。点击浏览选择你本地Sqlmap可执行文件的路径例如python /path/to/sqlmap.py或 Windows下的sqlmap.exe绝对路径。发送请求到Sqlmap在Burpsuite的任意界面如Proxy history, Repeater右键点击一条已经被Galaxy解密为明文的HTTP请求。在右键菜单中找到Galaxy或Extensions子菜单选择“Send to Sqlmap”或类似选项。Galaxy会自动将当前请求的详细信息URL、Headers、Cookie、明文Body构造成一个Sqlmap可识别的命令并弹出一个终端窗口或调用你系统的命令行来运行Sqlmap。关键优势无需手动处理加密Sqlmap接收到的就是明文它可以直接进行各种注入测试。自动处理响应Sqlmap发出的测试请求其响应在返回过程中会经过Galaxy的beforeResponse函数自动加密再传回给Sqlmap分析。Sqlmap看到的是解密后的明文响应从而能正确判断注入是否成功。保持会话通过Burpsuite的代理Sqlmap的测试请求能自动携带正确的Cookie等会话信息。4.3 与Xray联动进行全方位漏洞扫描与Sqlmap类似Galaxy也可以和长亭科技的Xray漏洞扫描器联动。配置Xray监听地址首先你需要启动Xray并让它以被动扫描模式运行监听一个端口例如127.0.0.1:7777。在Galaxy的Hook配置中找到“Xray Server”设置项填入Xray的监听地址如127.0.0.1:7777。发送请求到Xray同样在Burpsuite中右键一条明文请求选择“Send to Xray”。Galaxy会将这个请求通过HTTP协议转发到你配置的Xray服务器地址。Xray接收到这个请求后会将其加入扫描队列并开始进行包括SQL注入、XSS、命令执行、路径遍历等在内的全方位漏洞检测。联动工作流你可以配置Burpsuite的代理将全部流量转发给Xray在Xray中配置上游代理为Burp但这样会产生大量流量。更高效的方式是在测试过程中只将你认为重要的、功能性的接口请求手动右键发送给Xray进行深度扫描。Galaxy的右键菜单提供了这种精准触发的便捷性。5. 调试技巧与常见问题排坑实录在实际使用中你肯定会遇到各种问题。下面是我踩过坑后总结的一些经验和常见问题的解决方法。5.1 Hook脚本调试技巧使用print()函数输出日志在Hook脚本中print()函数输出的内容会显示在Burpsuite的Extender - Galaxy - Output标签页中。这是最重要的调试手段。在关键步骤如获取到Body后、解密前、解密后都打印一下信息可以清晰看到数据处理流程。function beforeRequest(plainRequest) { print([DEBUG] URL: plainRequest.getUrl()); var originalBody plainRequest.getBodyAsString(); print([DEBUG] Original Body (first 100 chars): originalBody.substring(0, Math.min(100, originalBody.length))); // ... 你的解密逻辑 print([DEBUG] Decrypted Body: decryptedBody); return plainRequest; }利用Burpsuite的Repeater手动测试将一条加密的请求发送到Repeater。在Repeater中你可以手动修改请求并观察Galaxy处理前后的变化。结合Output标签的打印日志能精准定位是解密逻辑错误还是加密逻辑错误亦或是Header处理有问题。分阶段验证算法先将加解密逻辑单独写在一个.js文件里用Node.js或浏览器的控制台测试确保算法本身正确无误。再将验证过的函数移植到Galaxy的Hook脚本中。5.2 常见问题与解决方案速查表问题现象可能原因排查步骤与解决方案Galaxy插件加载失败1. Burp版本过低。2. Java版本不兼容。3. 下载的Jar文件损坏。1. 升级Burpsuite到2023.10.3.7或更高。2. 尝试使用JDK 11或17。3. 重新从GitHub Release页面下载。检查Extender的Errors标签页看具体错误。Hook已启用但流量未解密1. Scope配置不正确未包含目标URL。2. Hook脚本中的URL判断逻辑有误。3. 加解密函数本身报错被try-catch静默处理。1. 检查Hook配置的Scope确保包含目标域名/IP。2. 在Hook开头用print()打印URL确认函数被触发。3. 检查Output标签页是否有JavaScript错误打印。在可能出错的地方注释掉try-catch让错误暴露出来。解密后请求乱码或报错1. 字符编码问题。解密后的字节数组转为字符串时用了错误的编码。2. 加密算法模式或填充方式不对。3. 密钥或IV错误。1. 尝试使用new java.lang.String(decryptedBytes, UTF-8)或GBK等不同编码。2. 确认逆向出的算法细节是AES-CBC还是ECB是PKCS7填充还是ZeroPadding3. 核对密钥和IV的值和格式是否是字符串是否需要Hex解码。Content-Length不正确导致服务器拒收Hook中修改了Body但没有更新Content-Length请求头。在beforeRequest和beforeResponse函数中修改Body后必须调用更新Content-Length的辅助函数见上文示例代码。联动Sqlmap/Xray失败1. Sqlmap/Xray路径配置错误。2. 系统环境变量问题如python命令找不到。3. 发送的请求本身不完整或格式不对。1. 在Galaxy配置中填写绝对路径。对于Sqlmap可以填python /absolute/path/to/sqlmap.py。2. 尝试在系统命令行中直接运行你配置的命令看是否成功。3. 确保你右键发送的请求是一个完整的、有效的HTTP请求最好从Proxy history中发送而非Repeater中未发送的。性能问题Burp变卡1. Hook脚本逻辑过于复杂或低效。2. Scope配置过宽处理了所有流量。3. 同时启用了多个重型Hook。1. 优化JavaScript代码避免在Hook中进行复杂的循环或同步网络请求。2. 将Scope精确到需要测试的域名和URL路径。3. 非必要时禁用其他插件或Hook。5.3 高级场景处理动态密钥与签名最棘手的情况是密钥动态生成或者请求体包含基于内容计算的签名如HMAC-SHA256。这要求Hook脚本不仅能加解密还要能复现客户端的密钥生成和签名逻辑。思路逆向密钥生成逻辑通过Hook客户端浏览器JS或移动端APP找到密钥是如何产生的。可能来源于一个固定的种子加上时间戳或者是一次登录会话中服务器下发的Token。在Hook中实现该逻辑将逆向出的密钥生成算法用JavaScript重写。可能需要用到Date.now()获取时间戳并进行一些运算。处理签名在beforeRequest中先解密Body得到明文P。根据明文P和动态密钥计算签名S。将签名S以某种形式如放在Header的X-Signature字段添加到请求中。注意计算签名用的明文必须是最终要发送的明文。有时签名会涵盖URL参数、特定Header和Body的组合需要完全模拟客户端行为。这部分的Hook脚本会非常复杂且高度定制化是Galaxy使用的最高阶形态。它要求测试者具备较强的逆向工程和代码能力。当成功实现时你将能完全自动化地测试这类安全性极高的接口这是手动测试无法想象的效率提升。