☰
Windows数据包捕获实战指南:从SNI-Spoofing 看WinDivert与pydivert关键技巧
2026/10/2 21:10:42 网站建设 项目流程

Windows数据包捕获实战指南:从SNI-Spoofing 看WinDivert与pydivert关键技巧

【免费下载链接】SNI-SpoofingBypass DPI with IP/TCP-Header manipulation项目地址: https://gitcode.com/gh_mirrors/sn/SNI-Spoofing

SNI-Spoofing是一个运行在 Windows 上的网络流量伪装工具,它通过WinDivert 数据包捕获与pydivert库对 IP/TCP 头部进行实时篡改,实现对 DPI(深度包检测)的绕过。本文以该项目为蓝本,带你零基础掌握 Windows 平台下数据包捕获、过滤、改包与注入的完整链路,是入门 WinDivert 与 pydivert 的实用教程。

一、先搞懂:SNI 是什么?为什么值得伪装

SNI(Server Name Indication,服务器名称指示)是 TLS 握手中ClientHello明文携带的目标域名。DPI 设备正是靠读取这一字段判断"你在访问哪个网站",从而实现基于域名的拦截。

SNI-Spoofing 的思路很直接:

  1. 在本地起一个监听端口,接收客户端流量;
  2. 主动发起一条到目标服务器的连接,但用伪装域名(Fake SNI)的 ClientHello 替换真实握手首包;
  3. 利用 WinDivert 挂钩内核网络栈,实时捕获、校验并注入这条连接上的每一个 TCP 包;
  4. 握手建立后,本地流量与远端流量双向中继,对上层应用完全透明。

WinDivert数据包捕获与pydivert注入原理示意

整个方案的三个核心文件如下:

  • 主程序与中继逻辑:main.py
  • 数据包捕获与注入器:injecter.py
  • 伪装数据包处理器:fake_tcp.py

二、为什么 Windows 选 WinDivert 而不是 Npcap

很多新手做抓包会先想到 Npcap/Wireshark,但两者定位不同:

对比项Npcap / WinPcapWinDivert
能力只能捕获副本,旁路观察捕获 +修改 + 注入,可干预真实流量
层级用户态抓包驱动内核驱动(WFP 调用)
典型场景流量分析、排障流量伪装、DPI 绕过、代理加速
Python 绑定scapy / pypcappydivert

关键点在于注入(Inject):SNI-Spoofing 不是旁观者,它必须把伪造好的 ClientHello真正塞回网络栈,这正是 WinDivert 的核心价值——捕获到的包可以改头改尾后重新发回系统。

📌提醒:WinDivert 是驱动级工具,需要以管理员身份运行,这也是新手跑此类项目最常见的第一个坑。

三、pydivert 一键安装:最快配置方法

pydivert 是 WinDivert 的 Python 封装,安装只需一行(依赖已声明在 requirements.txt 中):

pip install "pydivert>=3.1.0"

pydivert 的 API 非常克制,核心只有三件套:

  1. WinDivert(filter)—— 按过滤器创建捕获句柄;
  2. recv()—— 收包,返回结构化的Packet对象;
  3. send(packet, send_as_is)—— 把包发回系统,send_as_is=True时系统不再重新计算校验和。

项目里的 injecter.py 就是一个最小可用的捕获循环:

self.w: WinDivert = WinDivert(w_filter) # 用过滤器打开驱动 with self.w: while True: packet = self.w.recv(65575) # 阻塞收包 self.inject(packet) # 逐包处理

只有 4 行,却完整体现了 Windows 数据包捕获的标准骨架:过滤器 → 收包 → 处理 → 回送。

四、技巧 1:用过滤器把流量"漏斗化"

全量捕获所有包既慢又容易误伤,正确姿势是在打开 WinDivert 时就限定范围。项目主程序在启动时动态拼接过滤器字符串(main.py):

w_filter = "tcp and (" + "(ip.SrcAddr == " + 本机IP + " and ip.DstAddr == " + 目标IP + ")" + " or " + "(ip.SrcAddr == " + 目标IP + " and ip.DstAddr == " + 本机IP + ")" + ")"

这个过滤器的含义是:只捕获本机 IP 与目标 IP 之间双向的 TCP 包。三个要点值得新手抄作业:

  • tcp and限定协议,直接排除 UDP/ICMP 等无关流量;
  • 双向条件各写一条SrcAddr/DstAddr,缺一不可,否则只能看到单方向;
  • 过滤器在 injecter.py 构造WinDivert时传入,驱动层就完成过滤,用户态零浪费。

五、技巧 2:收发判断方向,Packet 对象直接"改内存"

