在 Linux 中另一个进程打开的套接字内写入

在 Linux 中另一个进程打开的套接字内写入

在 Linux 上,一个进程是否可以在另一个进程打开的套接字内写入数据?

假设我使用 netcat 打开与 google.com 的连接:

myuser@linux:~$ nc google.com 80

现在我可以查找进程 pid 并打开其文件描述符文件夹:

myuser@linux:~$ ls -la /proc/24105/fd
totale 0
dr-x------ 2 myuser myuser  0 2012-03-10 19:01 .
dr-xr-xr-x 7 myuser myuser  0 2012-03-10 19:01 ..
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 0 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 1 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:01 2 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 3 -> socket:[3947162]

现在我想使用该套接字内的 echo 来发出 HTTP 请求:

myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/3
bash: /proc/24285/fd/3: no such device or address

以 root 身份执行此操作不会改变结果。

我无法在套接字内写入,但可以在标准输入内写入:

myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/0
myuser@linux:~$

但这不是我想做的。

我在想:Linux 套接字应该像文件一样对待,不是吗?一个或多个进程可以使用同一个套接字,那么为什么我不能这样做呢?

答案1

这是不可能的,因为它很难实现并且很少有用。套接字比管道复杂得多:

  • 套接字是双向的。
  • 有不同类型的插座。有些套接字不是字节流(例如,UDP 套接字是数据报套接字,它发送数据包而不是字节)。
  • 套接字执行多路复用(等待连接的服务器使用的套接字和实际打开的连接使用的套接字之间存在一些过载)。

由于套接字是双向的,因此它们通常用于在双向协议下进行通信。如果您将数据注入对话中,另一方可能会发送对您的数据的响应,并且无法将响应分派给正确的请求者。这大大降低了允许在套接字上注入数据的实用性。

如果您尝试与现有客户端联系同一服务器而不是附加到现有对话,那么已经有一种方法可以做到这一点:以相同的方式联系服务器(在文件系统上打开一个套接字,或者打开一个 TCP或 UDP 端口)。如果套接字是两个进程之间的无名套接字,则这是一个很好的暗示,表明您不应该加入,因此操作系统不会让这变得容易。

使用数据报套接字(不是这里的情况),您无法直接注入数据,因为 shell 只理解字节流,它不知道调用send而不是write发送数据包。

如果你有一个端点的配合,你可以告诉 make use 文件描述符传递1 2 3

否则,您可以使打开套接字的进程本身发送数据ptrace(这就是gdb幕后使用的内容)。这很大程度上是有意设计的,会暂停进程,这样你的肮脏伎俩就不会太混乱进程。即使进程暂停,您也面临着使进程的数据结构与您注入的数据或环境修改的实际情况不一致的重大风险。 (请注意,即使系统允许通过套接字注入数据,也会存在类似的风险,即使较小,也会因这些不一致而使进程混淆。)

答案2

我想说这是可能的,但是两个进程需要合作才能做到这一点。您可以让一个进程通过套接字连接向另一进程发送文件描述符。我发现这个例子,这似乎可以在最新的 Arch Linux 机器上运行。

相关内容