如何通过袜子发送TCP数据包?

Posted

技术标签:

【中文标题】如何通过袜子发送TCP数据包?【英文标题】:How to send TCP packets through socks? 【发布时间】:2020-04-13 00:30:55 【问题描述】:

我有这个代码:

import socket
import socks

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, "IP_SOCK", PORT_SOCK, True)
s = socks.socksocket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target,port))
s.close()
print("Connection tested.")

它可以工作,但是数据包的长度为 0。我想添加一个有效负载数据,我该怎么做?

例如,这里我有这个带有 scapy 库的工作代码:

import socket
import socks
from scapy.all import *


def send(src_ip, dst_ip, dst_port):
    ip = IP(src=src_ip, dst=dst_ip)
    src_port = random.randint(20, 65000)
    transport = TCP(sport=src_port, dport=dst_port, flags="S")
    send(ip/transport/b"mydata")


if __name__ == '__main__':
    send('SRC_IP', 'DST_IP', DST_PORT)

它确实发送了“mydata”有效负载。如果我用 tcpdump 拦截它,我可以在 syn 数据包中看到数据字段的长度和“mydata”。

我想通过 sock 或 http 代理发送它,但我不知道该怎么做。

事实是我不需要建立连接,因为即使端口关闭我也想发送数据包。

有人继续告诉我,我不能用socks发送tcp数据包。这不是真的。 SOCKS 在第 4 层起作用,所以它是完全可行的,问题是我不知道如何在 Python 中做到这一点,因为我是新手。

【问题讨论】:

您是否考虑过“继续告诉”您不能通过袜子发送原始 tcp 数据包的人可能是对的? Here 是相关规范。 SOCKS 不在第 4 层中起作用。它是一种应用协议。 【参考方案1】:

有人继续告诉我,我不能用socks发送tcp数据包。这不是真的。

这是真的,即使你不喜欢它。代理(HTTP 代理或 Socks 代理)不是网络级别的数据包转发器。相反,它是应用程序级别的有效负载转发器。如果你想要一个数据包转发器,你需要一个真正的 ***(重点是“N”,即网络级别)。

使用 Socks 或 HTTP 代理时,需要先建立到代理的 TCP 连接。然后在这个 TCP 连接中进行一些初始握手,例如针对代理的身份验证和希望达到的目标规范。然后代理连接到目标,一旦完成,就会有两个 TCP 连接:一个在客户端和代理之间,另一个在代理和服务器之间。然后代理将读取这两个连接并将接收到的数据转发给对等方,即从客户端接收到的数据将被转发到服务器等。代理还可能会修改传输中的数据。

由于代理仅在应用程序级别转发数据,因此无法通过代理发送精心设计的 TCP 数据包。而且由于代理维护两个独立的 TCP 连接并且只转发应用程序级别的数据,即使传入和传出的数据包大小可能不同,即两个传入的数据包可以合并到一个传出数据包中,或者可能导致三个等。因为 TCP 只是字节流数据包大小在应用程序级别并不重要。

【讨论】:

【参考方案2】:

你可以使用sendall();例如:s.sendall("GET / HTTP/1.1 ...")

有关更多详细信息,请参阅 https://pypi.org/project/PySocks/ ,我从中获得了此示例,以及 https://docs.python.org/3/library/socket.htmlsocks 模仿 python 的内置 sockets)

【讨论】:

即使端口关闭也不发送数据包。

以上是关于如何通过袜子发送TCP数据包?的主要内容,如果未能解决你的问题,请参考以下文章

tcp是啥意思网络用语

TCP协议原理

TCP粘包与拆包之一

试图理解我通过 TCP 连接发送/接收的 UART 数据包

centostcp不发送

如何在主机将其发送到网络之前修改数据包标头(IP标头,TCP标头)