环境测试结果: {result}”)
# 环境验证示例
def validate_environment():
env = CDPEnvironment()
if env.setup_connection():
env.enable_debug_domains()
env.test_environment()
🔒 安全与合规配置
必要的安全措施:
# 请求频率控制 – 避免触发防护机制
import time
import random
def safe_delay(min_delay=1, max_delay=3):
“””添加随机延迟避免检测”””
delay = random.uniform(min_delay, max_delay)
time.sleep(delay)
# 错误处理与日志记录
import logging
logging.basicConfig(
level=logging.INFO,
format=’%(asctime)s – %(levelname)s – %(message)s’
)
📋 环境准备检查清单
✅ Chrome浏览器已安装并配置调试端口
✅ Python 3.7+ 环境已就绪
✅ 必需依赖库已安装(websocket-client, requests)
✅ 调试接口可正常访问( http://127.0.0.1:9222/json )
✅ WebSocket连接测试通过
✅ 基础CDP命令执行正常
此环境配置为后续的加密函数定位和爆破流程实现奠定了坚实的技术基础。
三、加密函数动态定位与密钥提取
🔍 动态定位加密函数的核心方法
1. 断点调试定位法
关键步骤:通过Chrome开发者工具手动设置断点,获取加密函数执行上下文
CDP实现流程:
# 设置断点监听加密函数调用
breakpoint_cmd = {
“id”: 2,
“method”: “Debugger.setBreakpoint”,
“params”: {
“location”: {“scriptId”: “<实际脚本ID>”, “lineNumber”: <加密函数行号>}
}
}
ws.send(json.dumps(breakpoint_cmd))
# 等待断点触发并提取callFrameId
while True:
msg = json.loads(ws.recv())
if msg.get(“method”) == “Debugger.paused”:
call_frame_id = msg[“params”][“callFrames”][0][“callFrameId”]
break
2. 全局函数扫描法
使用CDP命令扫描window对象中的加密函数:
scan_cmd = {
“id”: 4,
“method”: “Runtime.evaluate”,
“params”: {
“expression”: “Object.keys(window).filter(k => k.includes(‘encrypt’) || k.includes(‘sign’))”,
“returnByValue”: True
}
}
ws.send(json.dumps(scan_cmd))
resp = json.loads(ws.recv())
encrypt_functions = resp[“result”][“result”][“value”]
🗝️ 动态密钥提取策略
1. 实时密钥捕获
在加密函数执行时捕获动态生成的密钥参数:
def capture_dynamic_key(ws, call_frame_id):
# 执行表达式获取当前加密密钥
key_cmd = {
“id”: 5,
“method”: “Debugger.evaluateOnCallFrame”,
“params”: {
“callFrameId”: call_frame_id,
“expression”: “window.currentKey || cryptoKey || encryptionKey”,
“objectGroup”: “console”
}
}
ws.send(json.dumps(key_cmd))
key_resp = json.loads(ws.recv())
return key_resp[“result”][“result”][“value”]
2. 密钥生命周期管理
会话密钥:在同一个浏览器会话中保持有效
请求级密钥:每次请求重新生成,需要实时捕获
时间戳密钥:基于时间动态变化,需同步时间参数
🛡️ 反调试环境下的定位技巧
1. 隐蔽式断点设置
避免在明显位置设置断点,选择函数内部或异步回调中
使用条件断点减少触发频率:
conditional_bp = {
“params”: {
“location”: {“scriptId”: script_id, “lineNumber”: line_num},
“condition”: “password.length > 0” # 仅当有密码输入时触发
}
}
2. 环境检测绕过
在定位前先执行反检测脚本:
anti_detect_script = “””
Object.defineProperty(navigator, ‘webdriver’, {get: () => undefined});
window.debuggerDetected = false;
“””
ws.send(json.dumps({
“method”: “Runtime.evaluate”,
“params”: {“expression”: anti_detect_script}
}))
📊 动态参数追踪表
参数类型 提取方法 更新频率 CDP命令
静态密钥 页面加载后一次性提取 会话级 Runtime.evaluate
动态令牌 请求前实时捕获 请求级 Debugger.evaluateOnCallFrame
时间戳参数 同步浏览器时间 秒级 Runtime.evaluate(Date.now())
随机数种子 跟踪随机函数调用 每次加密 条件断点监控
🔧 实战代码:完整的动态定位流程
class EncryptionLocator:
def __init__(self, ws_connection):
self.ws = ws_connection
self.call_frame_id = None
self.current_key = None
def setup_encryption_monitoring(self):
“””设置加密函数监控”””
# 启用必要域
self.ws.send(json.dumps({“id”:1,”method”:”Debugger.enable”}))
self.ws.send(json.dumps({“id”:2,”method”:”Runtime.enable”}))
# 搜索加密相关函数
encrypt_funcs = self.scan_encryption_functions()
print(f”[+] 发现加密函数: {encrypt_funcs}”)
# 设置断点监控
for func_name in encrypt_funcs:
self.set_function_breakpoint(func_name)
def wait_for_encryption_call(self, timeout=30):
“””等待加密函数被调用”””
start_time = time.time()
while time.time() – start_time < timeout:
msg = json.loads(self.ws.recv())
if msg.get(“method”) == “Debugger.paused”:
# 检查是否在加密函数中断
call_frame = msg[“params”][“callFrames”][0]
if any(keyword in call_frame[“functionName”] for keyword in [‘encrypt’, ‘sign’]):
self.call_frame_id = call_frame[“callFrameId”]
self.extract_dynamic_parameters()
return True
# 非加密断点,继续执行
self.ws.send(json.dumps({“id”:10,”method”:”Debugger.resume”}))
return False
def extract_dynamic_parameters(self):
“””提取动态加密参数”””
# 获取当前加密密钥
key_expr = “window.currentKey || cryptoKey || encryptionKey || ””
key_cmd = {
“id”: 20,
“method”: “Debugger.evaluateOnCallFrame”,
“params”: {
“callFrameId”: self.call_frame_id,
“expression”: key_expr
}
}
self.ws.send(json.dumps(key_cmd))
key_resp = json.loads(self.ws.recv())
self.current_key = key_resp[“result”][“result”][“value”]
print(f”[+] 动态密钥已捕获: {self.current_key}”)
123