⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nat爆破者:在不同nat后的主机间建立tcp连接.txt

📁 P2P穿透NAT的一次探讨和局部实现
💻 TXT
📖 第 1 页 / 共 4 页
字号:
    每个参与TCP连接者都维持两个变量,一个序列号和一个应答号。在任何给定时刻,在任何主机的序列号是最后包发送的序列号。另外,在任何给定时刻,在任何主机的应答号是下一个预期包的应答号。通过三次握手的分步,初始的序列号和应答号被建立,如下:
    1.在客户端发送SYN包后,
      客户端的 seq#(序列号):P,ack#(应答号):N/A
      服务端的 seq#(序列号):N/A,ack#(应答号):N/A

    2.在服务端接收到SYN包和发送SYN+ACK后,
      客户端的 seq#(序列号):P,ack#(应答号):N/A
      服务端的 seq#(序列号):Q,ack#(应答号):P+1

    3.在客户端接收到SYN+ACK和发送ACK后,
      客户端的 seq#(序列号):P,ack#(应答号):Q+1
      服务端的 seq#(序列号):Q,ack#(应答号):P+1

    4.在服务端接收到ACK后,
      客户端的 seq#(序列号):P,ack#(应答号):Q+1
      服务端的 seq#(序列号):Q,ack#(应答号):P+1

    在三次握手最后的状态必须被我们的方案所复制到,即使两个端点假定为客户的角色。在每个方案的最后,各个端点的应答号必须是大于他们的伙伴的序列号。我们的方案完成这个协调。

5.3 低的TTL值确保
    我们的方案某些是依赖于设置一个TCP包的TTL值,因此包将离开端点的内部网络,但没到达伙伴的NAT。对不同的网络这个值将不同,因此它必须能被动态确定。
    为了确定伙伴距离有多远,一个端点可以使用典型的路由追踪方法。就是,发送从1开始而不断增加的TTL值的SYN包。当TTL失效时各个包将导致ICMP TTL过期包被发回到端点。通过分析返回的ICMP TTL过期包可以为连接中低的TTL值确定一个保险值。
    许多NAT不将ICMP TTL过期包发回内部主机,所以一个端点可以议定当一个ICMP TTL过期包没有被返回时,用一个TTL值来引发一个包离开内部网。
    同样地,在NAT返回ICMP TTL过期包,通过分析伙伴的NAT的消息,端点必须以发现的保险的TTL值为基础。如果伙伴的NAT产生一个RST包,则端点可以使用一个比所产生的RST包小1的TTL值。如果端点没有得到RST包但开始停止接收ICMP TTL过期包,则可以确定伙伴的NAT用了抛弃不请自来的消息而没有响应的保险行为。事实上,这种情况和端点的NAT没有返回ICMP TTL过期包是一样的。
    这个保险TTL值的确定不需要任何其它端点的参与。因此,它可以在保险低的TTL值被用于连接之前就被确定。

