Loading

使用Galaxy实现AES_CBC带干扰的加解密

在浏览一个网站的过程中,发现该网站与服务端之间http通信都是进行加密的,刚好最近在学习js逆向,就拿这个网站来试试,顺带看看如何使用Galaxy进行加解密。

在登录接口处设置断点调试,找到加密函数

定位加解密函数,获得干扰项位置

加密函数:

解密函数:

定位AES、CBC加密方式使用的KEY、IV

这里是通过断点调试,一步步的跟函数获得加密后的KEY和IV进行返推获得的KEY、IV。

实现加解密

安装Burp插件 Galaxy ,还要记得下载提供的脚本 GalaxyHttpHooker

因为已经知道了是aes cbs加密,但是其中添加了干扰内容,所以要修改原有的cbc加解密脚本:

增加对请求包进行【解密-加密】的函数,

从客户端发送--Burp拦截--去除干扰--解密--Burp中呈现或修改--加密--添加干扰--提交服务端

# 实现解密
def remove_request_noise(s):  
    # 删除 35:45(10字符)  
    return s[:35] + s[45:]  
  
  
def get_request_data(content: bytes) -> bytes:  
    print("get_request_data:", content)  
    body_json: t.Dict = json.loads(content)  
    return base64.b64decode(remove_request_noise(body_json[JSON_KEY]))  
  
# 实现加密
def add_request_noise(s: str) -> str:  
    """在响应数据中添加混淆字符"""  
    # 添加中缀混淆(10个随机字符)  
    infix = ''.join(random.choices(string.ascii_lowercase, k=10))  
  
    if len(s) < 35:  
        raise ValueError("密文太短,无法插入干扰")  
  
    # 在索引 35 处插入 10 个随机小写字母  
    return s[:35] + infix + s[35:]  
  
  
def to_request_data(content: bytes) -> bytes:  
    body_json = {}  
    base64_data = base64.b64encode(content).decode()  
    noisy_data = add_request_noise(base64_data)  
    body_json[JSON_KEY] = noisy_data  
    return json.dumps(body_json).encode()

增加对响应包进行【解密-加密】的函数

服务端返回--Burp拦截--去除干扰--解密--Burp中呈现或修改--加密--添加干扰--返回客户端

# 实现解密
def remove_response_noise(s):  
    # 删除 20:36(16字符)  
    return s[:20] + s[36:]  
  
  
def get_response_data(content: bytes) -> bytes:  
    body = remove_response_noise(content)  
    return base64.b64decode((body))  
  
# 实现加密
def add_response_noise(s: str) -> str:  
    """在响应数据中添加混淆字符"""  
    # 添加中缀混淆(16个随机字符)  
    infix = ''.join(random.choices(string.ascii_lowercase, k=16))  
  
    if len(s) < 20:  
        raise ValueError("密文太短,无法插入干扰")  
  
    # 在索引 35 处插入 10 个随机小写字母  
    return s[:20] + infix + s[20:]  
  
  
def to_response_data(contnet: bytes) -> bytes:  
    body = base64.b64encode(contnet).decode()  
    noisy_data = add_response_noise(body)  
    return noisy_data.encode()

完整的代码实现

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 *  
import random  
import string  
  
KEY = b""  
IV = b""  
JSON_KEY = "params"  
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_request_data(request.content)  
    # 调用函数解密  
    data: bytes = decrypt(encrypted_data)  
    # 更新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_request_data(encryptedData)  
    # 更新body  
    request.content = body  
    return request  
  
def remove_request_noise(s):  
    # 删除 35:45(10字符)  
    return s[:35] + s[45:]  
  
  
def get_request_data(content: bytes) -> bytes:  
    print("get_request_data:", content)  
    body_json: t.Dict = json.loads(content)  
    return base64.b64decode(remove_request_noise(body_json[JSON_KEY]))  
  
  
def add_request_noise(s: str) -> str:  
    """在响应数据中添加混淆字符"""  
    # 添加中缀混淆(10个随机字符)  
    infix = ''.join(random.choices(string.ascii_lowercase, k=10))  
  
    if len(s) < 35:  
        raise ValueError("密文太短,无法插入干扰")  
  
    # 在索引 35 处插入 10 个随机小写字母  
    return s[:35] + infix + s[35:]  
  
  
def to_request_data(content: bytes) -> bytes:  
    body_json = {}  
    base64_data = base64.b64encode(content).decode()  
    noisy_data = add_request_noise(base64_data)  
    body_json[JSON_KEY] = noisy_data  
    return json.dumps(body_json).encode()  
  
  
@app.post("/hookResponseToBurp", response_model=ResponseModel)  
async def hook_response_to_burp(response: ResponseModel):  
    """HTTP响应从Server到达Burp时被调用。在此处完成响应解密的代码就可以在Burp中看到明文的响应报文。"""  
    print(f"[+] hookResponseToBurp be called. response: {response.model_dump_json()}")  
    # 获取需要解密的数据  
    encryptedData: bytes = get_response_data(response.content)  
    # 调用函数解密  
    data: bytes = decrypt(encryptedData)  
    # 更新body  
    response.content = data  
    return response  
  
  
@app.post("/hookResponseToClient", response_model=ResponseModel)  
async def hook_response_to_client(response: ResponseModel):  
    """HTTP响应从Burp将要发送到Client时被调用。在此处完成响应加密的代码就可以将加密后的响应报文返回给Client。"""  
    print(f"[+] hookResponseToClient be called. response: {response.model_dump_json()}")  
    # 获取被解密的数据  
    data: bytes = response.content  
    # 调用函数加密回去  
    encryptedData: bytes = encrypt(data)  
    # 将已加密的数据转换为Server可识别的格式  
    body: bytes = to_response_data(encryptedData)  
    # 更新body  
    response.content = body  
    return response  
  
  
def remove_response_noise(s):  
    # 删除 20:36(16字符)  
    return s[:20] + s[36:]  
  
  
def get_response_data(content: bytes) -> bytes:  
    body = remove_response_noise(content)  
    return base64.b64decode((body))  
  
  
def add_response_noise(s: str) -> str:  
    """在响应数据中添加混淆字符"""  
    # 添加中缀混淆(16个随机字符)  
    infix = ''.join(random.choices(string.ascii_lowercase, k=16))  
  
    if len(s) < 20:  
        raise ValueError("密文太短,无法插入干扰")  
  
    # 在索引 35 处插入 10 个随机小写字母  
    return s[:20] + infix + s[20:]  
  
  
def to_response_data(contnet: bytes) -> bytes:  
    body = base64.b64encode(contnet).decode()  
    noisy_data = add_response_noise(body)  
    return noisy_data.encode()  
  
  
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))  
  
  
  
if __name__ == "__main__":  
    # 多进程启动  
    # uvicorn aes_cbc:app --host 0.0.0.0 --port 25000 --workers 4  
    import uvicorn  
  
    uvicorn.run(app, host="0.0.0.0", port=25000)

效果展示

输入完成手机号、验证码,点击获取验证码时发送的是加密数据包,收到的也是加密数据包:

运行脚本,设置Galaxy好后,经过代理的流量就都是解密好的了。

posted @ 2025-12-02 13:22  KAKSKY  阅读(5)  评论(0)    收藏  举报