别再只抓HTTP了!手把手教你用Fiddler Script拦截修改手游WebSocket封包
深度解析Fiddler Script在手游WebSocket协议逆向中的应用手游行业近年来呈现爆发式增长越来越多的游戏采用WebSocket协议来实现实时交互功能。与传统的HTTP协议相比WebSocket提供了全双工通信能力特别适合需要低延迟的实时游戏场景。然而这也给安全研究人员和开发者带来了新的挑战——如何有效地拦截和分析WebSocket封包1. WebSocket协议与手游交互机制WebSocket协议自2011年成为IETF标准以来已经成为现代实时网络应用的基石。在手游领域它被广泛应用于以下场景实时对战系统如MOBA、FPS等竞技类游戏聊天和社交功能游戏状态同步位置、血量等动态数据即时排行榜更新WebSocket与HTTP的关键区别特性HTTPWebSocket通信模式请求-响应全双工连接建立每次请求新建持久连接头部开销每次请求携带完整头部建立连接后极小帧头延迟较高极低服务器推送不支持原生支持理解这些差异对后续的封包拦截至关重要。传统的HTTP抓包工具虽然能捕获WebSocket握手阶段但对后续的数据帧往往无能为力。2. Fiddler环境配置与WebSocket捕获要开始WebSocket封包分析首先需要正确配置Fiddler环境。以下是详细步骤安装最新版Fiddler Classic确保版本号≥5.0旧版对WebSocket支持有限安装时勾选所有可选组件基础代理配置# 查看电脑IP地址Windows ipconfig /all进入Tools Options Connections设置监听端口建议8866或8888勾选Allow remote computers to connectHTTPS解密设置在Options HTTPS标签页勾选Decrypt HTTPS traffic信任Fiddler根证书重要WebSocket特定配置// 在FiddlerScript中添加以下规则 if (oSession.oRequest.headers.Exists(Upgrade) oSession.oRequest.headers[Upgrade] websocket) { oSession[x-breakrequest] websocket; }注意部分手游会检测代理设置遇到这种情况需要结合虚拟机或特定绕过技术这超出了本文范围。3. Fiddler Script核心技术与实战案例Fiddler Script是基于JScript.NET的脚本系统可以深度定制Fiddler行为。下面我们通过一个回合制游戏的出牌指令修改案例展示其强大功能。3.1 WebSocket帧拦截基础WebSocket协议数据帧结构如下0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -------------------------------------------------------- |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len126/127) | | |1|2|3| |K| | | ------------------------- - - - - - - - - - - - - - - - 在Fiddler Script中我们可以这样处理WebSocket帧static function OnWebSocketMessage(oMsg: WebSocketMessage) { // 只处理发送方向的帧游戏客户端-服务器 if (!oMsg.IsOutbound) return; // 获取原始Payload var originalPayload oMsg.PayloadAsBytes(); // 示例修改出牌指令假设opcode 0x8表示出牌 if (originalPayload[0] 0x8) { var modifiedPayload ModifyCardPlay(originalPayload); oMsg.SetPayload(modifiedPayload); } } static function ModifyCardPlay(original: Byte[]): Byte[] { // 这里实现具体的牌面修改逻辑 // 例如将卡牌ID 0x12改为0x1A普通攻击变必杀技 if (original.Length 5 original[4] 0x12) { original[4] 0x1A; } return original; }3.2 复杂协议逆向技巧实际手游协议往往采用以下保护措施Payload加密常见XOR、AES或自定义算法压缩zlib、lz4等协议混淆添加冗余字段或打乱结构针对加密Payload的处理示例static function DecryptPayload(encrypted: Byte[]): Byte[] { // 简单XOR解密示例实际游戏可能更复杂 var key 0x55; var decrypted new Byte[encrypted.Length]; for (var i 0; i encrypted.Length; i) { decrypted[i] encrypted[i] ^ key; } return decrypted; } static function OnWebSocketMessage(oMsg: WebSocketMessage) { if (oMsg.IsOutbound) { var decrypted DecryptPayload(oMsg.PayloadAsBytes()); // 分析解密后的协议结构... } }4. 高级应用与安全测试掌握了基础拦截技术后可以开展更深入的安全测试4.1 自动化测试框架集成将Fiddler Script与自动化测试工具结合# Python示例与Fiddler联动进行压力测试 import websocket import threading def send_modified_frame(): ws websocket.WebSocket() ws.connect(ws://game-server:8080) # 发送经过Fiddler修改的帧 ws.send_binary(b\x08\x05\x00\x00\x00\x1A) for i in range(100): threading.Thread(targetsend_modified_frame).start()4.2 常见漏洞检测模式手游WebSocket协议常见安全问题逻辑漏洞回合间隔时间篡改资源数量溢出非法状态切换安全缺陷缺乏帧完整性校验敏感操作无二次确认客户端过度信任测试用例表示例测试类型攻击载荷预期结果实际结果速度破解修改回合间隔为负值服务器拒绝回合立即结束资源作弊发送极大数值资源请求服务器校验客户端显示溢出状态异常未解锁角色使用指令权限拒绝角色可操控5. 实战从协议分析到功能修改让我们通过一个完整的案例演示如何发现并修改游戏功能协议分析阶段捕获正常出牌操作的WebSocket帧对比不同卡牌的Payload差异识别关键字段位置和含义功能修改阶段// 在FiddlerScript中实现自动替换卡牌 static var cardMapping { 0x12: 0x1A, // 普通攻击→必杀技 0x13: 0x14, // 防御→治疗 0x15: 0x16 // 道具→复活 }; static function ModifyCardPlay(original: Byte[]): Byte[] { if (original.Length 5) { var cardType original[4]; if (cardMapping.ContainsKey(cardType)) { original[4] cardMapping[cardType]; } } return original; }测试验证阶段确保修改后的帧能被服务器接受验证游戏逻辑是否按预期改变检查是否会触发反作弊机制重要提示这类技术应仅用于授权测试。未经许可修改游戏数据可能违反服务条款甚至法律法规。6. 调试技巧与性能优化当处理复杂的WebSocket协议时这些技巧能提高效率条件断点只在特定帧触发拦截if (oMsg.PayloadAsString().Contains(battle_result)) { oSession[x-breakrequest] break; }流量记录与回放# 使用Fiddler的SAZ文件保存会话 # 可通过命令行批量处理 fiddler.exe /replay sessions.saz性能统计脚本static var stats {inCount:0, outCount:0, totalSize:0}; static function OnWebSocketMessage(oMsg: WebSocketMessage) { if (oMsg.IsOutbound) stats.outCount; else stats.inCount; stats.totalSize oMsg.PayloadAsBytes().Length; } static function OnDone() { FiddlerObject.alert(流量统计 入站帧${stats.inCount} 出站帧${stats.outCount} 总数据量${stats.totalSize}字节); }在实际项目中我发现最耗时的往往不是脚本编写而是协议结构的逆向分析。建立完善的日志系统能大幅提升效率// 协议日志记录实现 static function LogFrame(direction: String, payload: Byte[]) { var logFile C:\\ws_log.txt; var sw System.IO.File.AppendText(logFile); sw.WriteLine(${DateTime.Now} [${direction}] ${BytesToHex(payload)}); sw.Close(); } static function BytesToHex(bytes: Byte[]): String { return bytes.Select(b b.ToString(X2)).Aggregate((a,b) a b); }7. 进阶工具链整合单一工具难以应对所有场景推荐整合以下工具Wireshark底层协议分析Charles Proxy备用抓包方案IDA Pro/Ghidra客户端二进制分析Burp SuiteWebSocket安全测试工具对比表工具WebSocket支持脚本扩展移动端友好性能影响Fiddler优秀强大中等低Charles良好有限优秀中Wireshark基础无差高Burp Suite专业中等中等中对于需要深度协议逆向的场景我通常会采用以下工作流程用Fiddler捕获初始流量识别关键协议特征对加密协议使用IDA分析手游客户端提取算法将算法移植到Fiddler Script实现实时解密建立自动化测试用例验证修改效果# 示例将IDA分析的算法移植到Python测试 def client_encrypt(data: bytes) - bytes: # 从手游客户端逆向的加密算法 result bytearray() key 0x7F for b in data: result.append((b key) 0xFF) key result[-1] return bytes(result)这套方法在多个商业手游的安全测试中效果显著但需要扎实的逆向工程基础。对于新手建议从简单的XOR加密协议开始练习。