PhantomSocks - 修改TCP帧从而实现突破防火墙

许久不见,一年没有写博文了。碰巧最近了解到一个突破防火墙的项目与大家分享下。不同于传统的加密 + 中转的形式,这个项目用了全新的思路。

原理

技术背景

TLS 握手时会发送 SNI(可以理解为域名),用于帮助单 IP 多站点的服务器实现 HTTPS。但加密型 SNI(如 ESNI 和 ECH)尚未普及,且防火墙会直接对此采取 TCP RST 阻断措施,所以目前 SNI 都是明文形式。

明文 SNI 会暴露你访问的网站域名,防火墙便可通过域名黑名单机制,屏蔽对应网站。现实中因难以维护等原因,较少采用直接屏蔽 IP 的策略。

传统的解决方案,便是利用通信正常的服务器进行中转传输。

新思路实现

PhantomSocks 利用 WinDivert(Windows)、Pcap、RawSocket(Linux) 修改 TCP 帧,伪造部分帧参数。修改后的 TCP 帧不合常理,会使大部分防火墙的审查功能紊乱,无法正常进行 SNI 检测,也就不会发出 RST 阻断连接。

概括来说,可以突破被 DNS 污染的网站。

等等,这不是修改 TCP 帧吗?应该通用性很强吧?实则不然,TCP 阻断只是众多封禁方法的一种,这些情况不适用:

  1. 其他传输层协议。如 UDP 丢弃,DCCP QoS 等。
  2. 基于 TCP 的顶层协议审查。如应用层的 HTTP 明文检测,后续传输依然会被 RST 阻断。
  3. 底层协议封锁。如网络层 IP 黑名单,除非找到可用的 IP。

更多技术细节见论文:https://conferences.sigcomm.org/imc/2017/papers/imc17-final59.pdf

使用说明

1. 下载安装 PhantomSocks

全平台版本

https://github.com/Macronut/phantomsocks
对外提供一个无加密 & 可选认证的代理接口(Socks5、HTTP、SS)供其他软件连接使用,或 Redirect 重定向所有流量。

编译安装:go get github.com/macronut/phantomsocks

默认是 Pcap 模式,RawSocket 和 Windivert 模式的编译及跨平台交叉编译请参见 README,本文不再赘述。

Windows 衍生版(TCPioneer)

https://github.com/Macronut/TCPioneer
直接接管网卡,全局代理。Releases 中有预编译程序。

2. 配置 PhantomSocks

参数讲解

配置文件看起来有点复杂,不过简单总结只要注意几点:

  1. DNS 解析服务器。用于解析网站 IP。
  2. 网站的 IP 地址,类似 hosts。对于某些大范围 IP 封锁的网站,需要手动指定可用的 IP 地址,而不能依赖 DNS 服务器返回的结果
  3. TCP 帧修改及发送策略。不同网站由于采用的服务器技术不同,对各种修改后的 TCP 帧的适应性也不同。需要调整到可迷惑防火墙但目标服务器可正确识别的形式。

【知识点】TCP 协议帧头结构

Source port | 源端口
Destination port | 目标端口
Sequence number | 帧序号
Acknowledgment number | 应答号
Data offset | 偏移量
Reserved | 保留备用
Flags x 9 | 9个标志
Window size | 窗口大小
Checksum | 校验和
Urgent pointer | 紧急指针

为了能正常传输 TCP 帧,有一些帧参数是不可修改的。PhantomSocks 可伪造的 TCP 帧参数包括:

  1. SEQ number 帧序号
  2. ACK number 应答号
  3. Checksum 校验和
  4. Urgent pointer 中的 timestamp 时间戳
  5. Flags 标志中的 SYN 标志(可选,用于 TCP 快速开启,0-RTT)
  6. Destination port 目标端口(可选,仅用于传输层的 HTTP 80 重定向 HTTPS 443)
  7. MD5(准确的说属于报文段结构,非帧结构)

同时为了保证网络层能正确转发 IP 数据包,PhantomSocks 还可以同时修改 IP 包:

  1. TTL 生存时间
  2. Destination IP 及 Version(可选,仅用于强制 IPv4 或强制 IPv6)

配置实战

大多数网站只需要伪造帧序号便可顺利突破防火墙。具体需要根据目标服务器调试。

这里提供一段我标注了注释的配置文件作为参考,更多参数详见项目 README。

# 日志等级
log=5

# TCP 帧伪造方法。伪造 MD5 校验。
method=w-md5

# 指定 DNS 解析服务器,用于解析未手动提供 IP 的域名
server=tls://1.0.0.1:853

# 重置 TCP 帧伪造方法,本行以后的域名生效。更正为伪造 MD5 校验、伪造帧序号、开启强制 HTTPS
method=w-md5,s-seg,https

