Saturday, October 20, 2007

Unix socket sniffer

There are a lot of tools for peeking into communication that is performed using the network sockets:
to just name a few.

But I didn't find any program that could perform this treat for the unix sockets. I found only one comment on some mailing list that someone hacked the Linux kernel to perform this (most probably altered the read syscall) but no code whatsoever.

I didn't want to start hacking the kernel as my only experience with it was compiling it during short time when I run Gentoo on my desktop. Then it occurred to me: Why not use the chroot?

Idea is quite simple. A Server and a client communicate via the unix socket, which is a named socket and is located somewhere in the file system. We run the server in standard way. For the client we create a chroot environment. We run the client in the chroot jail. Our sniffer program connects two sockets: the standard one with the one in chroot jail. While transferring the traffic it can dump it into a log file :-D.

So I wrote an app that performs this: SockSniffer ;-).
In the packet there are four files:
  • socksniff - the sniffer, it will output the log files into $PWD/dumps directory.
  • sockmerge - this program will merge log files in $PWD/dumps directory and output it in libpcap format which is readable for wireshark.
  • and - client and server scripts to test the sniffer.
All those scripts are written in Perl. Output of socksniff are hex dumps of the traffic. One file per "packet". To use the sockmerge script wireshark (or ethereal) needs to be installed.

In coming days I will post a guide how to sniff traffic generated by the GoogleDesktop for Linux.


Friedrich Lobenstock said...

# ./socksniff sock1 sock2
# mount -o bind sock2 sock1

no need for chroot ;-)

graag said...

I'll have to test it as it would be much easier then the chroot. At the moment I do not see how this could work :(.

The idea with chroot was the following:
- Client and server communicate through a predefined socket - no way to change it on client or server side.
- I do not know about any way that would enable socksniff to read the socket and leave the contents in so that the client would still be able to read it (same with clients response and server reading)
- Hence chroot
* Client and Server communicate with predefined socket but this time the sockets are separate
* This allows to put the socksniff in the middle to transfer the traffic between the sockets and output it to a file.

I do not see how mount -o bind would accomplish this but I'll give it a try.

Anonymous said...

uhm to read i/o of unix socket i'm using strace :

strace -e trace=read,write -e read=29,30 -e write=29,30 -p 12343

i'm reading i/o of unix socket created by processes 12343. The information of filedescriptor opened for the unix socket (29,30) are obtained from lsof. My hint is that instead doing a proxy/chroot you could use ptrace() call.

hjb said...

Hi :-)

I've had the same problem: trying to see what two processed were talking over a filesystem socket. I've googled a lot for stuff like "unix socket sniff" and stuff (actually this is how i found your page ;-)).

After talking to someone bright at my workplace, i've figured that i headed into the wrong direction :-). The answer to the problem is: tracing!

Under solaris, it's totally easy to trace what's going over a socket:

"truss -rall -wall -p PID"

You have to run that for both processes. You'll get all data that goes over the socket.

I'm quite sure that strace under linux provides the same functionality.

conrad said...

Thanks for the info about strace.

This didn't show up when I did google around for a solution before I wrote the script. For sure this should be easier to use ...

Anonymous said...

Just use netcat: nc -U /path/to/unixsocket

Erik said...

When running windows I find proxocket to be a really neat way to sniff traffic to/from Winsock. Proxocket isn't an application, just a DLL that can be placed in the same directory as the .exe that you wanna monitor: