在渗透的"幽灵模式"中开启"透视"外挂
字数 1694 2025-08-19 12:41:48
渗透测试中的"幽灵模式":针对全加密Web应用的透视技术详解
1. 背景与问题描述
本文档详细解析了一种针对请求和响应全加密Web应用的渗透测试解决方案。目标网站具有以下特征:
- 所有请求参数都经过加密后赋值给
data字段 - 每个请求都有
sign签名验证 - 响应体
res字段同样经过加密 - 使用国密SM4算法进行CBC模式的对称加密
这种全加密机制给渗透测试带来极大不便,需要开发一种"透视"技术,在不影响正常功能的前提下实现请求和响应的明文查看与修改。
2. 加密机制分析
2.1 data字段加密分析
-
加密流程:
- 原始参数被赋值给变量
t - 调用
v(t)函数对t进行加密 - 加密结果赋值给请求的
data字段
- 原始参数被赋值给变量
-
加密函数分析:
- 使用国密SM4算法
- CBC加密模式
- 密钥:
d6a785b93b6c0d4a - IV向量:
2d91d2be3ad9e42c
-
验证方法:
from gmssl import sm4 import base64 def encrypt_SM4(value): gmsm4 = sm4.CryptSM4() gmsm4.set_key(b'd6a785b93b6c0d4a', sm4.SM4_ENCRYPT) encrypt_value = gmsm4.crypt_cbc(b'2d91d2be3ad9e42c', value.encode()) return base64.b64encode(encrypt_value).decode('utf-8')
2.2 sign签名分析
-
签名生成逻辑:
- 固定值
this.COMPID为"CLYTB" - 对
COMPID进行MD5得到t值:d4a4a210ed3d3d367049d4d331883485 - 签名公式:
sign = md5(t + 原始参数 + "VETRIP_B2C")
- 固定值
-
验证方法:
import hashlib def generate_sign(text): md5_hash = hashlib.md5() md5_hash.update(('d4a4a210ed3d3d367049d4d331883485'+text+'VETRIP_B2C').encode()) return md5_hash.hexdigest()
3. 解决方案架构
整体解决方案分为三个关键部分:
- 浏览器端修改:禁用请求加密
- 中间代理层:负责请求加密和响应解密
- 浏览器响应处理修改:适配解密后的响应
浏览器(明文) → Burp(明文) → 中间代理(加密) → 目标服务器
目标服务器(加密) → 中间代理(解密) → Burp(明文) → 浏览器(适配处理)
4. 详细实施步骤
4.1 浏览器端请求加密禁用
-
启用Chrome本地覆盖:
- 打开DevTools → Sources → Overrides
- 选择一个空文件夹并允许
- 刷新页面,找到加密JS文件
-
修改加密逻辑:
- 定位到
t = v(t)这行代码 - 删除或注释掉这行代码,防止请求参数被加密
- 保存修改(Ctrl+S)
- 定位到
-
注意事项:
- 不要随意格式化JS代码,可能破坏功能
- 保持DevTools打开状态
4.2 中间代理层实现
使用mitmproxy作为Burp的上游代理,实现自动加解密:
import base64
import hashlib
import json
from gmssl import sm4
from mitmproxy import ctx
# 加密配置
encrypt_key = b'd6a785b93b6c0d4a'
iv = b'2d91d2be3ad9e42c'
gmsm4 = sm4.CryptSM4()
def encryptSM4(value):
gmsm4.set_key(encrypt_key, sm4.SM4_ENCRYPT)
data_str = str(value)
encrypt_value = gmsm4.crypt_cbc(iv, data_str.encode())
return base64.b64encode(encrypt_value).decode('utf-8')
def decryptSM4(encrypt_value):
encrypt_value = base64.b64decode(encrypt_value).hex()
gmsm4.set_key(encrypt_key, sm4.SM4_DECRYPT)
decrypt_value = gmsm4.crypt_cbc(iv, bytes.fromhex(encrypt_value))
return decrypt_value.decode()
def sign(text):
md5_hash = hashlib.md5()
md5_hash.update(('d4a4a210ed3d3d367049d4d331883485'+text+'VETRIP_B2C').encode())
return md5_hash.hexdigest()
def request(flow):
"""处理请求:加密data并更新sign"""
if flow.request.urlencoded_form:
data_value = flow.request.urlencoded_form['data']
flow.request.urlencoded_form['data'] = encryptSM4(data_value)
flow.request.urlencoded_form['sign'] = sign(data_value)
def response(flow):
"""处理响应:解密res字段"""
content_type = flow.response.headers.get("Content-Type", "")
if "application/json" in content_type:
response_body = flow.response.get_text()
json_data = json.loads(response_body)
json_data['res'] = decryptSM4(json_data['res'])
flow.response.set_text(json_data['res'])
启动命令:
mitmproxy.exe -p 8081 -s ./mit.py
4.3 浏览器响应处理修改
-
定位响应处理代码:
- 在JS中搜索
"res"定位响应处理逻辑 - 找到对
res字段的解密调用
- 在JS中搜索
-
修改解密逻辑:
- 原始代码通常包含
JSON.parse(b(i))或类似结构 - 修改为直接使用响应数据,因为代理已解密
- 示例修改:
// 原代码 var i = t.data.res; var r = JSON.parse(b(i)); // 修改为 var i = t.data.res; var r = i; // 直接使用已解密的数据
- 原始代码通常包含
-
异常处理:
- 注意避免对已经是JavaScript对象的变量再次调用
JSON.parse() - 确保修改后的代码不会破坏原有业务逻辑
- 注意避免对已经是JavaScript对象的变量再次调用
5. 验证与测试
-
请求验证:
- 在Burp中查看请求,确认
data字段为明文 - 确认
sign值正确生成
- 在Burp中查看请求,确认
-
响应验证:
- 在Burp中查看响应,确认
res字段已解密 - 浏览器功能正常,无报错
- 在Burp中查看响应,确认
-
渗透测试:
- 可以自由修改请求参数进行测试
- 能够直接查看响应内容分析漏洞
6. 技术要点总结
-
关键加密算法:
- 国密SM4对称加密
- CBC模式
- 固定密钥和IV
-
签名机制:
- 基于固定值和参数的MD5哈希
- 包含特定业务字符串
VETRIP_B2C
-
解决方案核心:
- 浏览器本地覆盖禁用加密
- 中间代理透明加解密
- 浏览器响应处理适配
-
工具链:
- Chrome DevTools本地覆盖
- mitmproxy中间代理
- Burp Suite作为主测试工具
7. 潜在问题与解决方案
-
JS格式化问题:
- 某些JS文件格式化后可能无法正常工作
- 解决方案:先保存原始文件再格式化,或部分格式化
-
加密算法变更:
- 目标网站可能更新加密方式
- 解决方案:定期检查加密逻辑,更新代理脚本
-
签名机制更新:
- 签名公式可能加入动态元素
- 解决方案:重新分析签名生成逻辑
-
HTTPS证书问题:
- mitmproxy需要安装CA证书
- 解决方案:正确配置mitmproxy证书
8. 扩展应用
本技术方案可应用于以下场景:
- 对全加密API接口的安全测试
- 黑盒测试中的协议分析
- 移动应用与加密后端通信的分析
- 其他需要"透视"加密通信的场景
只需根据具体加密算法和签名机制调整代理脚本即可。