5.4 情况1:<可预测的,可预测的,LSR>
A               X               B
|-------1a----->|<------1b------|
|<------2a------|-------2b----->|
|-------2b------|-------------->|
|<--------------|-------3a------|
|-------4a----->|<------4b------|
	    图2:情况1
    我们使用符号“NA:4000→NB:5000,选项/负荷”来表示在英特网上从NA到NB所传送的包内容。这符号意味着包有一个NA的IP源地址,源端口4000,目的地址NB的IP地址,和目的端口5000。此外,在目的端口后是其它的任何重要选项或负荷值。选项包含LSR:X、SYN:P、ACK:Q和SYN+ACK:R,S。LSR:X表明包将可松散源路由到X。SYN:P,ACK:Q表明跟随的序列号或者应答号的TCP包的类型。SYN+ACK:P,Q+1表明包是一个序列号为P和应答号为Q+1的TCP SYN+ACK包。首先我们展示情况1<可预测的,可预测的,LSR>,其中所使用的事件序号在图2中能找得到。
    1.A和B个发送一个可松散源路由的SYN包穿过协助者X到对方
      (a)NA:4000→NB:5000,LSR:X,SYN:P
      (b)NB:5000→NA:4000,LSR:X,SYN:Q
      这两个SYN包由TCP的connect()函数调用产生。SYN在NAT NA和NB上都创建了预期的映射。在NA上的映射将允许后面被转播向A而来自NB:5000的通信并签准。
    2.X缓存两个包并向A和B各自发了对方所用的ISN
      (a)X:1234→NA:3999,B刚用的ISN Q
      (b)X:1235→NB:4999,A刚用的ISN P
      各个端点都需要他们的伙伴的ISN,这样他们才能构造出一个合法的SYN+ACK包。
    3.A和B各向对方发送一个SYN+ACK包
      (a)NB:5000→NA:4000,LSR:X,SYN+ACK:Q,P+1
      (b)NA:4000→NB:5000,LSR:X,SYN+ACK:P,Q+1
      这两个SYN+ACK包是由运行于各个端点的独立线程所产生的。A和B重新使用了原来的序列号P和Q作为在SYN+ACK中的序列号,并保证了所复制的序列号和应答号的最后状态和5.2节讨论的真实的TCP连接一样。
    4.A和B各向对方发送一个ACK包
      (a)NA:4000→NB:5000,LSR:X,ACK:Q+1
      (b)NB:5000→NA:4000,LSR:X,ACK:P+1
      一旦欺骗的SYN+ACK包被接收到,TCP堆栈将自动地为我们做这一步。
    5.X抛弃两个到达的ACK包,因为没有任何一个端点期望接收到这个ACK。

    图2假定了A和B知道他们的伙伴将使用哪个端口来工作;由于各个端点和它的伙伴都必须提前知道对方的信息,所以这一假设是合理的。首先第一步,X必须完成对A和B的端口预测,因此X能预测到NAT设备选择的端口。A必须知道NB工作于5000端口,同时B必须知道NA工作于4000端口。为简单化,可以假定X自己没有在NAT后面,但唯一的假定前提是X必须预先直接连接到A和B。
    情况1存在一种变种的方案。X可以发送在第2和第3步所需的SYN+ACK欺骗包,这似乎好于发送信息到A和B以使他们自己能够伪造SYN+ACK包。我们选择目前的方法是因为如果X发送SYN+ACK欺骗包,他们将被路由器抛弃的总比通过的多。此外,发送从X到A和B的SYN+ACK伪造包需要超级用户权限。而A和B为了其它的目的必须且已经运行于超级用户权限。
    在我们的技术中,从步骤2到5是这样考虑的,我们将申明函数Case1(integer extPortA, integer extPortB)作为执行步骤2到5,把参数extPortA和extPortB各自取代外部端口4000和5000。

