发送带有负载的 TCP SYN 数据包
Send TCP SYN packet with payload
是否可以在发起TCP连接时发送一个带有自定义payload的SYN包?我的直觉是理论上是可行的。我正在寻找一种在 Linux 中实现此目标的简单方法(使用 C 或 Go 语言),但因为它不是标准行为,所以我还没有找到有用的信息。 (This post 非常相似,但不是很有帮助。)
请帮帮我,谢谢!
编辑:很抱歉含糊不清。不仅是这样的任务的可能性,我也在寻找一种方法,甚至是示例代码来实现它。
显然,如果您在两边都编写自己的软件,则可以让它按您想要的方式工作。但是如果你在任何一端都依赖标准软件(例如,标准 linux 或 Windows 内核),那么不,这是不可能的,因为根据 TCP,你不能在建立会话之前发送数据,并且在您从其他对等方收到 确认 到您的 SYN
之前不会建立会话。
因此,例如,如果您向 linux 内核发送一个还包含额外负载的 SYN
数据包(警告:这在某种程度上是推测,因为我还没有实际尝试过),它将简单地忽略有效负载并继续确认 (SYN/ACK
) 或拒绝 (使用 RST
) SYN
,具体取决于是否有侦听器。
在任何情况下,您都可以尝试这个,但是既然您要去 "off the reservation" 可以这么说,您将需要制作自己的原始数据包;您将无法说服当地 OS 为您创建它们。
pythonscapy
包可以构造它:
#!/usr/bin/env python2
from scapy.all import *
sport = 3377
dport = 2222
src = "192.168.40.2"
dst = "192.168.40.135"
ether = Ether(type=0x800, dst="00:0c:29:60:57:04", src="00:0c:29:78:b0:ff")
ip = IP(src=src, dst=dst)
SYN = TCP(sport=sport, dport=dport, flags='S', seq=1000)
xsyn = ether / ip / SYN / "Some Data"
packet = xsyn.build()
print(repr(packet))
我之前说过这是不可能的。总的来说,我支持这个评价。
但是对于客户端来说,使用connect()
API其实是不行的。使用 TCP Fast Open 时有一个替代连接 API。 Example:
sfd = socket(AF_INET, SOCK_STREAM, 0);
sendto(sfd, data, data_len, MSG_FASTOPEN,
(struct sockaddr *) &server_addr, addr_len);
// Replaces connect() + send()/write()
// read and write further data on connected socket sfd
close(sfd);
没有API允许服务器将数据附加到发送给客户端的SYN-ACK。
即便如此,在客户端和服务器上启用 TCP Fast Open 可能会让您获得想要的结果,如果您只是指来自客户端的数据,但它有自己的 issues.
如果您想要与 TCP 相同的可靠性和数据流语义,您将需要一个新的可靠协议,除了 TCP 提供的其余部分(例如拥塞控制和 window缩放。
幸运的是,您不必从头开始实施它。 UDP 协议是一个很好的起点,可以作为新 L4 的 L3。
其他项目也做了类似的事情,所以可以使用它们而不是实现你自己的。考虑 QUIC or UDT。这些协议是在现有的 UDP 协议上实现的,因此避免了部署 TCP Fast Open 所面临的问题。
据我了解(以及 Jeff Bencteux 在另一个答案中的评论中所写),TCP Fast Open 针对 TCP 解决了这个问题。
Eliminating a round trip
Theoretically, the initial SYN segment could contain data sent by the initiator of the connection: RFC 793, the specification for TCP, does permit data to be included in a SYN segment. However, TCP is prohibited from delivering that data to the application until the three-way handshake completes.
...
The aim of TFO is to eliminate one round trip time from a TCP conversation by allowing data to be included as part of the SYN segment that initiates the connection.
TCP 快速开放做到这一点。但是两端都要讲TCP快开。 QUIC 一个基于 AKA 0-RTT 的新协议来解决这个问题。
是否可以在发起TCP连接时发送一个带有自定义payload的SYN包?我的直觉是理论上是可行的。我正在寻找一种在 Linux 中实现此目标的简单方法(使用 C 或 Go 语言),但因为它不是标准行为,所以我还没有找到有用的信息。 (This post 非常相似,但不是很有帮助。)
请帮帮我,谢谢!
编辑:很抱歉含糊不清。不仅是这样的任务的可能性,我也在寻找一种方法,甚至是示例代码来实现它。
显然,如果您在两边都编写自己的软件,则可以让它按您想要的方式工作。但是如果你在任何一端都依赖标准软件(例如,标准 linux 或 Windows 内核),那么不,这是不可能的,因为根据 TCP,你不能在建立会话之前发送数据,并且在您从其他对等方收到 确认 到您的 SYN
之前不会建立会话。
因此,例如,如果您向 linux 内核发送一个还包含额外负载的 SYN
数据包(警告:这在某种程度上是推测,因为我还没有实际尝试过),它将简单地忽略有效负载并继续确认 (SYN/ACK
) 或拒绝 (使用 RST
) SYN
,具体取决于是否有侦听器。
在任何情况下,您都可以尝试这个,但是既然您要去 "off the reservation" 可以这么说,您将需要制作自己的原始数据包;您将无法说服当地 OS 为您创建它们。
pythonscapy
包可以构造它:
#!/usr/bin/env python2
from scapy.all import *
sport = 3377
dport = 2222
src = "192.168.40.2"
dst = "192.168.40.135"
ether = Ether(type=0x800, dst="00:0c:29:60:57:04", src="00:0c:29:78:b0:ff")
ip = IP(src=src, dst=dst)
SYN = TCP(sport=sport, dport=dport, flags='S', seq=1000)
xsyn = ether / ip / SYN / "Some Data"
packet = xsyn.build()
print(repr(packet))
我之前说过这是不可能的。总的来说,我支持这个评价。
但是对于客户端来说,使用connect()
API其实是不行的。使用 TCP Fast Open 时有一个替代连接 API。 Example:
sfd = socket(AF_INET, SOCK_STREAM, 0);
sendto(sfd, data, data_len, MSG_FASTOPEN,
(struct sockaddr *) &server_addr, addr_len);
// Replaces connect() + send()/write()
// read and write further data on connected socket sfd
close(sfd);
没有API允许服务器将数据附加到发送给客户端的SYN-ACK。
即便如此,在客户端和服务器上启用 TCP Fast Open 可能会让您获得想要的结果,如果您只是指来自客户端的数据,但它有自己的 issues.
如果您想要与 TCP 相同的可靠性和数据流语义,您将需要一个新的可靠协议,除了 TCP 提供的其余部分(例如拥塞控制和 window缩放。
幸运的是,您不必从头开始实施它。 UDP 协议是一个很好的起点,可以作为新 L4 的 L3。
其他项目也做了类似的事情,所以可以使用它们而不是实现你自己的。考虑 QUIC or UDT。这些协议是在现有的 UDP 协议上实现的,因此避免了部署 TCP Fast Open 所面临的问题。
据我了解(以及 Jeff Bencteux 在另一个答案中的评论中所写),TCP Fast Open 针对 TCP 解决了这个问题。
Eliminating a round trip
Theoretically, the initial SYN segment could contain data sent by the initiator of the connection: RFC 793, the specification for TCP, does permit data to be included in a SYN segment. However, TCP is prohibited from delivering that data to the application until the three-way handshake completes.
...
The aim of TFO is to eliminate one round trip time from a TCP conversation by allowing data to be included as part of the SYN segment that initiates the connection.
TCP 快速开放做到这一点。但是两端都要讲TCP快开。 QUIC 一个基于 AKA 0-RTT 的新协议来解决这个问题。