# 指定相关域名未封禁的 IP
google.com=172.253.114.90,172.217.203.90,172.253.112.90,142.250.4.90,142.250.9.90,172.253.116.90,142.250.97.90,142.250.30.90,142.250.111.90,172.217.215.90,142.250.11.90,142.251.9.90,108.177.122.90,142.250.96.90,142.250.100.90,142.250.110.90,172.217.214.90,172.217.222.90,142.250.31.90,142.250.126.90,142.250.10.90,172.217.195.90,172.253.115.90,142.251.5.90,142.250.136.90,142.250.12.90,142.250.101.90,172.217.192.90,142.250.0.90,142.250.107.90,172.217.204.90,142.250.28.90,142.250.125.90,172.253.124.90,142.250.8.90,142.250.128.90,142.250.112.90,142.250.27.90,142.250.105.90,172.253.126.90,172.253.123.90,172.253.122.90,172.253.62.90,142.250.98.90

# 下列子域及泛解析皆使用上述未封禁 IP
ajax.googleapis.com=[google.com]
.google.com=[google.com]
.google.com.hk=[google.com]
.googleusercontent.com=[google.com]
.ytimg.com=[google.com]
.ggpht.com=[google.com]
.gstatic.com=[google.com]
.translate.goog=[google.com]
blogspot.com=[google.com]
.blogspot.com=[google.com]

# 某些域难以找到未封禁 IPv4,则可以用 SNI 代理中转(龟速)
sniproxy=78.129.226.64,43.255.113.231,43.255.113.229,178.255.46.176,67.222.65.2,69.162.113.194,204.12.225.226,87.117.205.40,69.162.113.198,69.28.83.244,5.152.185.10,213.183.56.23,69.28.82.253,178.209.51.200,78.129.226.113,31.200.241.28
dns.google=[sniproxy]
.googlevideo.com=[sniproxy]

# 本地有 IPV6 的话亦可以强制走 IPv6。这里不手动提供 SNI 代理和 IP,将自动由 DNS 解析对应 IPv6
# ipv6=true
# .googlevideo.com

3. 启动 PhantomSocks

全平台版本

使用命令运行,需要指定对外代理端口,部分设备还需要指定出口网卡。

Linux(pcap&rawsocket):
sudo ./phantomsocks -device eth0 -socks 0.0.0.0:1080

Windows(windivert):
phantomsocks -socks 0.0.0.0:1080

macOS:
./phantomsocks -device en0 -socks 127.0.0.1:1080 -proxy socks://127.0.0.1:1080

或者重定向网卡流量,Linux 要先用 iptables 重定向。

Linux(pcap&rawsocket):
iptables -t nat -A OUTPUT -d 6.0.0.0/8 -p tcp -j REDIRECT --to-port 6
./phantomsocks -device eth0 -dns :53 -redir :6

Windows(windivert):
./phantomsocks -redir 0.0.0.0:6 -proxy redirect://0.0.0.0:6

Windows 衍生版(TCPioneer)

直接以管理员权限运行可执行文件,或者使用预置 bat 写入系统服务。

其他事项

安全性
防火墙放行后,实际为本机直连目标网站服务器 IP,防火墙日志必定会留下痕迹,所以需要承担风险。

稳定性
直连线路质量决定实际体验。大多数被屏蔽的网站和本地线路的直连效果由多方面因素决定,一般丢包率感人(主要原因是出口汇聚层拥堵,这真不是防火墙的锅,有空再写文详细介绍)

另外,防火墙可能会改进对 TCP 帧的审查方式(这不是什么难事),如果未来防火墙不受 PhantomSocks 的伪造干扰,这种方案自然也就失效了。

    jack
    jack  2022-08-01, 05:29

    配置文件进行了大改动,我想问一下博主是怎么解决

      xinxin8816
      xinxin8816  2022-08-20, 23:21

      只是换成了json,底层逻辑没有变

        Devil.Antivirus
        Devil.Antivirus  2022-08-24, 13:17

        现在好像没法直接./phantomsocks -device xxx -socks xxx启动服务了,是需要先改配置文件config.json吗

          xinxin8816
          xinxin8816  2022-09-22, 22:47

          是的,现在这些参数都写在config里

    访客
    访客  2023-01-26, 16:44

    “基于 TCP 的下层协议审查。”和“顶层协议封锁。”这两个搞混了吧……应用层是顶层,而网络层则是相对于传输层而言的下层……

      xinxin8816
      xinxin8816  2023-03-13, 08:36

      感谢指正。我对顶层底层的理解有误。

    qiansui
    qiansui  2023-07-15, 00:36

    您好,我被短信轰炸了,可以帮帮我吗?

    SYO
    SYO  2023-12-13, 16:52

    我是来感谢你的短信轰炸台的,3Q!