1. 项目概述为什么我们需要在BurpSuite里搞加解密做Web安全测试的朋友对BurpSuite这个“瑞士军刀”肯定不陌生。抓包、改包、重放、爆破这些常规操作大家都很熟。但近几年随着应用安全意识的提升越来越多的App和Web接口开始对传输的数据进行加密。你抓到的包不再是明文的usernameadminpassword123456而是一串像U2FsdGVkX1...或者7a8f9b3c1d2e...这样的天书。这时候BurpSuite自带的那些功能就有点“抓瞎”了——你没法直接修改一个加密后的参数值去爆破也没法直观地看到请求和响应的真实内容。这就是我们今天要解决的痛点如何让BurpSuite具备实时加解密流量特别是AES_CBC这种常见对称加密算法的能力答案就是利用BurpSuite强大的扩展性通过插件来实现。而Galaxy插件正是BurpSuite官方插件商店BApp Store里一款专门用于处理加解密流量的利器。它本身不提供具体的加解密算法而是扮演一个“调度中心”的角色允许你通过编写外部脚本比如Python、Java来定义加解密逻辑然后BurpSuite在流量经过时自动调用这些脚本进行处理。简单来说这个项目的核心就是用Python写一个AES_CBC加解密的脚本服务然后配置Galaxy插件去调用它从而实现对BurpSuite中经过的加密请求和响应进行自动解密、修改、再加密的全流程自动化。这不仅能让你在测试加密接口时“重见光明”还能将自动化渗透测试如爆破、扫描的能力延伸到加密场景中极大提升测试效率。2. 核心原理与工具选型为什么是AES_CBC和Galaxy在动手之前我们得先搞清楚两件事一是目标加密算法AES_CBC是什么二是为什么选择Galaxy插件而不是其他方案。2.1 AES_CBC算法浅析AES高级加密标准是目前应用最广泛的对称加密算法之一而CBC密码分组链接是其最常见的一种工作模式。对称加密加密和解密使用同一把密钥。这就要求测试者和服务器拥有相同的密钥通常通过逆向客户端、分析JS代码或协议文档来获取。CBC模式这种模式的特点是每个明文块在加密前会先与前一个密文块进行异或操作。对于第一个块则需要一个初始化向量IV。IV不需要保密但必须不可预测通常随机生成且每次加密都应不同以保证相同的明文加密后产生不同的密文增强安全性。一个典型的AES_CBC加密过程需要以下几个关键参数密钥Key长度可以是128位16字节、192位24字节或256位32字节。初始化向量IV固定为16字节128位需要与密文一起传输或双方约定。明文需要加密的数据。如果数据长度不是16字节的整数倍需要进行填充Padding最常用的是PKCS7填充。密文加密后的输出通常是Base64或Hex编码的字符串。在安全测试中我们遇到的接口数据往往是JSON或表单数据被整体加密成一个Base64字符串放在HTTP Body里。我们的任务就是把这个字符串解密出来修改里面的某个值比如密码再重新加密回去。2.2 Galaxy插件与其他方案的对比BurpSuite处理自定义加解密主要有几种思路手动加解密工具手动替换用外部工具如CyberChef、在线网站、自己写的脚本解密复制明文到BurpSuite里修改再加密后复制回去。效率极低无法自动化。使用Burp Custom Crypto等插件有些插件内置了常见算法配置相对简单。但灵活性差遇到非标准或自定义的加密流程比如密钥不是直接给出而是经过几次哈希变换就无能为力。编写完整的BurpSuite Extender插件Java最灵活性能最好。但门槛高需要熟悉Java和Burp的API开发调试周期长。使用Galaxy插件 外部脚本这正是我们选择的方案。它的优势非常明显门槛低你可以用你最熟悉的语言写加解密逻辑Python、Ruby、Go、Java都行Galaxy通过HTTP/进程间通信调用你的脚本。灵活性强脚本里你可以写任何逻辑不仅仅是标准AES任何自定义的、魔改的加密算法都能处理。隔离性好加解密脚本运行在独立的进程即使脚本崩溃也不会导致BurpSuite主程序挂掉。复用性高写好的Python脚本本身就是一个独立的加解密工具可以在其他地方使用。注意Galaxy插件在BurpSuite社区版免费版中可能无法从BApp Store直接安装因为它属于“专业”插件。你需要使用专业版或者寻找其他方式获取插件Jar文件。这是使用Galaxy前需要确认的第一件事。3. 环境准备与工具安装工欲善其事必先利其器。我们先来把所需的工具和环境搭建好。3.1 BurpSuite与Galaxy插件安装安装BurpSuite从PortSwigger官网下载最新版。建议使用专业版以获得完整功能和支持。安装过程很简单一路下一步即可。安装Galaxy插件打开BurpSuite进入Extender标签页 -BApp Store。在搜索框中输入 “Galaxy”找到 “Galaxy – Crypto / Hash Handler” 这个插件。点击 “Install” 进行安装。如果安装失败社区版常见你需要手动下载插件的Jar文件。手动安装从可靠的来源如GitHub仓库或安全社区下载galaxy.jar文件。然后在Extender-Extensions-Add选择Extension type为Java然后加载你下载的Jar文件。安装成功后你会在BurpSuite顶部菜单栏看到一个新的Galaxy菜单这就说明插件加载成功了。3.2 Python环境与依赖库我们的加解密脚本将使用Python编写因为它语法简洁密码学库丰富。安装Python前往Python官网下载并安装Python 3.6及以上版本。安装时务必勾选 “Add Python to PATH”。安装密码学库我们主要使用pycryptodome库它是PyCrypto的一个流行分支维护更活跃功能也更完善。打开命令行CMD或Terminal执行以下命令安装pip install pycryptodome如果安装速度慢可以使用国内镜像源例如pip install pycryptodome -i https://pypi.tuna.tsinghua.edu.cn/simple验证安装在Python交互环境中输入from Crypto.Cipher import AES如果没有报错说明安装成功。4. 核心脚本编写一个健壮的AES_CBC加解密服务Galaxy插件支持两种方式与外部脚本交互HTTP Server和Process-based。这里我们选择HTTP Server模式因为它更通用脚本可以运行在任何地方本地或远程服务器且通信过程清晰易于调试。我们的Python脚本需要实现一个简单的HTTP服务器接收Galaxy发送过来的JSON数据根据其中的指令“operation”进行加密或解密然后将结果返回。4.1 脚本架构设计脚本需要处理以下核心逻辑启动一个HTTP服务监听特定端口如8080。定义请求处理函数解析Galaxy发送的POST请求。解析JSON请求体获取操作类型encrypt/decrypt、数据、密钥、IV等参数。实现AES_CBC加解密函数正确处理PKCS7填充。将结果封装成JSON格式返回给Galaxy。下面是一个完整、健壮且带有详细注释的脚本aes_cbc_server.py#!/usr/bin/env python3 # -*- coding: utf-8 -*- BurpSuite Galaxy插件 AES-CBC 加解密服务端脚本 运行python aes_cbc_server.py 默认监听 0.0.0.0:8080 import json import base64 from http.server import HTTPServer, BaseHTTPRequestHandler from urllib.parse import urlparse from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad import logging # 配置日志方便查看运行状态和错误 logging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s) logger logging.getLogger(__name__) class AES_CBC_Handler: AES-CBC 加解密核心处理类 staticmethod def decrypt(ciphertext_b64, key_b64, iv_b64): AES-CBC 解密 :param ciphertext_b64: Base64编码的密文 :param key_b64: Base64编码的密钥 :param iv_b64: Base64编码的初始化向量 :return: 解密后的明文字符串 try: # 1. Base64解码 ciphertext base64.b64decode(ciphertext_b64) key base64.b64decode(key_b64) iv base64.b64decode(iv_b64) # 2. 创建AES解密器 cipher AES.new(key, AES.MODE_CBC, iv) # 3. 解密并去除PKCS7填充 decrypted_data unpad(cipher.decrypt(ciphertext), AES.block_size) # 4. 将字节串转换为字符串假设原文是UTF-8编码的文本如JSON return decrypted_data.decode(utf-8) except Exception as e: logger.error(f解密失败: {e}) raise ValueError(f解密过程出错: {e}) staticmethod def encrypt(plaintext, key_b64, iv_b64): AES-CBC 加密 :param plaintext: 明文字符串 :param key_b64: Base64编码的密钥 :param iv_b64: Base64编码的初始化向量 :return: Base64编码的密文 try: # 1. Base64解码密钥和IV key base64.b64decode(key_b64) iv base64.b64decode(iv_b64) # 2. 将明文转换为字节串并进行PKCS7填充 plaintext_bytes plaintext.encode(utf-8) padded_data pad(plaintext_bytes, AES.block_size) # 3. 创建AES加密器并加密 cipher AES.new(key, AES.MODE_CBC, iv) ciphertext cipher.encrypt(padded_data) # 4. 将密文进行Base64编码 return base64.b64encode(ciphertext).decode(utf-8) except Exception as e: logger.error(f加密失败: {e}) raise ValueError(f加密过程出错: {e}) class GalaxyRequestHandler(BaseHTTPRequestHandler): 处理Galaxy插件HTTP请求的处理器 def _set_response(self, status_code200, content_typeapplication/json): 设置HTTP响应头 self.send_response(status_code) self.send_header(Content-type, content_type) self.send_header(Access-Control-Allow-Origin, *) # 简单处理CORS self.end_headers() def do_POST(self): 处理POST请求这是Galaxy插件调用我们的入口 content_length int(self.headers.get(Content-Length, 0)) if content_length 0: self._set_response(400) self.wfile.write(b{error: Empty request body}) return try: # 1. 读取并解析请求体JSON格式 post_data self.rfile.read(content_length) request_json json.loads(post_data.decode(utf-8)) logger.info(f收到请求: {json.dumps(request_json, indent2)}) # 2. 提取必要参数 operation request_json.get(operation) # encrypt 或 decrypt data request_json.get(data) # 要处理的数据明文或密文 key request_json.get(key) # Base64编码的密钥 iv request_json.get(iv) # Base64编码的IV # 3. 参数校验 if not all([operation, data, key, iv]): missing [k for k in [operation, data, key, iv] if not request_json.get(k)] error_msg f缺少必要参数: {missing} logger.warning(error_msg) self._set_response(400) self.wfile.write(json.dumps({error: error_msg}).encode()) return # 4. 根据操作类型调用相应的加解密函数 result None if operation.lower() decrypt: result AES_CBC_Handler.decrypt(data, key, iv) elif operation.lower() encrypt: result AES_CBC_Handler.encrypt(data, key, iv) else: error_msg f不支持的操作类型: {operation} logger.warning(error_msg) self._set_response(400) self.wfile.write(json.dumps({error: error_msg}).encode()) return # 5. 构造成功响应 response { success: True, result: result, operation: operation } response_body json.dumps(response, ensure_asciiFalse) self._set_response(200) self.wfile.write(response_body.encode(utf-8)) logger.info(f请求处理成功操作: {operation}) except json.JSONDecodeError as e: error_msg f无效的JSON格式: {e} logger.error(error_msg) self._set_response(400) self.wfile.write(json.dumps({error: error_msg}).encode()) except ValueError as e: # 捕获加解密过程中的错误 error_msg str(e) logger.error(error_msg) self._set_response(500) self.wfile.write(json.dumps({error: error_msg}).encode()) except Exception as e: error_msg f服务器内部错误: {e} logger.exception(error_msg) # 打印完整堆栈信息 self._set_response(500) self.wfile.write(json.dumps({error: error_msg}).encode()) def log_message(self, format, *args): 重写日志方法使用我们配置的logger logger.info(%s - %s % (self.address_string(), format%args)) def run_server(server_classHTTPServer, handler_classGalaxyRequestHandler, port8080, host0.0.0.0): 启动HTTP服务器 server_address (host, port) httpd server_class(server_address, handler_class) logger.info(f启动AES-CBC加解密服务在 http://{host}:{port}) try: httpd.serve_forever() except KeyboardInterrupt: logger.info(服务器被用户中断) finally: httpd.server_close() logger.info(服务器已关闭) if __name__ __main__: # 你可以在这里修改监听的主机和端口 run_server(port8080, host0.0.0.0)4.2 脚本关键点解析与避坑指南编码与填充编码我们假设客户端被测试的App和服务端传输时对密文使用了Base64编码。这是最常见的做法因为HTTP协议是文本协议直接传输二进制字节流不方便。如果你的目标使用的是Hex十六进制编码只需将脚本中的base64.b64decode/b64encode替换为bytes.fromhex/bytes.hex即可。填充AES是块加密算法要求明文长度是16字节的整数倍。PKCS7填充是标准做法。pycryptodome的pad和unpad函数帮我们自动处理了这一点。务必确保你的脚本和服务端使用的填充模式一致否则解密会失败。密钥和IV的格式脚本中我们要求密钥Key和IV也以Base64格式传入。这是因为Galaxy插件配置界面输入的是字符串Base64是一种方便的表示二进制数据为字符串的方式。在实际测试中你获取到的密钥和IV可能是Hex字符串或直接就是原始字节。你需要根据实际情况在Galaxy配置或脚本中进行转换。一个常见的坑是密钥长度不对。AES-128密钥是16字节AES-256是32字节。如果你拿到一个32位的Hex字符串64个十六进制字符那它实际上是16字节对应AES-128。错误处理与日志脚本中加入了详细的异常捕获和日志记录。这在调试阶段至关重要。当Galaxy调用失败时你可以查看脚本输出的日志快速定位是参数错误、加解密算法错误还是网络问题。HTTP服务器返回了结构化的JSON错误信息Galaxy插件会显示这些错误方便你排查。运行脚本将上面的代码保存为aes_cbc_server.py。在命令行中运行python aes_cbc_server.py。你应该看到输出启动AES-CBC加解密服务在 http://0.0.0.0:8080。保持这个命令行窗口打开。5. Galaxy插件配置详解脚本服务跑起来了现在需要告诉Galaxy插件怎么去调用它。打开Galaxy配置界面在BurpSuite顶部菜单栏点击Galaxy-Configure Galaxy。会弹出一个配置窗口。创建新的Crypto Handler在配置窗口左侧点击Add按钮。会弹出一个新的处理器配置窗口。配置处理器参数Name给你这个处理器起个名字比如AES-CBC-Test-API。Type选择HTTP。这就是我们上面写的HTTP服务器模式。URL填写你的Python脚本服务地址例如http://127.0.0.1:8080。确保BurpSuite能访问到这个地址。Operation field填写operation。这告诉Galaxy它在发送的JSON数据中用哪个字段来标识是加密还是解密操作。我们的脚本正是读取这个字段。Data field填写data。这是存放待处理数据明文或密文的字段名。Result field填写result。这是我们的脚本返回的JSON中存放处理结果的字段名。查看我们脚本的响应格式{success: True, result: ...}所以这里填result。Additional Data这是最关键的部分用于传递固定的参数比如密钥和IV。点击Add添加两条数据Name:key,Value:你的Base64编码的密钥。例如如果原始密钥是16个字节的0123456789abcdef那么它的Base64编码是MTIzNDU2Nzg5YWJjZGVm注意这里是示例不是有效的AES密钥。Name:iv,Value:你的Base64编码的IV。例如MTIzNDU2Nzg5YWJjZGVm。重要这里的Value就是固定值。Galaxy在每次调用脚本时会把这里定义的键值对合并到它生成的JSON请求体中。所以我们的脚本才能收到key和iv参数。测试连接在配置窗口下方有两个测试区域Encryption test和Decryption test。在Decryption test的Input里粘贴一段你从抓包中获取的、已知明文对应的密文Base64格式。点击Test按钮。Galaxy会向你的脚本服务发送一个测试请求。如果一切配置正确你会在Output里看到解密后的明文。同时你的Python脚本命令行窗口也会打印出收到的请求和处理的日志。同样可以在Encryption test中输入一段明文测试加密功能是否正常。保存并应用测试通过后点击OK保存这个处理器配置。回到主配置窗口确保你的处理器处于勾选启用状态然后点击OK关闭配置窗口。实操心得在Additional Data里配置密钥和IV是最常见的方式但这意味着密钥是硬编码在BurpSuite配置里的。如果不同请求的IV是动态变化的比如每次加密随机生成并放在请求体的另一个字段里这种静态配置就不行了。对于这种情况Galaxy支持更高级的“动态参数”功能可以从HTTP请求/响应的其他部分如Header、Cookie、Body的某个JSON字段提取IV值。这需要在配置窗口的Dynamic additional data部分进行设置通常需要写一点简单的正则表达式或JSON路径来提取值。这是Galaxy插件更强大的地方也是应对复杂加密场景的必备技能。6. 实战应用让加解密在BurpSuite中自动运行配置好之后Galaxy插件就可以在BurpSuite的各个模块中生效了。它的工作原理是“拦截-处理-放行”。6.1 在Proxy代理中实时查看加解密流量这是最直观的应用。打开BurpSuite的Proxy-Intercept标签确保拦截是开启的。让你的手机或浏览器代理到BurpSuite触发一个加密的API请求。请求会被拦截在BurpSuite中。此时你看到的是加密后的原始数据一个Base64字符串。在拦截面板的右侧你会发现多了一个Galaxy标签页。点击Galaxy标签你会看到两个子标签Request和Response。在Request标签下Galaxy会自动调用你配置的解密处理器将加密的Body解密并显示出来。现在你可以像修改普通请求一样修改解密后的明文比如把password从test123改成admin123。修改完成后点击Forward转发请求。关键来了Galaxy会在请求发出前自动将你修改过的明文重新加密成密文也就是说你始终在操作明文但实际发送出去的是加密后的数据完全无缝。同样服务器的加密响应回来时在Response的Galaxy标签下你也能看到解密后的明文内容。这个过程完全自动化你无需手动进行任何加解密操作就像在测试一个未加密的接口一样。6.2 在Intruder入侵者中爆破加密参数这是Galaxy插件威力最大的地方。传统上爆破一个加密参数几乎是不可能的任务因为你需要为每一个Payload单独加密。现在Galaxy可以帮你自动化完成。抓包并发送到Intruder在Proxy历史记录或Target站点地图中找到你的加密请求右键Send to Intruder。设置攻击类型和位置在Intruder的Positions标签通常选择Sniper或Pitchfork攻击类型。像普通请求一样在解密后的明文视图确保Galaxy标签页激活中选中你想要爆破的参数值比如password字段的值点击Add §添加Payload位置。注意你必须在Galaxy解密后的视图中添加Payload标记。如果你在原始加密视图Raw标签中添加标记会被插入到Base64字符串中间导致数据损坏加解密都会失败。配置Payload切换到Payloads标签配置你的字典比如常见的弱口令列表。关键启用Galaxy处理器在Payloads标签页的最下方有一个Payload Processing区域。点击Add在规则类型中选择Invoke Galaxy item。然后在弹出的选择器中选择你刚才配置好的AES-CBC-Test-API处理器并选择Encrypt操作。这意味着什么Intruder会为Payload列表中的每一个候选值明文密码先调用Galaxy处理器将其加密然后用加密后的结果去替换请求中的Payload位置。开始攻击点击Start attack。你会看到Intruder窗口里每次攻击发送的请求其Body中的密文都是不同的因为对应不同的明文密码加密而成。你可以根据长度、状态码、响应时间或解密后的响应内容来判断爆破结果。6.3 在Repeater重放器中手动测试在Repeater中测试加密接口也变得极其简单。将加密请求发送到Repeater。在Repeater界面同样会有一个Galaxy标签页。你可以在这里查看和编辑解密后的请求。修改明文后点击SendRepeater会自动加密并发送。在响应部分也能在Galaxy标签下查看解密后的响应体。7. 常见问题排查与进阶技巧即使按照步骤操作你也可能会遇到一些问题。这里总结一些常见的坑和解决方法。7.1 问题排查清单问题现象可能原因排查步骤Galaxy标签页不显示或为空白1. Galaxy插件未正确安装或启用。2. 当前请求/响应格式未被识别如非HTTP或Content-Type不匹配。3. 处理器配置错误或未启用。1. 检查Extender中Galaxy插件状态。2. 检查请求是否为HTTP/HTTPS且BurpSuite能正常解析。3. 检查Galaxy主配置确保对应的处理器已勾选。测试时返回错误如解密失败1. 密钥、IV错误。2. 密文/明文编码问题不是Base64。3. 填充模式不一致。4. 算法模式不是CBC可能是ECB, GCM。5. Python脚本服务未启动或端口被占用。1.核对密钥和IV确保与客户端使用的完全一致。用其他工具如在线AES工具验证你的密钥/IV能否解密已知密文。2.检查编码确认数据是Base64。尝试先用Base64解码看看是否是乱码。3.查看脚本日志Python命令行窗口会打印详细错误是首要排查点。4.网络连通性在浏览器访问http://127.0.0.1:8080看是否有响应应返回405错误因为只处理POST。Intruder攻击时所有请求都失败或返回相同错误1. Payload位置标记加错了地方加在了Raw视图的密文里。2. Galaxy的Payload Processing规则没添加或选错了处理器/操作。1.务必在Galaxy解密视图下添加Payload标记。2. 检查Intruder的Payload Processing规则确保添加了Invoke Galaxy item且选择了正确的处理器和Encrypt操作。加解密速度慢1. Python脚本性能问题对于高强度爆破单线程HTTP服务可能成为瓶颈。2. 网络环路如果Galaxy配置的URL是127.0.0.1则无此问题。1. 对于爆破场景可以考虑使用Process-based模式减少HTTP开销。这需要修改脚本从HTTP服务器改为从标准输入输出读取JSON行。Galaxy配置时Type选Process并指定Python解释器和脚本路径。2. 优化Python代码避免不必要的初始化。7.2 进阶技巧与场景扩展处理动态IV如果每次请求的IV都不同并放在请求体的一个字段里例如iv: xxxx, data: yyyy。你需要在Galaxy处理器配置中使用Dynamic additional data。在配置窗口找到这部分添加一条规则。Name填iv对应脚本参数。From选择Request body。Expression填一个正则表达式来提取IV值比如如果IV在JSON中可以用正则iv\s*:\s*([^])。这样Galaxy会在每次请求时实时从请求体中提取IV并传递给脚本。密钥派生有时密钥不是直接给出的而是通过密码Password经过PBKDF2、SHA256等算法派生Derive出来的。你可以在Python脚本中实现这个派生过程而不是在Galaxy里配置原始密钥。这样你在Galaxy中配置的key参数实际上可以是密码脚本收到后先进行密钥派生再进行加解密。多算法/多接口支持一个Python脚本可以同时支持多种算法。你可以在Galaxy的请求JSON中添加一个algorithm字段脚本根据这个字段选择不同的加解密分支。或者更清晰的做法是为不同的接口创建不同的Galaxy处理器每个处理器指向同一个脚本服务但使用不同的URL路径如/decrypt/aes,/decrypt/des脚本根据路径来区分逻辑。脚本部署到远程服务器将aes_cbc_server.py部署到一台Linux服务器上并使用systemd或supervisor将其作为守护进程运行。然后在Galaxy配置中将URL改为服务器的公网IP和端口。这样团队内的所有测试人员都可以共享这一套加解密服务保证密钥和算法的一致性。这个基于Galaxy插件和Python脚本的AES_CBC加解密方案彻底打破了加密流量对安全测试的壁垒。它不仅仅是一个工具的使用教程更提供了一种应对加密通信的通用方法论通过外部脚本实现灵活的解密逻辑利用中间代理的插件架构实现自动化集成。掌握了这个方法无论是面对AES、DES、RSA还是各种自定义的魔改算法你都能快速构建出对应的测试环境让BurpSuite这把利器在加密的世界里同样所向披靡。在实际项目中最花时间的往往不是写脚本而是通过逆向分析或沟通确定目标系统使用的加密算法、密钥、IV和编码方式这些细节而这正是安全测试工程师核心价值的体现。