ota*_*u22 10 linux process io socket
在 Linux 上,一个进程是否可以在另一个打开的套接字中写入?
假设我使用 netcat 打开与 google.com 的连接:
myuser@linux:~$ nc google.com 80
Run Code Online (Sandbox Code Playgroud)
现在我可以查找进程 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]
Run Code Online (Sandbox Code Playgroud)
所以现在我想使用该套接字内的回声发出 HTTP 请求:
myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/3
bash: /proc/24285/fd/3: no such device or address
Run Code Online (Sandbox Code Playgroud)
以 root 身份执行它不会改变结果。
我不能在套接字里面写,但我可以在标准输入里面写:
myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/0
myuser@linux:~$
Run Code Online (Sandbox Code Playgroud)
但这不是我想做的。
我在想:Linux 套接字应该被视为文件,不是吗?一个或多个进程可以使用同一个套接字,为什么我不能这样做呢?
这是不可能的,因为它很难实现并且很少有用。套接字比管道复杂得多:
由于套接字是双向的,因此它们通常用于在双向协议下进行通信。如果您将数据注入对话,另一方可能会向您的数据发送响应,并且无法将响应分派给正确的请求者。这大大降低了允许在套接字上注入数据的有用性。
如果您尝试联系与现有客户端相同的服务器,而不是加入现有对话,那么已经有一种方法可以做到这一点:以相同的方式联系服务器(打开文件系统上的套接字,或连接到 TCP或 UDP 端口)。如果套接字是两个进程之间的无名套接字,这是一个很好的提示,表明您不应该加入,因此操作系统并不容易。
使用数据报套接字(这里不是这种情况),您不能直接注入数据,因为 shell 只理解字节流,它不知道调用send
而不是write
发送数据包。
如果你有一个端点的配合,你可以告诉 make use 文件描述符传递1 2 3。
否则,您可以让打开套接字的进程发送数据本身,使用ptrace
(这是gdb
在幕后使用的)。这在很大程度上是设计使流程暂停,因此您的肮脏技巧不会过多地混淆流程。即使流程暂停,您也会面临使流程的数据结构与您注入的数据或环境修改的现实不一致的重大风险。(请注意,即使系统允许通过套接字注入数据,也会有类似的风险,即使是较小的,将过程与这些不一致混淆。)