5.5 情况2:<可预测的,可预测的,no LSR>
A               X               B
|-------2a----->|<------2b------|
|-------3a----->|<------3b------|
|<------4a------|-------4b----->|
|-------5b------|-------------->|
|<--------------|-------5a------|
|-------6a----->|<------6b------|
	    图3:情况2
    情况1依靠于可用的松散源路由。许多路由器目前设置了预防松散源路由,同时将具有代表性地抛弃请求服务的包。同样地,依靠于松散源路由的技术在实际中将有很高的概率会失败。如果松散源路由不可利用,SYN序列号可以利用一个外出通道(他们预先连接到X的连接)和X通信,而不是物理性地让X看到包。注意图2的步骤2,X知道TCP序列号P和Q,因为X正确地接收到两个SYN包。没了LSR就不是这种情况了。
    为了初始连接,每端主机发送一个初始的SYN包到他们的伙伴,虽然他们知道将不能到达目的地。他们这时嗅探包离开网络,记录序列号,并报告这个信息给X。X需要这些包的TCP序列号,如此它将能够转播这些信息回到A和B,那样他们就能够产生SYN+ACK包。两条路线所发的包都不会到达他们所标明地址的目的地。
    更简单的方案是每个端点各发送一个不被考虑的SYN到他们伙伴。在接收端适当的设置NAT和防火墙,他们将由于没有映射存在而不会向前发送这些包到内部网络主机。一些NAT和一些防火墙将发送TCP重置包(RST)到这个不请自来的包的源地址。如果NAT产生RST包,A和B不能简单的像图2里步骤1的建议一样发送一个SYN包到对方,因为在接受到RST,NA和NB将终止所建立的洞。如果NAT没有产生RST包,打开的TCP连接将不会突然终止。
    另一种确保SYN包将不会到达它的目的网络的方法是发送带有低于伙伴的NAT路径长度的TTL值的SYN包。这包将会在去目的地的路上被明确地抛弃,并且TCP RST包将不会被任何发送者看到。更确切地说,一个ICMP过期包将被看到,并且产生一个问题,因为ICMP过期包突然地终止一个TCP连接。然而,如果使用者能够设置他们本地的防火墙抛弃ICMP包或者如果NAT不会发送ICMP消息包到它的内部网络,TCP连接的尝试将不会突然终止。
    一个方案不能包括简单的欺骗源地址的SYN包,使发送者不会接收到ICMP包或者RST包。这样做会在中间件创建一个残废的映射。中间件在看到一个SYN包时,将创建一个从内部IP地址和端口到外部IP和端口的映射。然而,由于一个欺骗的SYN包有一个错误的源IP地址,映射将不会对应到内部网络的主机。此外,一个方案不能包括把TTL设置低到连中间件都看不到SYN包,因为这样做不会创建我们需要的允许外部后面发到内网的通信的映射。
    假定一个<可预测的,可预测的,no LSR>环境,这种连接就像我们现在在图3所描述的。
    1.X做了关于5.1节描述的端口预测。X预测到NA的下一端口是4000并预测到NB的下一端口是5000,并经由已经存在的连接告知A和B。
    2.A和B各自发送一个SYN包到对方,他们知道这个包将会被对方的NAT抛弃或者由于TTL过期而被抛弃。
      (a)NA:4000→NB:5000,SYN:P
      (b)NB:5000→NA:4000,SYN:Q
      这一点是在各个端点的真实TCP的connect()函数调用所产生的。SYN包由TCP堆栈产生。这在NAT上创建了允许后面的来自伙伴IP地址和端口的通信通过并到达端点的映射。
    3.A和B各自发送他们自己所留意的ISN(P和Q)到X。
      (a)NA:3999→X:1234,刚使用的ISN号P
      (b)NB:4999→X:1235,刚使用的ISN号Q
      各个端点都需要它的伙伴的ISN,如此他们才能够构造合法的SYN+ACK包从而发到他们的伙伴。
    4.X发送A和B的对方各自所留意的ISN到A和B
      (a)X:1234→NA:3999,B刚使用的ISN号Q
      (b)X:1235→NB:4999,A刚使用的ISN号P
    5.A和B各自发送一个SYN+ACK包到对方
      (a)NB:5000→NA:4000,SYN+ACK:Q,P+1
      (b)NA:4000→NB:5000,SYN+ACK:P,Q+1
      这是三次握手的第二部分。此外,A和B重用了他们原来的序列号P和Q作为在SYN+ACK中的序列号,并保证了所复制的序列号和应答号的最后状态和5.2节讨论的真实的TCP连接一样。
    6.A和B各自发送一个ACK包到对方,他们知道这包将会被对方的NAT抛弃或者由于TTL过期而被抛弃。
      (a)NA:4000→NB:5000,ACK:Q+1
      (b)NB:5000→NA:4000,ACK:P+1
      TCP堆栈将自动地为我们发送这些ACK包来完成三次握手。我们不想ACK包到达他们的目的地,由于没有任何一方在等待ACK包。

    作为步骤4到5而和情况1很相似的另一种方法,是X可以欺骗A和B所需的SYN+ACK包。然而,我们为了某些类似在情况1中的原因选择了目前的方法。
    由于步骤2到6在我们的技术中是可重复利用的,所以我们做了函数Case2(integer extPortA, integer extPortB)作为执行步骤2到6,用参数extPortA和extPortB分别替代了外部端口4000和5000。

5.6 情况3:<随机的,可预测的,LSR>
A               X               B
|-------2a----->|               |
|               |-------2b----->|
|               |<------2c------|
|          Case1|(m,5000)       |
	    图4:情况3
    情况3<随机的,可预测的,LSR>类似于图2所描述的情况1。然而,X不能够预测到两个NAT中的一个的端口,比方说NA。A首先不得不发送它的SYN包来允许X查看NA所选的端口。X将报告这一信息给B,因此B能够发送它的SYN包到正确的目标IP地址和端口。这个情况1的修改版在图4中描述并解释如下。
    1.X做了关于5.1节描述的端口预测。X不能预测到NA的下一端口,但能够预测到NB的下一端口是5000,并经由已经存在的连接告知A和B。
    2.A和B同步经由X
      (a)NA:m→NB:5000,LSR:X,SYN:P
      (b)X让B知道NA工作于端口m

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -