跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python大前端算法

前端加密靶场 encrypt-labs 环境搭建与全关卡解析

encrypt-labs 靶场提供前端加密场景的专项练习,涵盖环境搭建、工具配置及多类加密算法破解。流程包括 Docker 部署、BurpSuite 插件(Galaxy/autoDecoder)设置,以及针对 AES 固定 Key、动态 Key、RSA、DES 和签名机制的分析。通过浏览器调试定位混淆代码,编写 Python 脚本处理请求加解密,实现密码爆破与绕过验证,深入理解前端加密防护核心原理。

SqlMaster发布于 2026/4/9更新于 2026/7/2440 浏览
前端加密靶场 encrypt-labs 环境搭建与全关卡解析

在 Web 前端安全防护中,为抵御密码爆破攻击,开发人员常会在前端对登录关键参数(如签名、密码等)采用加密技术处理后再提交请求,增加了爆破的技术门槛。

而'encrypt-labs'作为专项练习靶场,用于探索这类前端加密场景下的破解思路 —— 我们需要先分析前端加密逻辑,掌握常用的解密/逆向手法,再构造符合服务端验证规则的请求,以此完成密码爆破的技术练习,理解前端加密防护的核心原理与破解要点。

1 环境搭建(Docker 混淆版)

基于 Ubuntu 24.04.3 TLS 环境。

git clone https://github.com/Ta0ing/encrypt-labs-docker.git # 修改数据库配置
cd src sudo vim database.php # 修改如下 4 行
$host='encrypt_labs_mysql';
$dbname='encrypt_labs_db';
$username='encrypt_user';
$password='encrypt_password';
# docker 镜像配置
sudo vim /etc/docker/daemon.json 
{"registry-mirrors":["https://docker.1ms.run", "https://dockerproxy.cn", "https://hub.rat.dev"]}
systemctl restart docker
# 老版本 Docker(独立安装 docker-compose)
docker-compose up -d --build
# 新版本 Docker(内置命令 compose)
docker compose up -d --build

在这里插入图片描述

访问 你的靶机 ip:82 地址,默认账户密码:admin 123456

在这里插入图片描述

2 配置插件

配置 BurpSuite 插件的目的:

  • 其实加解密可以通过任意语言的代码实现,但是我们解密后在 BurpSuite 中可以直接配置明文,更直观的进行爆破;
  • 如果不通过 BurpSuite 进行爆破,完全可以仅通过脚本来实现请求的加解密和爆破。

2.1 Galaxy

安装 BurpSuite 插件:

https://github.com/outlaws-bai/Galaxy

插件介绍:https://github.com/outlaws-bai/Galaxy/wiki/%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3

在这里插入图片描述

下载脚本示例代码:便于独立脚本的开发

git clone https://github.com/outlaws-bai/GalaxyHttpHooker.git 

示例说明:

  • aes_cbc.py(基础版本)直接处理请求体中的 JSON 数据
  • aes_cbc_form.py(表单版本)处理表单数据 (a=1&b=2)
  • aes_cbc_query.py(查询参数版本)只对查询参数中的字段进行加解密 (?a=1&b=2)

因此我们遇到的 HTTP 参数加密请求,可以依据上述模板进行修改。

在这里插入图片描述

所有脚本围绕 4 个 hook 方法:hookRequestToBurp,hookRequestToServer,hookResponseToBurp,hookResponseToClient。

作用分别如下:我们对请求的加解密是前 2 个方法,如果响应内容加密了,你想解密需要实现后 2 个方法。

①:HTTP 请求从客户端到达 Burp 时被触发。你需要在此处完成请求解密的代码,这样就可以在 Burp 中看到明文的请求报文。

②:HTTP 请求从 Burp 将要发送到 Server 时被触发。你需要在此处完成请求加密的代码,这样就可以将加密后的请求报文发送到 Server。

③:HTTP 响应从 Server 到达 Burp 时被触发。你需要在此处完成响应解密的代码,这样就可以在 Burp 中看到明文的响应报文。

④:HTTP 响应从 Burp 将要返回到 Client 时被触发。你需要在此处完成响应加密的代码,这样就可以将加密后的响应报文返回给 Client。

2.2 autoDecoder

官方仓库:https://github.com/f0ng/autoDecoder

3 AES 固定 Key

使用火狐浏览器的'栈跟踪'功能,查看调用的所有 js 代码。

可以看到 sendDataAes http://192.168.10.11:82/js/app.js:1:1098 和发起者都是 app.js,因此从 app.js 查询加密逻辑。

在这里插入图片描述

如果是谷歌浏览器,只能看发起时的 js 文件,当然这个靶场不复杂,无伤大雅。

在这里插入图片描述

继续使用火狐浏览器演示,查看 app.js 代码,可以看到代码经过了混淆。

在这里插入图片描述

在右边 click 处勾上,表示点击时调试。

在这里插入图片描述

点击登录按钮,然后点击'AES 固定 key',继续调试。

在这里插入图片描述

自动定位到如下 sendDataAes 函数中,可以看到对用户名、密码的对象使用 AES 加密,包含 iv、CBC 的 mode、padding 填充信息。

在这里插入图片描述

我们需要知道是如何将用户名密码进行 AES 加密的,直接将此处代码给 AI 分析下:

函数:sendDataAes()

加密参数:

  • 算法:AES-CBC
  • 密钥(Key):固定 16 位字符串 1234567890123456(Utf8 编码)
  • 偏移量(IV):固定 16 位字符串 1234567890123456(Utf8 编码)
  • 填充方式:PKCS7(默认填充规则)
  • 输出:Base64 编码的加密结果

传输方式:将加密后的数据拼接为 encryptedData=加密值,以 application/x-www-form-urlencoded 格式 POST 提交

抓包查看请求信息,是表单格式的。

在这里插入图片描述

点击 start 按钮启动插件,这里不勾选 Hook Response,原因是响应内容是明文,request.host 填入的是靶机的 IP。

在这里插入图片描述

直接复制 aes_cbc_form.py 脚本进行修改:这里修改了 KEY、IV 的值,将模板中的 username 修改为 encryptedData,因为请求时的参数是 encryptedData。

import json import base64 import typing as t from fastapi import FastAPI from urllib.parse import parse_qs, urlencode from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from _base_classes import* KEY =b"1234567890123456" IV =b"1234567890123456" JSON_KEY ="data" app = FastAPI()
@app.post("/hookRequestToBurp", response_model=RequestModel)
async def hook_request_to_burp(request: RequestModel):
    """HTTP 请求从数据客户端到达 Burp 时被调用。在此处完成请求解密的代码就可以在 Burp 中看到明文的请求报文。"""
    # 获取需要解密的数据 encrypted_data:bytes= base64.b64decode( parse_qs(request.content.decode())["encryptedData"][0])
    # 调用函数解密 data:bytes= decrypt(encrypted_data)
    print(f"[DEBUG] 解密后的数据:{data.decode()}")
    # 更新 query request.content = urlencode({"encryptedData": data.decode()}).encode()
    return request
@app.post("/hookRequestToServer", response_model=RequestModel)
async def hook_request_to_server(request: RequestModel):
    """HTTP 请求从 Burp 将要发送到 Server 时被调用。在此处完成请求加密的代码就可以将加密后的请求报文发送到 Server。"""
    # 获取被解密的数据 data:bytes= parse_qs(request.content.decode())["encryptedData"][0].encode()
    # 调用函数加密回去 encryptedData:bytes= encrypt(data)
    print(f"[DEBUG] 加密后的数据:{base64.b64encode(encryptedData)}")
    # 更新 query request.content = urlencode({"encryptedData": base64.b64encode(encryptedData)}).encode()
    return request
@app.post("/hookResponseToBurp", response_model=ResponseModel)
async def hook_response_to_burp(response: ResponseModel):
    return response
@app.post("/hookResponseToClient", response_model=ResponseModel)
async def hook_response_to_client(response: ResponseModel):
    return response
def decrypt(content:bytes)->bytes:
    cipher = AES.new(KEY, AES.MODE_CBC, IV)
    return unpad(cipher.decrypt(content), AES.block_size)
def encrypt(content:bytes)->bytes:
    cipher = AES.new(KEY, AES.MODE_CBC, IV)
    return cipher.encrypt(pad(content, AES.block_size))
def get_data(content:bytes)->bytes:
    body_json: t.Dict = json.loads(content)
    return base64.b64decode(body_json[JSON_KEY])
def to_data(contnet:bytes)->bytes:
    body_json ={}
    body_json[JSON_KEY]= base64.b64encode(contnet).decode()
    return json.dumps(body_json).encode()
if __name__ =="__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=5000)

然后可以在 proxy 请求中尝试解密,操作如下:

在这里插入图片描述

解密后可以看到明文显示,这里是弹出了一个窗口,可以看到 url 编码后的结果;注意这里的 X-Galaxy-Http-Hook: HookedRequest 是 Galaxy 插件 hook 的标识,有这个标识才会进行加密脚本中 hookRequestToServer 的执行。

在这里插入图片描述

使用 Decoder 模块进行 URL 解码看看结果。

在这里插入图片描述

如果觉得手动解码有点麻烦,可以将请求发送到 repeater 模块中解密,右侧的 inspector 功能自动解码,省去一次操作步骤。

在这里插入图片描述

脚本也会同步打印调试信息,可以看到解密后的信息。

在这里插入图片描述

那么我们修改输入的明文,看看插件的效果,能否自动加密后发送请求。

在这里插入图片描述

可以看到,脚本中的 hookRequestToServer 将明文加密后发送给服务端。

在这里插入图片描述

接下来就是如何进行爆破的问题,其实跟普通的爆破是一样的,将解密后端请求添加到 intruder 模块中,针对爆破参数添加字典进行爆破即可(后续题目不再赘述爆破步骤)。

在这里插入图片描述

可以看到响应结果是正常显示。

在这里插入图片描述

插件脚本也会自动进行加密后发送请求,这里提供的脚本也同步打印了加密的信息。

在这里插入图片描述

4 AES 服务端获取 Key

查看请求:先从服务端获取 aes 加密的 key 和 iv 的值,多次请求可以看到这 2 个值是固定的。

