Write inside a socket open by another process in Linux

10,317

Solution 1

This isn't possible because it would be difficult to implement and rarely useful. Sockets are a lot more complex than pipes:

  • Sockets are bidirectional.
  • There are different types of sockets. Some sockets aren't streams of bytes (e.g. UDP sockets are datagram sockets, which send packets and not bytes).
  • Sockets perform multiplexing (and there's some overloading between sockets used by servers waiting for connections and sockets used by actual opened connections).

Because sockets are bidirectional, they are often used to communicate under bidirectional protocols. If you inject data into the conversation, the other side might send a response to your data, and there is no way to dispatch the response to the right requester. This considerably reduces the usefulness of allowing data injection on sockets.

If you're trying to contact the same server as an existing client and not tack onto an existing conversation, there is already a way to do that: contact the server in the same way (open a socket on the filesystem, or to a TCP or UDP port). If the socket is a nameless one between two processes, that's a good hint that you aren't supposed to join in, so the operating system doesn't make it easy.

With a datagram socket (not the case here), you couldn't directly inject data because the shell only understands streams of bytes, it doesn't know to call send instead of write to send a packet.

If you have the cooperation of one endpoint, you can tell make use file descriptor passing 1 2 3.

Otherwise, you can make the process that has the socket open send the data itself, with ptrace (that's what gdb uses under the hood). This suspends the process, very much by design, so that your dirty tricks don't confuse the process too much. Even with the process suspended, you run a major risk of making the process's data structures inconsistent with the reality of the data or environment modifications that you've injected. (Note that even if the system allowed injecting data over a socket, there would be a similar, if lesser, risk of confusing the process with these inconsistencies.)

Solution 2

I'd say it is possible, but both processes need to cooperate to do this. You can have one process send a file descriptor over a socket connection to another process. I found this example, which seems to work on an up-to-date Arch linux machine.

Share:
10,317

Related videos on Youtube

otaku22
Author by

otaku22

Updated on September 18, 2022

Comments

  • otaku22
    otaku22 over 1 year

    Is it possible on Linux for a process to write inside a socket open by another one?

    Let's say I open a connection to google.com using netcat:

    myuser@linux:~$ nc google.com 80
    

    Now I can lookup for the process pid and open its file descriptor folder:

    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]
    

    So now I would like to make the HTTP request using an echo inside that socket:

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

    Doing it as root doesn't change the result.

    I can't write inside the socket but I can write inside the stdin:

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

    But it's not what I want to do.

    I was thinking: a Linux socket should be treated like a file, isn't it? One or more processes can use the same socket, so why can't I do this?

    • Admin
      Admin about 12 years
      It doesnt look like it is possible. First this is a socket, not a fifo, so you cant just echo to it like a normal file. nc can do this, but trying to do so results in "Transport endpoint is not connected". Example command nc -v --send-only -U /proc/123/fd/3 <<< 'GET /'$'\n\n'
    • Admin
      Admin about 12 years
      what? Why should I use the -U (Unix socket) option? By the way I can't understand how it can be useful
    • Admin
      Admin about 12 years
      I found a bad workaround using gdb: gdb -p 24285 and then I can write inside the file descriptor using call write(3, "test",4). It works, but I would like to do the same thing from the procfile because the use of gdb requires to stop the process (so rises the risk of crashes or other bad things)
  • otaku22
    otaku22 about 12 years
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' about 12 years
    @otaku22 Leading to In theory you can't get an open on this inode, but /proc provides a back door. Remember to keep it shut otherwise you'll let the creepy crawlies in. My answer aims to show what these creepy crawlies are, I don't know if there's a more official or more complete presentation elsewhere.