BurpGuard 的使用案例
2024年8月15日大约 4 分钟
BurpGuard 的使用案例
注
本文版权归原作者所有,未经允许禁止转载。
前言
越来越多的师傅正在针对渗透中前端加解密生成解决方案,例如 Galaxy:https://github.com/outlaws-bai/Galaxy,而 BurpGuard
是依赖于 mitmproxy
的开发的一个简易代理框架,可以一键启动上下游代理,并编写 Python
代码对请求和响应进行自定义修改。
阅读本文前建议读者先掌握一些 Python
的基础语法,并前往项目地址,阅读项目的使用帮助。
项目地址:https://github.com/yinsel/BurpGuard
靶场项目:https://github.com/0ctDay/encrypt-decrypt-vuls/
在线练习地址:http://39.98.108.20:8085/(非本人搭建,由先知师傅搭建,轻点测)
在线靶场来源:https://xz.aliyun.com/t/15252
JS 逆向
JS 逆向的话不是特别难,可以参考先知师傅的,讲的很详细。
下面介绍下逆向的结果。
加密
加密采用 AES CBC 模式,PKCS 7 填充模式以及 Base 64 。
签名
根据当前日期生成时间戳 timestamp,以及 32 位的 id(通过 uuid 生成),最终通过以下公式生成 sign 值:
# data是原始请求数据
sign = data + id + timestamp
编写脚本并调试
以下 Demo 可直接贴在 ClientProxyHandler.py
或者是 BurpProxyHandler.py
的最下方直接运行。
解密请求数据 Demo
# 加密的数据
data = "viaGravie+m/oW4EuPkeHhloK+IDv3tzkvO3+gMNIDX2bNwDOSVxYZ84Z/c6JGWDamAmfPaulWDT8cASPYbRrg=="
data = b64decode(data.encode())
print(AES.decrypt(data,AES.CBC,b"1234567891234567",b"1234567891234567"))
结果:
b'{"password":"123456","username":"admin","validCode":"e65a"}'
生成签名 Demo
data = '{"password":"123456","username":"admin","validCode":"e65a"}'
def md5(data: str):
return hashlib.md5(data.encode()).hexdigest()
def get_sign(data: str, id: str, timestamp: str):
sign = md5(data + id + timestamp)
return sign
timestamp = str(int(time.time() * 1000))
id = uuid.uuid4().hex
sign = get_sign(data,id,timestamp)
print("timestamp:",timestamp)
print("RequestId:",id)
print("sign:",sign)
原始:

结果:
timestamp: 1723698310909
RequestId: af5abbb088674543acab0d4b44568680
sign: 91b68d873cee0a714ba584cb96caf491
复制新的签名到 Burp 中:

加密请求数据
# 原始数据
data = '{"password":"123456","username":"admin","validCode":"e65a"}'
data = AES.encrypt(data.encode(),AES.CBC,b"1234567891234567",b"1234567891234567")
print(b64encode(data).decode())
结果:
viaGravie+m/oW4EuPkeHhloK+IDv3tzkvO3+gMNIDX2bNwDOSVxYZ84Z/c6JGWDamAmfPaulWDT8cASPYbRrg==
解密响应:
# 加密的数据
data = "0uMDI+g2bagWZ6+wlwBGQYjPFu1pJ8oA39/HzrpZT7m90oXkbw2BYHkVaDSemjsXmDg3TomBk3caiSxIlLkgKkJch+VD0Utg/L0NdMbH+of1ffTgHmYmHIM/1ysStaI8cGDrZsxBsM+Ha5ATgGq/lrLEXF7LOOGxJDIPYO+HZBLHfK3uyi+oetEP8FUUrMLpU/iAeWwx2c9BaN/01mwLb7PV0HzY3/2ulZoe+jxZz3TBD1RBci5dP6Cqr+vNQ7D8eToVuC1H/0YZiRcxIWKtBgmOhHNrndDTRyb4jMwPHXFwRqJajAVWUuceQqHjOnqhyZOnUQ1krX7Bpz/h7maJ4p1lGVn0crljtoG0ZMfaKEvKSN/ErQLjDvEoBwGD9ScU"
data = b64decode(data.encode())
print(AES.decrypt(data,AES.CBC,b"1234567891234567",b"1234567891234567").decode())
结果:
{"code":"0","msg":"成功","data":{"id":15,"username":"admin","nickName":"test","sex":"
男","address":"test223","phone":"11111111111","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxNSIsImV4cCI6MTcyMzc4NTExNH0.pJyORDB6akJHwLOqmEznXOSR_wOHNZx-xO4ag0qUYMs","role":2}}
最终成品
ClientProxyHandler.py
from mitmproxy import http
from Utils.Crypto import *
import httpx
from base64 import b64encode,b64decode
from urllib.parse import quote,unquote
import json
import traceback
import time
import hashlib
import uuid
class ClientProxyHandler:
def __init__(self) -> None:
self.client = httpx.Client(timeout=None,verify=False)
# 处理来自客户端的请求,通常在这里对请求进行解密
def request(self,flow: http.HTTPFlow):
try:
req = flow.request
# 解密请求数据
if req.method == "POST" and f"{req.host}:{req.port}" == "39.98.108.20:8085":
data = req.text
data = b64decode(data.encode())
data = AES.decrypt(data,AES.CBC,b"1234567891234567",b"1234567891234567")
req.content = data
except Exception as e:
traceback.print_exception(e)
return flow
# 处理返回给客户端的响应,通常在这里对响应进行加密
def response(self,flow: http.HTTPFlow):
try:
rsp = flow.response
req = flow.request
# 加密响应数据
if f"{req.host}:{req.port}" == "39.98.108.20:8085" and rsp.content:
data = rsp.content
data = AES.encrypt(data,AES.CBC,b"1234567891234567",b"1234567891234567")
data = b64encode(data)
rsp.content = data
except Exception as e:
traceback.print_exception(e)
return flow
addons = [ClientProxyHandler()]
BurpProxyHandler.py
from mitmproxy import http
from Utils.Crypto import *
import httpx
from base64 import b64encode,b64decode
from urllib.parse import quote,unquote
import json
import traceback
import time
import hashlib
import uuid
def md5(data: str):
return hashlib.md5(data.encode()).hexdigest()
def get_sign(data: str, id: str, timestamp: str):
sign = md5(data + id + timestamp)
return sign
class BurpProxyHandler:
def __init__(self) -> None:
self.client = httpx.Client(timeout=None,verify=False)
# 处理来自Burp的请求,通常在这里对请求进行加密
def request(self,flow: http.HTTPFlow):
try:
req = flow.request
if req.method == "POST" and f"{req.host}:{req.port}" == "39.98.108.20:8085":
data = req.text
# 生成签名
timestamp = str(int(time.time() * 1000))
id = uuid.uuid4().hex
sign = get_sign(data,id,timestamp)
req.headers["sign"] = sign
req.headers["requestId"] = id
req.headers["timestamp"] = timestamp
# 加密请求数据
data = AES.encrypt(data.encode(),AES.CBC,b"1234567891234567",b"1234567891234567")
data = b64encode(data).decode()
req.text = data
except Exception as e:
traceback.print_exception(e)
finally:
return flow
# 处理返回给客户端的响应,通常在这里对响应进行解密
def response(self,flow: http.HTTPFlow):
try:
req = flow.request
rsp = flow.response
# 解密响应数据
if f"{req.host}:{req.port}" == "39.98.108.20:8085" and rsp.content:
data = rsp.text
data = b64decode(data.encode())
data = AES.decrypt(data,AES.CBC,b"1234567891234567",b"1234567891234567")
rsp.content = data
except Exception as e:
traceback.print_exception(e)
finally:
return flow
addons = [BurpProxyHandler()]
效果:

