第4章:MCP协议逆向环境搭建
说实话,搞协议逆向最怕什么?
不是看不懂报文,而是环境没搭好,抓包抓不全,插件跑不起来。我见过太多人一上来就对着Wireshark瞎点,结果关键字段全被过滤掉了。这一章,咱们就把地基打牢。
4.1 Wireshark安装与配置
Wireshark这东西,我用了快十年。版本迭代了不少,但核心配置思路没变过。
4.1.1 安装要点
- Windows用户:安装时记得勾选「Install WinPcap/Npcap」,否则抓不了包。我个人习惯用Npcap,兼容性更好。
- macOS用户:用Homebrew装最省事——
brew install wireshark。但要注意,首次运行需要授权权限。 - Linux用户:
sudo apt install wireshark,然后把自己加到wireshark组里,不然每次都要sudo。
⚠️ 避坑指南
我曾经在CentOS上装Wireshark,忘了装libpcap-dev,结果抓包界面一片空白。折腾了两小时才发现是底层库缺失。所以装完后先跑一下
我曾经在CentOS上装Wireshark,忘了装libpcap-dev,结果抓包界面一片空白。折腾了两小时才发现是底层库缺失。所以装完后先跑一下
tshark -D,看看能不能列出网卡。
4.1.2 核心配置
装好之后,别急着抓包。先做三件事:
- 设置捕获过滤器:只抓MCP相关流量。比如MCP默认端口是8888,那就写
port 8888。如果端口不固定,可以用host 192.168.1.100。 - 调整显示过滤器:这个更灵活。比如我只想看MCP的握手包,就写
mcp.handshake == 1(等我们开发完插件后生效)。 - 开启自动滚动:实时抓包时,这个功能能让你看到最新报文。在View菜单里勾上「Auto Scroll in Live Capture」。
💡 我的小习惯
我会把常用的过滤器保存成按钮。比如「MCP_Handshake」、「MCP_Data」等,点一下就能切换。在Filter工具栏旁边有个「Manage Display Filters」按钮,可以添加预设。
我会把常用的过滤器保存成按钮。比如「MCP_Handshake」、「MCP_Data」等,点一下就能切换。在Filter工具栏旁边有个「Manage Display Filters」按钮,可以添加预设。
4.2 MCP协议解析插件开发
Wireshark默认不认识MCP协议。你得告诉它:这个字段叫什么、占几个字节、怎么解析。说白了,就是写一个Lua插件。
为什么用Lua?因为不用编译,改完就能用。我早期用C写插件,改个字段名都要重新编译,太痛苦了。
4.2.1 插件结构
一个完整的MCP解析插件,至少包含这几部分:
-- mcp_protocol.lua
-- MCP协议解析插件
-- 1. 创建协议对象
local mcp_proto = Proto("mcp", "MCP Protocol")
-- 2. 定义字段
local f_version = ProtoField.uint8("mcp.version", "Version", base.DEC)
local f_msg_type = ProtoField.uint8("mcp.msg_type", "Message Type", base.DEC)
local f_length = ProtoField.uint16("mcp.length", "Length", base.DEC)
local f_payload = ProtoField.bytes("mcp.payload", "Payload")
mcp_proto.fields = {f_version, f_msg_type, f_length, f_payload}
-- 3. 解析函数
function mcp_proto.dissector(buffer, pinfo, tree)
pinfo.cols.protocol = "MCP"
local subtree = tree:add(mcp_proto, buffer(), "MCP Protocol Data")
-- 解析版本号
subtree:add(f_version, buffer(0, 1))
-- 解析消息类型
subtree:add(f_msg_type, buffer(1, 1))
-- 解析长度
subtree:add(f_length, buffer(2, 2))
-- 解析负载
subtree:add(f_payload, buffer(4, buffer:len() - 4))
end
-- 4. 注册到指定端口
local tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(8888, mcp_proto)
🔑 关键点
buffer(0, 1)表示从第0字节开始取1个字节。偏移量一定要算准,否则解析出来的数据全是乱的。我踩过这个坑,调试了一下午才发现偏移量写错了。
4.2.2 插件调试技巧
写插件最怕什么?加载失败还不知道原因。我的调试三板斧:
- 看日志:Wireshark的Lua错误会输出到控制台。Windows下按Ctrl+Shift+L打开日志窗口。
- 加打印:在插件里写
print("version:", buffer(0, 1):uint()),能帮你定位问题。 - 用测试数据:先构造一个已知的MCP报文,用
tshark -r test.pcap -Y "mcp"验证解析结果。
⚠️ 注意
插件文件要放在Wireshark的插件目录下。Windows是
插件文件要放在Wireshark的插件目录下。Windows是
%APPDATA%\Wireshark\plugins,Linux是~/.local/lib/wireshark/plugins。放错位置,Wireshark根本不会加载。
4.3 虚拟网络环境搭建
你想想看,如果直接在真实网络里抓包,万一搞崩了怎么办?所以我建议用虚拟环境。既安全又可控。
4.3.1 方案选择
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Docker Compose | 轻量、启动快 | 网络隔离不够彻底 | 快速验证协议 |
| VirtualBox + 桥接 | 完全隔离、真实感强 | 资源占用大 | 复杂场景模拟 |
| Mininet | 支持自定义拓扑 | 学习成本高 | 教学演示 |
我个人偏爱Docker Compose。为什么?因为一条命令就能拉起整个环境。我在项目中经常用它来模拟MCP客户端和服务器。
4.3.2 Docker Compose实战
下面是一个典型的MCP测试环境配置:
version: '3'
services:
mcp-server:
image: mcp-server:latest
ports:
- "8888:8888"
networks:
- mcp-net
environment:
- MCP_LOG_LEVEL=debug
mcp-client:
image: mcp-client:latest
depends_on:
- mcp-server
networks:
- mcp-net
command: ["python", "client.py", "--server", "mcp-server", "--port", "8888"]
networks:
mcp-net:
driver: bridge
启动命令就一行:docker-compose up -d。然后你就能在Wireshark里看到MCP流量了。
💡 避坑指南
我曾经在Docker里抓包,发现Wireshark只能看到宿主机流量,看不到容器内部的。后来发现是因为没把容器网卡映射出来。解决办法:在docker-compose.yml里加上
我曾经在Docker里抓包,发现Wireshark只能看到宿主机流量,看不到容器内部的。后来发现是因为没把容器网卡映射出来。解决办法:在docker-compose.yml里加上
network_mode: "host",或者用ip link把容器网桥挂到宿主机上。
4.3.3 网络拓扑设计
为了模拟真实场景,我通常会搭建一个三层拓扑:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ MCP客户端 │────▶│ 交换机/路由 │────▶│ MCP服务器 │
│ (192.168.1.2)│ │ (192.168.1.1)│ │ (192.168.1.3)│
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└────────────────────┼────────────────────┘
│
┌─────────────┐
│ Wireshark │
│ (抓包点) │
└─────────────┘
抓包点放在交换机上,这样能同时看到客户端和服务器之间的所有交互。如果条件有限,也可以在客户端或服务器上抓包,但会漏掉一些中间报文。
4.4 环境验证
环境搭好了,怎么知道能不能用?跑一个简单的测试:
- 启动Docker环境:
docker-compose up -d - 在Wireshark里选择Docker的虚拟网卡(通常是docker0或vethxxx)
- 设置显示过滤器:
tcp.port == 8888 - 在客户端执行一次MCP握手请求
- 观察Wireshark是否捕获到报文,并且协议列显示为「MCP」
如果一切正常,你会看到类似这样的输出:
Frame 1: 74 bytes on wire (592 bits)
Ethernet II, Src: 02:42:ac:11:00:02, Dst: 02:42:ac:11:00:03
Internet Protocol Version 4, Src: 192.168.1.2, Dst: 192.168.1.3
Transmission Control Protocol, Src Port: 49152, Dst Port: 8888
MCP Protocol Data
Version: 1
Message Type: 0x01 (Handshake Request)
Length: 20
Payload: [hex dump]
看到「MCP Protocol Data」这行,说明插件加载成功了。如果显示的还是「TCP」,那就回去检查插件路径或者端口注册。
🎯 总结一下
环境搭建这件事,说白了就是三个步骤:装好Wireshark、写好插件、搭好虚拟网络。每一步都有坑,但只要你按我上面说的来,基本一次过。我当年第一次搭MCP环境,光插件就调了三天。现在回想起来,其实就是偏移量算错了一位。
环境搭建这件事,说白了就是三个步骤:装好Wireshark、写好插件、搭好虚拟网络。每一步都有坑,但只要你按我上面说的来,基本一次过。我当年第一次搭MCP环境,光插件就调了三天。现在回想起来,其实就是偏移量算错了一位。
嗯,环境搭好了,接下来就可以真正开始分析MCP协议了。你准备好了吗?
公众号:蓝海资料掘金营,微信deep3321