收到的Packet对象带有ip、tcp等结构化字段,读改都很直观。项目用 fake_tcp.py 中的inject()方法区分进出方向:

  • packet.is_inbound—— 目标服务器发来的包;
  • packet.is_outbound—— 本机发出的包。

而"改包注入"的全部魔法就在 fake_tcp.py 的fake_send_thread()里:

packet.tcp.psh = True # 打上 PSH 标志 packet.ip.packet_len = packet.ip.packet_len + len(fake_data) # 修正 IP 总长 packet.tcp.payload = connection.fake_data # 用伪造 ClientHello 替换载荷

注意packet.ip.packet_len必须手动同步——你替换了载荷长度,IP 头里的总长度字段就得跟着改,否则包在下一跳就会被丢弃。这就是"IP/TCP 头部操纵"(Header manipulation)最基础的一步。

伪造的 ClientHello 由 utils/packet_templates.py 中的ClientHelloMaker生成:以一份真实抓包的 TLS 握手为模板,只替换其中的随机数、会话 ID 和SNI 字段,伪装域名(如auth.vercel.com)在 config.json 中一行配置即可切换。

六、技巧 3:send_as_is与 TCP 序列号陷阱

这是全项目最精华、也最容易翻车的一点。项目采用wrong_seq(错误序列号)策略,见 fake_tcp.py:

if connection.bypass_method == "wrong_seq": packet.tcp.seq_num = (connection.syn_seq + 1 - len(packet.tcp.payload)) & 0xffffffff connection.fake_sent = True self.w.send(packet, True) # send_as_is = True

原理拆解:

  1. 正常握手中,客户端发出 SYN(记录其seq_num),随后第三个 ACK 的序列号应为syn_seq + 1;
  2. 程序故意把伪造包的seq_num算成"应有序列号 - 载荷长度",即一个"错误"的序列号,让 DPI 设备按常规抓包逻辑难以把 ClientHello 内容正确还原;
  3. 关键在self.w.send(packet, True)的第二个参数True(send_as_is)。默认情况下 WinDivert 回送包时会重算 TCP 校验和,而伪造的序列号需要保持"原样"送达——所以必须传True告诉驱动:别动我的校验和,包是什么样就回送什么样。

新手最常见的两个错误:

  • ❌ 用send(packet, False)回送改过的包 → 驱动重算校验和,伪装失效;
  • ❌ 忘记处理 32 位序列号回绕 → 项目里所有序号运算都带了& 0xffffffff,抄写时请勿省略。

此外,fake_tcp.py 还完整演示了握手状态机校验:SYN 的 ack_num 必须为 0、SYN-ACK 的 ack 必须等于syn_seq + 1……任何一条不满足就判定"非预期包"并安全关闭连接(见 on_unexpected_packet)。做流量注入时这种"防御性校验"是保证连接稳定性的关键。

七、项目结构速览:照着它搭你自己的抓包工具

文件职责学习要点
main.py本地监听 + 流量中继监听端口、sock_connect与 utils/network_tools.py 自动探测出口网卡 IP
injecter.py捕获循环基类WinDivert 生命周期管理(with语句)
fake_tcp.py改包与注入头部字段改写、send_as_is、状态机校验
monitor_connection.py连接状态表用五元组(src_ip, src_port, dst_ip, dst_port)作键索引连接
utils/packet_templates.pyClientHello 构造基于真实模板做字节级替换
config.json运行配置监听端口、目标 IP/端口、Fake SNI

八、常见坑与排查清单 🛠️

  1. 驱动加载失败:确认以管理员身份运行,且未被安全软件拦截 WinDivert 驱动;
  2. 收不到包:90% 是过滤器写错,先用宽松过滤器tcp验证链路再逐步收紧;
  3. 连接直接断开:检查 IP 总长是否随载荷同步更新、序列号是否处理了回绕;
  4. 校验和不匹配:确认伪造包回送时使用了send_as_is=True;
  5. 端口被占:修改 config.json 中的LISTEN_PORT后重启。

九、总结

通过 SNI-Spoofing 这个项目,一条 Windows 数据包捕获的完整知识线就串起来了:

WinDivert 过滤器精确选包 → pydivertrecv收包 → Packet 对象直接改 IP/TCP 头 →send(send_as_is)控制校验和 → 状态机保证注入时机正确

这套"捕获—篡改—注入"的三板斧,是 DPI 绕过、透明代理、流量加速类工具的通用底座。建议从 injecter.py 的四行主循环读起,再顺着 fake_tcp.py 的状态机走一遍,你就能独立搭出属于自己的 Windows 数据包处理工具了。

【免费下载链接】SNI-SpoofingBypass DPI with IP/TCP-Header manipulation项目地址: https://gitcode.com/gh_mirrors/sn/SNI-Spoofing

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询