/n4

双 NAT4 网络打洞 PoC

Primary LanguagePythonGNU General Public License v3.0GPL-3.0

N4

N4 是针对双方均为 “端口递增型 NAT” 的一种打洞测试工具。

“端口递增型 NAT” 不限制 NAT 种类。
也就是说,即使双方均为对称型 NAT(NAT4 - NAT4),只要满足端口递增,也可使用此工具成功打通。

快速开始

公网服务器运行:

python3 n4.py -s

需要打洞的两个 NAT4 客户端运行:

python3 n4.py -c -h 服务器IP

客户端日志显示:

[2024-06-01 12:38:56,438] INFO [n4.py:375] ==================
[2024-06-01 12:38:56,439] INFO [n4.py:376] Source port: 30000-30025
[2024-06-01 12:38:56,459] INFO [n4.py:287]  <= Hello 
[2024-06-01 12:38:56,471] INFO [n4.py:293]  => Ready 
[2024-06-01 12:38:56,472] INFO [n4.py:302]  <= Exchange 
[2024-06-01 12:38:56,486] INFO [n4.py:312]  => Peer: 203.0.113.12:5793 
[2024-06-01 12:38:56,486] INFO [n4.py:313]  [ Target: 203.0.113.12:5813 ] 
[2024-06-01 12:38:56,487] INFO [n4.py:321]  <= Punch 
[2024-06-01 12:39:06,498] INFO [n4.py:386] [ LOSE ]
[2024-06-01 12:39:06,500] INFO [n4.py:375] ==================
[2024-06-01 12:39:06,500] INFO [n4.py:376] Source port: 30025-30050
[2024-06-01 12:39:06,514] INFO [n4.py:287]  <= Hello 
[2024-06-01 12:39:06,526] INFO [n4.py:293]  => Ready 
[2024-06-01 12:39:06,527] INFO [n4.py:302]  <= Exchange 
[2024-06-01 12:39:06,541] INFO [n4.py:312]  => Peer: 203.0.113.12:5434 
[2024-06-01 12:39:06,541] INFO [n4.py:313]  [ Target: 203.0.113.12:5454 ] 
[2024-06-01 12:39:06,542] INFO [n4.py:321]  <= Punch 
[2024-06-01 12:39:06,556] INFO [n4.py:334]  => Punch from peer 
[2024-06-01 12:39:08,559] INFO [n4.py:342]  <= Punch 
[2024-06-01 12:39:08,560] INFO [n4.py:379] ------
[2024-06-01 12:39:08,560] INFO [n4.py:380] Local port:    30040
[2024-06-01 12:39:08,560] INFO [n4.py:381] Peer address:  203.0.113.12:5454
[2024-06-01 12:39:08,560] INFO [n4.py:382] ------
[2024-06-01 12:39:08,560] INFO [n4.py:383] [ WIN ]
[2024-06-01 12:39:08,560] INFO [n4.py:385] > nc -u -p 30040 203.0.113.12 5454

日志出现 [ WIN ] 字样,表示两者打通。

双方运行日志中提示的 nc 命令,即可互相进行 P2P 通信。

打洞过程

服务端监听 TCP/1721UDP/1721

  • TCP 端口用于与客户端通信;
  • UDP 端口仅用于获取客户端公网上的IP、端口信息,只接收不发送。

打洞过程共有 5 步:

1. Hello       client --TCP-> server
2. Ready       client <-TCP-- server
3. Exchange    client --UDP-> server
4. Peerinfo    client <-TCP-- server
5. Punch       client <-UDP-> client

解释说明:

  1. 客户端向服务端发送 Hello 包;
  2. 服务端收到两个客户端的 Hello 包后,同时向两方发送 Ready 包;
  3. 客户端收到 Ready 包,使用 UDP 向服务器发送 Exchange 包,表示交换两客户端 UDP 公网信息;
  4. 服务端收到一客户端的 Exchange 包,向另一客户端发送 Peerinfo 包,携带前者 UDP 公网信息;
  5. 客户端收到 Peerinfo 包,根据对方地址 IP:PORT, 预测对方将来的地址会有 IP:PORT + peer_port_offset。 客户端从自身端口 src_port_start ~ src_port_start + src_port_count 范围, 使用 UDP 逐一向 IP:PORT + peer_port_offset 固定地址发送 Punch 包。

如果客户端收到 Punch 包,代表打通。否则,增加源端口值,再次尝试。

示例说明

下面是一个示例,假设有以下设定值。

src_port_start      = 30000
src_port_count      = 8
peer_port_offset    = 5

括号内为 NAT 转换后的地址。该地址只对目标可见,对来源不可见。

客户端A:

---(Exchange)---
192.168.1.101:30000 --> (198.51.100.3:1801) --> 192.0.2.2:1721
----(Punch)-----
192.168.1.101:30000 --> (198.51.100.3:1803) --> 203.0.113.12:3028
192.168.1.101:30001 --> (198.51.100.3:1804) --> 203.0.113.12:3028
192.168.1.101:30002 --> (198.51.100.3:1807) --> 203.0.113.12:3028
192.168.1.101:30003 --> (198.51.100.3:1806) --> 203.0.113.12:3028 [*]
192.168.1.101:30004 --> (198.51.100.3:1810) --> 203.0.113.12:3028
192.168.1.101:30005 --> (198.51.100.3:1812) --> 203.0.113.12:3028
192.168.1.101:30006 --> (198.51.100.3:1817) --> 203.0.113.12:3028
192.168.1.101:30007 --> (198.51.100.3:1814) --> 203.0.113.12:3028

客户端B:

---(Exchange)---
192.168.0.112:30000 --> (203.0.113.19:3023) --> 192.0.2.2:1721
----(Punch)-----
192.168.0.112:30000 --> (203.0.113.12:3025) --> 198.51.100.3:1806
192.168.0.112:30001 --> (203.0.113.12:3029) --> 198.51.100.3:1806
192.168.0.112:30002 --> (203.0.113.12:2030) --> 198.51.100.3:1806
192.168.0.112:30003 --> (203.0.113.12:3031) --> 198.51.100.3:1806
192.168.0.112:30004 --> (203.0.113.12:3028) --> 198.51.100.3:1806 [*]
192.168.0.112:30005 --> (203.0.113.12:3032) --> 198.51.100.3:1806
192.168.0.112:30006 --> (203.0.113.12:3033) --> 198.51.100.3:1806
192.168.0.112:30007 --> (203.0.113.12:3034) --> 198.51.100.3:1806

在以上打洞组合中,[*] 标记的一对尝试,成功打通。

客户端 A 运行:

nc -u -l 30003

客户端 B 运行:

nc -u -p 30004 198.51.100.3 1806

两者即可 P2P 通信。

License

GNU General Public License v3.0