SNI-Spoofing 架构深度解析:代理、注入、监控三大模块如何协作骗过DPI?
【免费下载链接】SNI-SpoofingBypass DPI with IP/TCP-Header manipulation项目地址: https://gitcode.com/gh_mirrors/sn/SNI-Spoofing
SNI-Spoofing 是一款运行在 Windows 上的DPI 规避工具,核心功能是通过SNI 伪造与TCP 头部操纵(wrong_seq 注入法)绕过深度包检测(DPI)封锁。它监听本地端口,把客户端流量伪装成访问白名单域名(如auth.vercel.com)的 HTTPS 连接,再悄悄转发到真实目标服务器。🔍
先搞懂背景:DPI 为什么会拦你的连接?
普通防火墙只看 IP 和端口,而DPI(深度包检测)会拆开数据包,读取 TLS 握手中的SNI 字段——即你在浏览器地址栏输入的那个域名。一旦被识别为被封锁域名,连接立刻中断。
SNI-Spoofing 的思路很巧妙:TCP 层正常握手,只在发出第一个数据包的瞬间,注入一个 SNI 指向白名单域名的伪造 ClientHello,等 DPI 放行后,再恢复正常传输。这就是"骗过 DPI"的全部秘密。
三大模块一览:3 分钟看懂项目结构
| 模块 | 文件 | 角色 | 一句话说明 |
|---|---|---|---|
| 代理模块 | main.py | 前台接线员 | 监听本地端口、建立出站连接、双向转发数据 |
| 注入模块 | fake_tcp.py + injecter.py | 幕后魔术师 | 拦截网卡流量,在握手关键帧注入伪造包 |
| 监控模块 | monitor_connection.py | 状态记录员 | 为每条连接维护五元组与握手状态 |
| 数据包工厂 | utils/packet_templates.py | 伪造件工坊 | 按模板拼装 517 字节的 ClientHello |
| 网络工具 | utils/network_tools.py | 地址探测器 | 探测默认网卡出口 IPv4 |
整个项目仅依赖 requirements.txt 中的一个库pydivert(Windows 下对 WinDivert 的 Python 封装),轻量到什么程度:整个仓库只有 372KB。
代理模块 main.py:连接的前台接线员
启动时,main.py 做三件事:
- 读取配置:从 config.json 加载监听地址、目标 IP 和目标端口;
- 创建监听套接字:在本地端口(默认 40443)等待客户端连接,并为连接配置 TCP Keep-Alive 参数防止链路超时;
- 为每条新连接开工厂:为每个进来的客户端,创建一个绑定本机出口 IP 的出站套接字,向真实目标(如
CONNECT_IP:443)发起 TCP 连接,随后建立双向异步中继——本地进来的数据发给远端,远端回来的数据发回本地。
值得注意的是,出站连接创建后并不立刻放行握手。代码会等待一个叫t2a_event的事件(timeout 2 秒),这个事件由注入模块在"确认伪造包已被服务端 ACK"之后才触发。握手没骗过去,连接就干净地关闭——这是保证不暴露的关键。🛡️
注入模块 fake_tcp.py:TCP 头操纵的核心魔法
这是整个项目最精彩的 150 行。fake_tcp.py 通过继承 injecter.py 中的TcpInjector基类,把 WinDivert 的流量过滤器精确指向"本机 IP ↔ 目标 IP"之间的 TCP 流量,然后对每个包做剧本式校验:
出站方向(on_outbound_packet):
- 捕获SYN:记录初始序列号
syn_seq,放行; - 捕获ACK(握手完成的确认包):扣住不放,立即启动一个线程,等 1 毫秒后把伪造的 ClientHello 数据"嫁接"到这个 ACK 包上——补上 PSH 标志、改写 IP 长度、把 TCP 序列号改成
syn_seq + 1 - payload长度(即故意算错),然后注入网络。
入站方向(on_inbound_packet):
- 校验服务端SYN-ACK的序列号/确认号是否匹配,不匹配立刻拆连接;
- 收到服务端对伪造数据的ACK后,宣布"骗过 DPI",触发
t2a_event,代理模块才开始真正转发。
所谓wrong_seq(错误序列号)技巧:DPI 设备通常只校验"第一个包是不是合法握手包",而不对序列号做严格核算。一个序列号不合法但内容"看起来像白名单 HTTPS 握手"的包,足以让 DPI 放行,而真正的服务端 TCP 栈会按实际数据重新同步。😎
伪造包本身由 utils/packet_templates.py 的ClientHelloMaker生成:它内置一个真实抓取的 517 字节 ClientHello 模板,运行时只替换随机数、会话 ID、SNI 字段和 key_share 四个位置,其余字节保持"原汁原味",最大限度降低被特征库识别的概率。
监控模块 monitor_connection.py:每条连接的"体检卡"
monitor_connection.py 中的MonitorConnection看似简单,却是三大模块协作的"黑板":
- 每条连接用(源IP, 源端口, 目标IP, 目标端口)五元组作为唯一 ID;
- 记录
syn_seq、syn_ack_seq两个握手状态值,供注入模块逐包比对; - 持有
thread_lock,因为 WinDivert 运行在独立线程,代理侧运行在 asyncio 事件循环,两线程共享连接对象,锁保证状态一致; - 提供
t2a_event(线程安全的事件桥),让包线程能通知 asyncio 主循环"握手骗过去了,可以放行了"。
fake_tcp.py中的FakeInjectiveConnection继承它并追加伪造数据、注入方法等字段,正是"监控"与"注入"的合体。📋
协作全流程:一次"偷天换日"的时间线
- 客户端连接本地
40443,代理模块创建出站连接并开始握手(main.py); - 注入模块捕获 SYN / SYN-ACK / ACK,全部校验放行,在 ACK 帧注入伪造 ClientHello(fake_tcp.py);
- 服务端 ACK 伪造数据,
monitor状态标记fake_data_ack_recv,监控黑板点亮事件(monitor_connection.py); - 代理模块收到事件,拆除监控,双向中继正式开启,此后流量原样穿透;
- 任何一步序列号对不上 →
on_unexpected_packet直接双向关闭,宁折不弯。
整个过程发生在毫秒级,客户端完全无感。
最快配置方法:config.json 逐项说明
| 字段 | 默认值 | 含义 |
|---|---|---|
LISTEN_HOST/LISTEN_PORT | 0.0.0.0/40443 | 本地监听地址与端口 |
CONNECT_IP/CONNECT_PORT | 188.114.98.0/443 | 真实目标服务器 |
FAKE_SNI | auth.vercel.com | 伪装的白名单域名,DPI 看到的就是它 |
修改 config.json 后重启程序即可,无需改动任何代码。⚙️
快速上手:安装与运行步骤
- 准备一台Windows机器(WinDivert 仅支持 Windows),以管理员身份运行;
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/sn/SNI-Spoofing - 安装依赖:
pip install -r requirements.txt - 按需修改 config.json 中的目标与伪域名;
- 运行
python main.py,然后把客户端(如代理客户端)指向本机40443端口。
总结
SNI-Spoofing 用极简的三模块分工实现了教科书级的 DPI 规避:main.py 负责"面上"的代理与转发,fake_tcp.py 负责"地下"的包注入,monitor_connection.py 负责把两边缝合成一条状态机。它的价值不仅在于功能,更在于是一份易读的 TCP 注入范例——如果你想深入理解 WinDivert、序列号操纵与 TLS 握手细节,这是非常好的开源样本。🎯
【免费下载链接】SNI-SpoofingBypass DPI with IP/TCP-Header manipulation项目地址: https://gitcode.com/gh_mirrors/sn/SNI-Spoofing
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考