在这里插入图片描述

然后发送加密请求,响应内容存在 Unicode 编码,使用 python print 解码得到 用户名或密码错误

在这里插入图片描述

在这里插入图片描述

通过栈跟踪,定位到关键代码后分析如下:

请求格式:POST + application/json + encryptedData 的 JSON 体;

请求内容:明文是账号密码 JSON,加密后仅传加密字符串;

加密方式:AES-CBC + PKCS7 填充 + Base64 输出;

加密参数:Key/IV 从后端动态获取(Base64 解码后使用),长度均为 16 字节(AES-128)。

在这里插入图片描述

那么我们复制模板中的 aes_cbc.py 脚本,修改对 key 和 iv 进行 base64 解码、修改 JSON_KEY 为请求中的参数 encryptedData:

import json import base64 import typing as t from fastapi import FastAPI from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from _base_classes import* KEY = base64.b64decode("UMmKw73GSNZcCFqj6/XN5A==") IV = base64.b64decode("1SofbOFnjQCBcNt2M35PTQ==") JSON_KEY ="encryptedData" app = FastAPI()
@app.post("/hookRequestToBurp", response_model=RequestModel)
async def hook_request_to_burp(request: RequestModel):
    """HTTP 请求从客户端到达 Burp 时被调用。在此处完成请求解密的代码就可以在 Burp 中看到明文的请求报文。"""
    # print(f"[+] hookRequestToBurp be called. request: {request.model_dump_json()}")
    # 获取需要解密的数据 encrypted_data:bytes= get_data(request.content)
    # 调用函数解密 data:bytes= decrypt(encrypted_data)
    print(f"[DEBUG] 解密后的数据:{data.decode()}")
    # 更新 body 为已解密的数据 request.content = data
    return request
@app.post("/hookRequestToServer", response_model=RequestModel)
async def hook_request_to_server(request: RequestModel):
    """HTTP 请求从 Burp 将要发送到 Server 时被调用。在此处完成请求加密的代码就可以将加密后的请求报文发送到 Server。"""
    # print(f"[+] hookRequestToServer be called. request: {request.model_dump_json()}")
    # 获取被解密的数据 data:bytes= request.content
    # 调用函数加密回去 encryptedData:bytes= encrypt(data)
    # 将已加密的数据转换为 Server 可识别的格式 body:bytes= to_data(encryptedData)
    print(f"[DEBUG] 加密后的数据:{base64.b64encode(encryptedData)}")
    # 更新 body request.content = body
    return request
@app.post("/hookResponseToBurp", response_model=ResponseModel)
async def hook_response_to_burp(response: ResponseModel):
    return response
@app.post("/hookResponseToClient", response_model=ResponseModel)
async def hook_response_to_client(response: ResponseModel):
    return response
def decrypt(content:bytes)->bytes:
    cipher = AES.new(KEY, AES.MODE_CBC, IV)
    return unpad(cipher.decrypt(content), AES.block_size)
def encrypt(content:bytes)->bytes:
    cipher = AES.new(KEY, AES.MODE_CBC, IV)
    return cipher.encrypt(pad(content, AES.block_size))
def get_data(content:bytes)->bytes:
    body_json: t.Dict = json.loads(content)
    return base64.b64decode(body_json[JSON_KEY])
def to_data(contnet:bytes)->bytes:
    body_json ={}
    body_json[JSON_KEY]= base64.b64encode(contnet).decode()
    return json.dumps(body_json).encode()
if __name__ =="__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=5000)

启动后将加密请求发送到 repeater 模块进行解密。

在这里插入图片描述

成功解密,脚本也正常打印调试信息。

在这里插入图片描述

修改密码请求,发送成功

在这里插入图片描述

脚本也成功打印调试信息。

在这里插入图片描述

5 Rsa 加密

加密请求如下:

在这里插入图片描述

通过栈追踪定位到如下代码,分析结果如下:

请求方式:POST + 表单格式(application/x-www-form-urlencoded);

请求参数:明文是账号密码 JSON 串(格式是 data={"username":"xxx","password":"xxx"}),加密后为 Base64 格式的 RSA 密文;

加密方法:RSA 非对称加密,PKCS#1 v1.5 填充;

加密参数:固定硬编码的 RSA 1024 位公钥。

在这里插入图片描述

Galaxy

改造模板中的 rsa.py 代码:

  • 本题不知道解密的私钥,只能尝试进行请求的加密(前面分析已经知道了请求体的格式);
  • 这个题目需要对加密后的结果进行 url 编码;
  • 注意公钥书写的格式, 手动换行;
  • 提取请求的参数 JSON_KEY 是 data;
  • 需要对 BurpSuite 请求添加请求头 X-Galaxy-Http-Hook: HookedRequest,以让 Galaxy 插件识别是要加密的请求。
import base64 from urllib.parse import parse_qs, quote_plus from Crypto.Cipher import PKCS1_v1_5 from Crypto.PublicKey import RSA from fastapi import FastAPI from _base_classes import* pub_key ="""-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujvi NH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlM DSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3Cb ocDbsNeCwNpRxwjIdQIDAQAB -----END PUBLIC KEY-----""" JSON_KEY ="data" app = FastAPI()
@app.post("/hookRequestToBurp", response_model=RequestModel)
async def hook_request_to_burp(request: RequestModel):
    return request
