由于需要重新验证我自己的协议内部运作背后的原理,我决定使用 netcat 来模拟幕后发生的事情。
目的 是为了模拟“打洞”的范例——一种流行的 NAT 穿越技术。在我的测试中,NAT 后面有一个客户端,还有一个服务器——它对互联网完全开放。
我有麻烦了..
练习的第一部分:;
我监听(服务器端):
netcat -v -u -l -p 492
我连接到(NAT后面)
ncat -u -p 501 REMOTE_PORT 492
这个洞似乎被打了(因为我可以从服务器发送数据)会议(请注意,UDP 是一种无状态、无连接的协议)已建立(数据到达服务器)。我只需在服务器端终端中输入即可进行测试。但我遇到了两个主要问题,可能是 netcat 本身的问题:
- 为什么 netcat 会将服务器套接字 BIND(通过调用 CONNECT 隐式地)到第一个连接的客户端超出了我的能力范围- 在一个应该(?)用于网络测试的瑞士军刀。
- 在这期间,我又生成了一个终端,希望生成另一个数据报到 501 并发往客户端节点。但没成功。我以为这是因为 netcat 将服务器套接字绑定到 501,也许它不知道如何使用 SO_REUSEADDRESS,但事实并非如此。关闭服务器后,我仍然无法找到漏洞。
还,练习的第二部分:;
- 当我从位于 NAT 后面的客户端发起传出会话时,
ncat -u -p 501 REMOTE_PORT 492
NAT 似乎允许数据报在发送了 3 个以上数据报后通过(在练习的第一部分中也发现)。如果数据报较少,则这些数据报根本无法到达目的地。但是,如果满足这样的条件,我可以在服务器端(不在 NAT 后面)通过在服务器端的 netcat 终端中键入来响应。
但是后来,我想通过以下方式重现这种情况:
- NAT 后面的客户端,发送数据报,例如:ncat -u -p 4033 REMOTE_HOST 447
我希望上述代码能在 NAT 上打一个洞,这样当数据报发往端口 4033 时,它会让数据报从 REMOTE_HOST 通过。毕竟,只有 NAT 才能看到数据报飞过,实际的服务器端代码根本没有任何意义。
- 因此,在多次启动客户端部分之后(为了模拟我之前发现的创建 NAT 规则的多个数据报的要求),我在服务器端尝试通过调用以相反的方式发送数据报:
netcat -u -p 447 NAT_IP 4033
- 希望这些数据报能够通过“洞”。
没有锁定;我已经三次检查 IP 地址是否正确 NAT_IP 与练习第一部分中以详细模式运行的服务器端报告的完全相同。
我一直在客户端用 Wireshark 监控流量;只是为了确保 netcat 和 ncat 都不会对我玩任何意想不到的把戏(比如绑定到第一个客户端或其他什么)。
从理论上讲,我相信第二个练习应该产生完全相同的结果;但事实并非如此;
我已经验证没有 ICMP 数据报流过,即由于关闭端口等可能会影响所涉及的 NAT 的决策等。
更新:我继续尝试进一步验证这一点,我在案例 1 和案例 2 之间得到了不同的结果。
上面是客户端在打洞阶段看到的 wireshark 日志。粉色水平线将案例 1(下面)和案例 2(上面)分开……在我看来,它们非常相似。不过,在第一种情况下,我可以检测到数据报从热点传输到客户端(在 NAT 后面),如下所示:
以上所用的命令是:
ncat -u -p 4433 103.102.238.182 443 <- for client side
netcat -v -u -l -p 443 <- server side
正如您在上文中看到的,双向通信已经打通。
现在,让我们尝试情况 2,其中服务器上没有运行 netcat(但没有生成 ICMP 响应)。
首先让我们执行客户端命令:
ncat -u -p 4433 103.102.238.182 443 <- for client side
通过输入并按几次回车键来生成一些数据报,这样 NAT 就会看到同样的东西。 然后在服务器端,我希望能够使用以下命令通过打孔发送 UDP 数据报:
netcat -u 37.30.0.204 4433
请注意,端口设置与上一个练习完全匹配。
结果:尽管打洞阶段的通信模式完全相同,但来自服务器端的数据报永远不会进入 NAT 后面的计算机。
更新 3:
尽可能明确一点。如果我们使用方法 1 来破坏通信通道。几秒钟后,只需终止服务器 netcat 会话 (CTRL+C),然后立即尝试通过该会话向客户端发送数据报 netcat -u 37.30.0.204 4433
- 这种方法行不通。
更新 4。作为一名逆向工程师,我花了 5 年多的时间,但仍然难以释怀。
因此,我使用:
nping -c 150 --udp -p 448 -g 445 103.102.238.182 --data-length 10 --ttl 128 --rate 5
在路由器上打一个洞。看似成功了但我无法通过调用来验证这一点
nping --udp -p 445 -g 444 37.30.0.204 --data-length 15 --ttl 48 (from client side).
37.30.0.204 地址是正确的,因为当数据报从客户端到达时,服务器端会在详细模式下报告该地址。
我甚至设置了 TTL 值来模仿练习 1 中的值。
我可以通过在服务器端生成 ncat 服务器并从那里回复(通过在终端中输入)来验证是否成功 - 当通过 nping 打洞时,数据包确实到达。(Windows 机器因 ICMP 主机不可达数据报而尖叫,是的......谁会关心 Windows 上的安全性..关闭服务器端的 netcat..但是..数据包确实通过了 NAT)。 更新 5: 我搞定了。稍后将描述对这个“问题”的回答。
答案1
好的各位,突然之间,在玩耍的时候nping
,我注意到了这一行,在服务器端,当 UDP 同时对客户端节点进行 ping 时,因为客户端正在 ping 服务器:
我的眼睛睁得大大的。。:3241当然,NAT 不断改变/转换源端口。
在练习 1 中Netcat 服务器只需查看代表传入数据报的数据结构就能清楚了解源端口。
在练习 2 中但是,我不知道 NAT 改变了源端口号,并且我坚持以客户端报告的源端口号为目标(但这根本行不通)。
无论如何,以下 nping 命令成功地完成了我们的打洞工作,并在先验描述的场景中确定了双向通信通道:
客户端(打洞):
nping -c 150 --udp -p 448 -g 445 103.102.238.182 --data-length 10 --ttl 128 --rate 5
服务器端(测试会话/建立路径):
nping --udp -p 32421 -g 448 37.30.0.204 --data-length 15 --ttl 48
下次见,伙计们。
在 Wireshark 中,在客户端可以看到预期的目标端口,这表明当数据包从服务器流向客户端时,NAT 也会进行目标地址转换。