@app.post("/hookRequestToServer", response_model=RequestModel)
async def hook_request_to_server(request: RequestModel):
    """HTTP 请求从 Burp 将要发送到 Server 时被调用。在此处完成请求加密的代码就可以将加密后的请求报文发送到 Server。"""
    # 获取请求内容 content_str = request.content.decode('utf-8')
    # 解析请求内容,提取参数的值 try: parsed_data = parse_qs(content_str)
        if'data'in parsed_data:
            # 获取参数的值 original_data = parsed_data['data'][0]
            print(f"[DEBUG] 加密前的数据:{original_data}")
            # 对值进行 RSA 加密 encrypted_data = encrypt(original_data.encode('utf-8'), pub_key)
            # Base64 编码 encrypted_b64 = base64.b64encode(encrypted_data).decode('utf-8')
            # URL 编码 encrypted_url_encoded = quote_plus(encrypted_b64)
            # 构造新的请求内容 new_content =f"data={encrypted_url_encoded}"
            print(f"[DEBUG] 加密后的数据:{new_content}")
            # 更新请求内容 request.content = new_content.encode('utf-8')
        else:print("[WARNING] 请求中未找到指定参数")
    except Exception as e:print(f"[ERROR] 处理请求时出错:{e}")passreturn request
def encrypt(content:bytes, secret:bytes)->bytes:
    rsa_key = RSA.import_key(secret)
    cipher = PKCS1_v1_5.new(rsa_key)
    return cipher.encrypt(content)
if __name__ =="__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=5000)

启动脚本后,通过构造 BurpSuite 请求完成加密请求,注意添加请求体 X-Galaxy-Http-Hook: HookedRequest,让请求走我们编写的 Galaxy 的脚本。

在这里插入图片描述

在这里插入图片描述

autoDecoder

配置如下图:题目中的密文还进行了 url 编码,所有要勾选 2

在这里插入图片描述

注意密钥是公钥:填写格式如下:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujvi NH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlM DSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3Cb ocDbsNeCwNpRxwjIdQIDAQAB 

在这里插入图片描述

配置后在 repeater 模块发送请求,可以成功加密。

在这里插入图片描述

6 AES+Rsa 加密

加密请求如下:

在这里插入图片描述

定位到加密代码,分析如下:

使用算法:

  • AES-CBC 模式,加密数据格式 {"username":"xxx","password":"xxx"},AES 的 key 和 iv 随机 16 字节。
  • RSA 公钥加密,_0x41d8d9[_0x13ef4f(953, 972)](_0x13ef4f(990, 973)) 这一行,就是设置 RSA 公钥的地方;_0x13ef4f(953, 972)对应 setPublicKey,(_0x13ef4f(990, 973)即公钥内容。
{"encryptedData":"AES 加密后的用户名 + 密码 JSON 字符串",// AES 加密数据
"encryptedKey":"RSA 加密后的 AES key(Base64 格式)",// RSA 加密后的 AES key
"encryptedIv":"RSA 加密后的 AES iv(Base64 格式)"// RSA 加密后的 AES iv}

在这里插入图片描述

在浏览器的控制台打印 console.log(_0x13ef4f(990, 973)) 获取 RSA 公钥:

在这里插入图片描述

-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujvi NH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlM DSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3Cb ocDbsNeCwNpRxwjIdQIDAQAB 

思路:

  • 目标是替换 encryptedData 的内容,因此需要进行 AES 解密;
  • AES 解密需要 AES 的 key 和 iv;
  • key 和 iv 在 encryptedKey 和 encryptedIv 中被 RSA 的公钥加密;
  • 不知道 RSA 私钥无法解密 key 和 iv;通过 Chrome 浏览器固定 AES 的 key 和 iv 的值;
  • 传参时 encryptedData 使用明文数据(格式前面分析已经知道);encryptedKey 和 encryptedIv 使用请求中的原始密文。
  • 加密时通过 AES 算法加密 encryptedData 的值。

使用 Chrome 浏览器的 override content 功能替换 app.js:先将原始 app.js 下载到本地,在浏览器源码处右键 Overrides content 选择本地的文件,选中后修改代码中固定 key 和 iv 为 16 字节,修改完按 Ctrl+S 保存,注意格式。

注意:下次打开浏览器即使该页面启用了 Overrides content 也会失效,需要在修改的地方打断点,用 debugger 的形式运行。

, _0x4515a4 = CryptoJS.enc.Utf8.parse('1234567890123456') , _0x5e9345 = CryptoJS.enc.Utf8.parse('1234567890123456')

在这里插入图片描述

然后抓包,可以看到使用固定 key 和 iv 进行 AES 加密后的 encryptedData,重试一次保证 encryptedData 的值不变,说明代码修改有效。

在这里插入图片描述

Galaxy

脚本需要实现的是使用 AES 加密参数 encryptedData 的值,固定 key 和 iv 为我们指定的值;其他 2 个参数的值不变。

import base64 import json from Crypto.Cipher import PKCS1_v1_5, AES from Crypto.PublicKey import RSA from Crypto.Util.Padding import pad from fastapi import FastAPI from _base_classes import* KEY =b"1234567890123456"# 16 字节 IV =b"1234567890123456"# 16 字节 JSON_KEY1 ="encryptedData" app = FastAPI()
@app.post("/hookRequestToServer", response_model=RequestModel)
async def hook_request_to_server(request: RequestModel):
    try:
        # 获取请求内容 data:bytes= request.content
        # 解析 JSON request_json = json.loads(data.decode())
        # print(f"解析的 JSON: {request_json}")
        # 只修改 encryptedData 参数,保持其他参数不变 if JSON_KEY1 in request_json:
            # 获取原始的 encryptedData 值 original_encrypted_data = request_json[JSON_KEY1]
            print(f"原始 encryptedData: {original_encrypted_data}")
            # 处理 encryptedData 值 if isinstance(original_encrypted_data,str):
                try:# 尝试将字符串解析为 JSON 对象 inner_json = json.loads(original_encrypted_data)
                    print(f"解析出的 JSON: {inner_json}")
                    # 重新序列化为字符串用于加密 encrypted_data_bytes = original_encrypted_data.encode()
                except json.JSONDecodeError:# 如果不是有效的 JSON 字符串,直接使用原字符串 print("encryptedData 不是有效的 JSON 格式,直接使用原值") encrypted_data_bytes = original_encrypted_data.encode()
            else:# 如果不是字符串,转换为字符串 encrypted_data_bytes =str(original_encrypted_data).encode()
            # 对 encryptedData 进行 AES 加密 encryptedData1:bytes= aes_encrypt(encrypted_data_bytes)
            # 更新 encryptedData 参数的值 request_json[JSON_KEY1]= base64.b64encode(encryptedData1).decode()
            # 构造新的请求体 body:bytes= json.dumps(request_json, ensure_ascii=False).encode() encrypted_json_str = body.decode()
            print(f"[DEBUG] 修改后的数据:{encrypted_json_str}") request.content = body
        else:print(f"未找到 {JSON_KEY1} 参数")
    except Exception as e:print(f"处理错误:{e}")return request
def aes_encrypt(content:bytes)->bytes:
    cipher = AES.new(KEY, AES.MODE_CBC, IV)
    return cipher.encrypt(pad(content, AES.block_size))
def rsa_encrypt(content:bytes, secret:bytes)->bytes:
    rsa_key = RSA.import_key(secret)
    cipher = PKCS1_v1_5.new(rsa_key)
    return cipher.encrypt(content)
if __name__ =="__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=5000)

启动编写的脚本,将加密请求发送到 repeater 模块,添加 hook 的请求头,修改加密数据为 {\"username\":\"admin\",\"password\":\"123456\"},发送请求后,服务端成功响应。

在这里插入图片描述

脚本也同步打印调试信息:

在这里插入图片描述

autoDecoder

使用 autoDecoder 比较方便,配置如下(记得保存配置):正则是 "encryptedData":"(.*)","encryptedKey"。

在这里插入图片描述

记得重新加载下新配置,以免不生效。

在这里插入图片描述

直接在请求中明文输入,内容是 {"username":"admin","password":"123456"},实战中可以对这里进行爆破。

在这里插入图片描述

7 DES 规律 key

请求如下:

在这里插入图片描述

核心代码使用 DES-CBC 模式加密密码,核心规则:

  • 密钥(Key):从用户名截取前 8 位(0 开始),不足补字符 6 到 8 位;
  • 向量(IV):固定前缀 9999 + 用户名前 4 位(0 开始),不足补字符 9 到 8 位;
  • 填充方式:PKCS7(CryptoJS 默认);
  • 输出格式:加密后的二进制密文转 16 进制字符串(而非 Base64);
  • 加密对象:页面输入的密码(password 输入框的值)。

一句话总结:通过用户名获取 key 和 iv 的值,对密码进行 DES-CBC 加密,结果转 16 进制字符串。

在这里插入图片描述

Galaxy

脚本代码如下:实现的就是对 password 值的加解密,需要获取 username 来生成 key 和 iv 的值。

import json from Crypto.Cipher import DES from Crypto.Util.Padding import pad, unpad from fastapi import FastAPI from _base_classes import* KEY =b"" IV =b"" app = FastAPI()
@app.post("/hookRequestToBurp", response_model=RequestModel)
async def hook_request_to_burp(request: RequestModel):
    """HTTP 请求从客户端到达 Burp 时被调用。在此处完成请求解密的代码就可以在 Burp 中看到明文的请求报文。"""
    # print(f"[+] hookRequestToBurp be called. request: {request.model_dump_json()}")
    try:
        # 解析请求体 JSON request_body = json.loads(request.content.decode()) username = request_body.get("username","") password_encrypted = request_body.get("password","")
        if not username or not password_encrypted:print("缺少 username 或 password 字段")return request
        # 生成 KEY 和 IV global KEY, IV KEY, IV = generate_key_iv(username)
        print(f"生成的 KEY: {KEY}, IV: {IV}")
        # 将十六进制字符串转换为字节用于解密 encrypted_bytes =bytes.fromhex(password_encrypted)
        # 使用 decrypt 方法解密 decrypted_bytes = decrypt(encrypted_bytes) password_decrypted = decrypted_bytes.decode('utf-8')
        print(f"解密后的 password: {password_decrypted}")
        # 更新请求体 request_body["password"]= password_decrypted request.content = json.dumps(request_body, ensure_ascii=False).encode()
    except Exception as e:print(f"解密过程出错:{e}")return request
@app.post("/hookRequestToServer", response_model=RequestModel)
async def hook_request_to_server(request: RequestModel):
    """HTTP 请求从 Burp 将要发送到 Server 时被调用。在此处完成请求加密的代码就可以将加密后的请求报文发送到 Server。"""
    # print(f"[+] hookRequestToServer be called. request: {request.model_dump_json()}")
    try:
        # 解析请求体 JSON(此时 password 应该是明文) request_body = json.loads(request.content.decode()) username = request_body.get("username","") password_decrypted = request_body.get("password","")
        if not username or not password_decrypted:print("缺少 username 或 password 字段")return request
        # 生成 KEY 和 IV global KEY, IV KEY, IV = generate_key_iv(username)
        print(f"[+] 生成的 KEY: {KEY}, IV: {IV}")
        # 使用现有的 encrypt 方法加密 password password_bytes = password_decrypted.encode('utf-8') encrypted_bytes = encrypt(password_bytes)
        # 转换为十六进制字符串 password_encrypted = encrypted_bytes.hex()
        print(f"加密后的 password: {password_encrypted}")
        # 只更新 password 字段 request_body["password"]= password_encrypted
        # 构造新的请求体 request.content = json.dumps(request_body, ensure_ascii=False).encode()
    except Exception as e:print(f"加密过程出错:{e}")return request
def generate_key_iv(username:str)->tuple[bytes,bytes]:
    """ 根据用户名生成 KEY 和 IV KEY: 用户名截取前 8 位(0 开始),不足补字符'6'到 8 位 IV: 固定前缀'9999' + 用户名前 4 位(0 开始),不足补字符'9'到 8 位 """
    # 生成 KEY username_prefix = username[:8] key = username_prefix.ljust(8,'6').encode()
    # 生成 IV username_prefix_4 = username[:4] iv_str ="9999"+ username_prefix_4.ljust(4,'9') iv = iv_str.encode()
    return key, iv
def decrypt(content:bytes)->bytes:
    cipher = DES.new(KEY, DES.MODE_CBC, IV)
    return unpad(cipher.decrypt(content), DES.block_size)
def encrypt(content:bytes)->bytes:
    cipher = DES.new(KEY, DES.MODE_CBC, IV)
    return cipher.encrypt(pad(content, DES.block_size))
if __name__ =="__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=5000)

在 repeater 中解密请求:

在这里插入图片描述

解密后密码是明文:

在这里插入图片描述

发送也正常:

在这里插入图片描述

脚本调试信息也正常:

在这里插入图片描述

autoDecoder

使用这个工具的话只能单个进行验证,需要自己算 key 和 iv,密码记得选 16 进制 (hex);因此这关使用 autoDecoder 工具只能爆破固定用户名的密码。

在这里插入图片描述

8 明文加签

请求如下:

在这里插入图片描述

核心代码分析如下:

随机数

  • 签名算法:HmacSHA256(基于哈希的消息认证码,不可逆);
  • nonce 是随机小数转换成 36 进制再去掉 0.;
  • timestamp 是获取当前毫秒时间戳,除以 1000 并向下取整;
  • 签名密钥:固定值 be56e057f20f883e;
  • 签名原文:用户名 + 密码 + 随机数 (nonce) + 时间戳 (timestamp);
  • 签名输出:HmacSHA256 结果转 16 进制字符串。

在这里插入图片描述

选中使用 Galaxy 进行请求加签,脚本如下:

import hashlib import hmac import json import random import string import time from fastapi import FastAPI from _base_classes import* app = FastAPI()
@app.post("/hookRequestToServer", response_model=RequestModel)
async def hook_request_to_server(request: RequestModel):
    """HTTP 请求从 Burp 将要发送到 Server 时被调用。在此处完成请求签名计算的代码。"""
    try:
        # 获取原始请求内容 content_str = request.content.decode('utf-8')
        # 解析请求体 JSON request_body = json.loads(content_str)
        # 获取用户名和密码 username = request_body.get("username","") password = request_body.get("password","")
        if not username or not password:print("缺少 username 或 password 字段")return request
        # 生成随机数 nonce =''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
        # 获取当前毫秒时间戳 timestamp =int(time.time())
        # 签名密钥 secret_key ="be56e057f20f883e"
        # 构造签名原文:用户名 + 密码 + 随机数 + 时间戳 sign_text =f"{username}{password}{nonce}{timestamp}"
        # 计算 HmacSHA256 签名 signature = hmac.new( secret_key.encode('utf-8'), sign_text.encode('utf-8'), hashlib.sha256 ).hexdigest()
        # 更新请求体中的字段 request_body["nonce"]= nonce request_body["timestamp"]= timestamp request_body["signature"]= signature
        # 构造新的请求体 new_content = json.dumps(request_body, ensure_ascii=False).encode() request.content = new_content
        print(f"新的请求内容:{new_content.decode()}")
    except json.JSONDecodeError as e:print(f"JSON 解析错误:{e}")return request
    except Exception as e:print(f"签名计算过程出错:{e}")return request
return request
if __name__ =="__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=5000)

发送请求时记得添加请求头:X-Galaxy-Http-Hook: HookedRequest

在这里插入图片描述

在这里插入图片描述

9 加签 key 在服务器端

请求有 2 个,先从服务端获取签名,再发送请求:

在这里插入图片描述

在这里插入图片描述

核心代码逻辑:账号密码 + 生成时间戳 → 找服务器要签名 → 带签名提交登录信息。

async function sendDataWithNonceServer(_0xb4476b){function _0x5b14e6(_0x9f039f, _0x3746ee){return_0x4f79d5(_0x9f039f -0xde, _0x3746ee);}const _0x41822d = document['getElementById']('username')['value'], _0x3c65d8 = document['getElementById']('password')['value'], _0x173dbd = Math[_0x5b14e6(0x281,0x282)](Date[_0x5b14e6(0x282,0x26f)]()/0x3e8);try{const _0x55d2c7 =awaitfetch(_0xb4476b +_0x5b14e6(0x283,0x28d),{'method':_0x5b14e6(0x27a,0x26b),'headers':{'Content-Type':_0x5b14e6(0x280,0x26f)},'body':JSON['stringify']({'username': _0x41822d,'password': _0x3c65d8,'timestamp': _0x173dbd })});closeModal();if(!_0x55d2c7['ok']){ console['error']('获取签名失败:', _0x55d2c7['statusText']),alert('获取签名失败,请稍后重试。');return;}const{signature: _0x2755ad}=await _0x55d2c7[_0x5b14e6(0x26b,0x279)]();if(!_0x2755ad){alert('签名获取失败,服务器未返回签名。');return;}const _0x58deb5 =awaitfetch(''+ _0xb4476b,{'method':'POST','headers':{'Content-Type':'application/json'},'body':JSON['stringify']({'username': _0x41822d,'password': _0x3c65d8,'timestamp': _0x173dbd,'signature': _0x2755ad })});if(!_0x58deb5['ok']){ console['error'](_0x5b14e6(0x284,0x28b), _0x58deb5['statusText']),alert('提交数据失败,请稍后重试。');return;}const _0x22648d =await _0x58deb5['json'](); _0x22648d[_0x5b14e6(0x26c,0x26a)]?(alert('登录成功'), window['location']['href']='success.html'):alert(_0x22648d[_0x5b14e6(0x274,0x285)]||'用户名或密码错误');}catch(_0x30ffca){ console['error'](_0x5b14e6(0x26f,0x265), _0x30ffca),alert('发生错误,请稍后重试。');}}}

直接通过纯 python 脚本实现即可,没必要使用插件。

import requests import json import time host ="http://192.168.10.11:82" headers ={"Content-Type":"application/json","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36","Cookie":"PHPSESSID=73fc283a7d583cc5433f44f606f9822a"}
def get_timestamp():return int(time.time())
def step1_get_signature(username, password, timestamp): url =f"{host}/encrypt/get-signature.php" payload ={"username": username,"password": password,"timestamp": timestamp } response = requests.post(url, json=payload, headers=headers) response.raise_for_status() result = response.json()
return result.get("signature")
def step2_send_signed_request(username, password, timestamp, signature): url =f"{host}/encrypt/signdataserver.php" payload ={"username": username,"password": password,"timestamp": timestamp,"signature": signature } response = requests.post(url, json=payload, headers=headers) response.raise_for_status()
return response.json()
def main(): username ="admin" password ="123456" timestamp = get_timestamp()
try: signature = step1_get_signature(username, password, timestamp) result = step2_send_signed_request(username, password, timestamp, signature)
    print(f"服务器响应:{json.dumps(result, indent=2, ensure_ascii=False)}")
except Exception as e:print(f"发生错误:{e}")
if __name__ =="__main__": main()

在这里插入图片描述

10 禁止重放

请求如下:可以看到核心在于生成的 random 参数的值。

在这里插入图片描述

核心代码:random = RSA 加密 (毫秒时间戳 )。

function generateRequestData(){function _0x34b479(_0x38b999, _0x500418){return_0x4f79d5(_0x38b999 -0x1e4, _0x500418);}const _0x1da0ac = document[_0x34b479(0x360,0x357)](_0x34b479(0x366,0x379))['value'], _0x4fdc07 = document[_0x34b479(0x360,0x360)](_0x34b479(0x368,0x37d))[_0x34b479(0x367,0x351)], _0x5a8525 = Date[_0x34b479(0x388,0x37a)](), _0x9f2be4 =_0x34b479(0x37e,0x381);function _0x5b0e97(_0x482893, _0x201f27){const _0x3ef89b =newJSEncrypt(); _0x3ef89b[_0x434cfc(0x300,0x2f2)](_0x201f27);const _0x311c6b = _0x3ef89b[_0x434cfc(0x2ed,0x2fc)](_0x482893['toString']());function _0x434cfc(_0x57eb61, _0x7fc509){return_0x34b479(_0x57eb61 --0x7d, _0x7fc509);}if(!_0x311c6b)thrownewError('RSA\x20encryption\x20failed.');return _0x311c6b;}let _0x110e21;try{ _0x110e21 =_0x5b0e97(_0x5a8525, _0x9f2be4);}catch(_0x16a5f1){return console['error']('Encryption\x20error:', _0x16a5f1),null;}const _0x163cb9 ={'username': _0x1da0ac,'password': _0x4fdc07,'random': _0x110e21 };return _0x163cb9;}

经过断点调试,找到公钥:

-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujvi NH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlM DSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3Cb ocDbsNeCwNpRxwjIdQIDAQAB -----END PUBLIC KEY----- 

在这里插入图片描述

在这里插入图片描述

编写 Galaxy 脚本,纯 python 脚本也行,逻辑一样。

import base64 import json import time from Crypto.Cipher import PKCS1_v1_5 from Crypto.PublicKey import RSA from fastapi import FastAPI from _base_classes import* app = FastAPI() KEY ="""-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRvA7giwinEkaTYllDYCkzujvi NH+up0XAKXQot8RixKGpB7nr8AdidEvuo+wVCxZwDK3hlcRGrrqt0Gxqwc11btlM DSj92Mr3xSaJcshZU8kfj325L8DRh9jpruphHBfh955ihvbednGAvOHOrz3Qy3Cb ocDbsNeCwNpRxwjIdQIDAQAB -----END PUBLIC KEY-----"""
@app.post("/hookRequestToServer", response_model=RequestModel)
async def hook_request_to_server(request: RequestModel):
    """HTTP 请求从 Burp 将要发送到 Server 时被调用。在此处完成请求签名计算的代码。"""
    # print(f"[+] hookRequestToServer be called. request: {request.model_dump_json()}")
    try:
        # 获取原始请求内容 content_str = request.content.decode('utf-8')
        # 解析请求体 JSON request_body = json.loads(content_str)
        # 获取用户名和密码 username = request_body.get("username","") password = request_body.get("password","")
        if not username or not password:print("缺少 username 或 password 字段")return request
        # 获取当前毫秒时间戳 timestamp =str(int(time.time())*1000)
        # 对时间戳进行 RSA 加密 encrypted_bytes = encrypt(timestamp.encode('utf-8'), KEY) random = base64.b64encode(encrypted_bytes).decode()
        # 更新请求体中的字段 request_body["random"]= random
        # 构造新的请求体 new_content = json.dumps(request_body, ensure_ascii=False).encode() request.content = new_content
        print(f"新的请求内容:{new_content.decode()}")
    except Exception as e:print(e)return request
return request
def encrypt(content, secret)->bytes:
    rsa_key = RSA.import_key(secret)
    cipher = PKCS1_v1_5.new(rsa_key)
    return cipher.encrypt(content)
if __name__ =="__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=5000)

在这里插入图片描述

在这里插入图片描述

目录

  1. 1 环境搭建(Docker 混淆版)
  2. docker 镜像配置
  3. 老版本 Docker(独立安装 docker-compose)
  4. 新版本 Docker(内置命令 compose)
  5. 2 配置插件
  6. 2.1 Galaxy
  7. 2.2 autoDecoder
  8. 3 AES 固定 Key
  9. 4 AES 服务端获取 Key
  10. 5 Rsa 加密
  11. Galaxy
  12. autoDecoder
  13. 6 AES+Rsa 加密
  14. Galaxy
  15. autoDecoder
  16. 7 DES 规律 key
  17. Galaxy
  18. autoDecoder
  19. 8 明文加签
  20. 9 加签 key 在服务器端
  21. 10 禁止重放
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • KWDB 3.1.0 进阶实战:千万级时序写入、监控与运维
  • 基于 GLM-4.6 与 Trae 的 AI 面试教练系统设计与实现
  • LLaMaFactory 基于免费 GPU 环境微调大模型教程
  • StarRocks 与 MySQL 深度对比:架构、性能与选型
  • Linux 环境下编译 Kotaemon 源码:C#与 C++混合开发指南
  • AI 辅助 PCB 设计:效率革命与工程师角色重塑
  • IROS 2025 无人机与集群学习控制论文精选
  • 仿生学突破:SILD 模型如何实现无人机电力线避障检测
  • 小需求设计:如何用 Redis 实现协议勾选状态管理
  • C++ 异常机制详解
  • AI 工具泛滥时代,为何能力越来越不值钱?
  • 深入理解 Linux 软链接与硬链接
  • Java IO 流:核心原理与实战应用
  • Stable Diffusion 模型版本演进与核心差异解析
  • 前端新手必备的 10 个 VS Code 插件及配置指南
  • C++ 输入输出详解(上):基础流与格式控制
  • Java 模拟算法实战:经典题型深度解析
  • YOLO+OpenClaw+SAM 微调实现工业缺陷自动标注
  • Spring Bean Scope 作用域详解
  • ToClaw 信息检索与分析能力实测:从热搜到深度报告

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online