Recipe 9.19 Detecting Insecure Network Protocols

9.19.1 Problem

You want to determine if insecure protocols are being used on the network.

9.19.2 Solution

Use dsniff.

To monitor the network for insecure protocols:

# dsniff -m [-i interface] [-s snap-length] [filter-expression]

To save results in a database, instead of printing them:

# dsniff -w gotcha.db [other options...]

To read and print the results from the database:

$ dsniff -r gotcha.db

To capture mail messages from SMTP or POP traffic:

# mailsnarf [-i interface] [-v] [regular-expression [filter-expression]]

To capture file contents from NFS traffic:

# filesnarf [-i interface] [-v] [regular-expression [filter-expression]]

To capture URLs from HTTP traffic:

# urlsnarf  [-i interface] [-v] [regular-expression [filter-expression]]

ngrep is also useful for detecting insecure network protocols. [Recipe 9.18]

9.19.3 Discussion

dsniff is not supplied with Red Hat or SuSE, but installation is straightforward. A few extra steps are required for two prerequisite libraries, libnet and libnids, not distributed by Red Hat. SuSE provides these libraries, so you can skip ahead to the installation of dsniff itself on such systems.

If you need the libraries, first download libnet, a toolkit for network packet manipulation, from, and unpack it:

$ tar xvzpf libnet-1.0.*.tar.gz

Then compile it:[10]

[10] At press time, dsniff 2.3 (the latest stable version) cannot be built with the most recent version of libnet. Be sure to use the older libnet 1.0.2a with dsniff 2.3.

$ cd Libnet-1.0.*
$ ./configure --prefix=/usr/local
$ make

and install it as root:

# make install

We explicitly configure to install in /usr/local (instead of /usr), to match the default location for our later configuration steps. Next, download libnids , which is used for TCP stream reassembly, from, and unpack it:

$ tar xvzpf libnids-*.tar.gz

Then compile it:

$ cd `ls -d libnids-* | head -1`
$ ./configure
$ make

and install it as root:

# make install

dsniff also requires the Berkeley database library, which is provided by both Red Hat and SuSE. Unfortunately, some systems such as Red Hat 7.0 are missing /usr/include/db_185.h (either a plain file or a symbolic link) that dsniff needs. This is easy to fix:

# cd /usr/include
# test -L db.h -a ! -e db_185.h \
    && ln -sv `readlink db.h | sed -e 's,/db,&_185,'` .

Your link should look like this:

$ ls -l db_185.h
lrwxrwxrwx    1 root root 12 Feb 14 14:56 db_185.h -> db4/db_185.h

It's OK if the link points to a different version (e.g., db3 instead of db4).

Finally, download dsniff from, and unpack it:

$ tar xvzpf dsniff-*.tar.gz

Then compile it:

$ cd `ls -d dsniff-* | head -1`
$ ./configure
$ make

and install it as root:

# make install

Whew! With all of the software in place, we can start using dsniff to audit the use of insecure network protocols:

# dsniff -m
dsniff: listening on eth0
03/01/03 20:11:07 tcp -> (ftp)
USER katie
PASS Dumbo!
03/01/03 20:11:23 tcp -> (telnet)
ls -l
03/01/03 20:14:56 tcp -> (rlogin)
rm junque
03/01/03 20:16:33 tcp -> (x11)
MIT-MAGIC-COOKIE-1 c166a754fdf243c0f93e9fecb54abbd8
03/01/03 20:08:20 udp -> (mountd)
/home [07 04 00 00 01 00 00 00 0c 00 00 00 02 00 00 00 3b 11 a1 36 00 00 00 00 00 00 
00 00 00 00 00 00 ]

dsniff understands a wide range of protocols, and recognizes sensitive data that is transmitted without encryption. Our example shows passwords captured from FTP and Telnet sessions, with telnet commands and other input. (See why typing the root password over a Telnet connection is a very bad idea?) The rlogin session used no password, because the source host was trusted, but the command was captured. Finally, we see authorization information used by an X server, and filehandle information returned for an NFS mount operation.

dsniff uses libnids to reassemble TCP streams, because individual characters for interactively-typed passwords are often transmitted in separate packets. This reassembly relies on observation of the initial three-way handshake that starts all TCP sessions, so dsniff does not trace sessions already in progress when it was invoked.

The dsniff -m option enables automatic pattern-matching of protocols used on nonstandard ports (e.g., HTTP on a port other than 80). Use the -i option to listen on a specific interface, if your system is connected to multiple networks. Append a filter-expression to restrict the network traffic that is monitored, using the same syntax as tcpdump. [Recipe 9.16] dsniff uses libpcap to examine the first kilobyte of each packet: use the -s option to adjust the size of the snapshot if necessary.

dsniff can save the results in a database file specified by the -w option; the -r option reads and prints the results. If you use a database, be sure to protect this sensitive data from unwanted viewers. Unfortunately, dsniff cannot read or write libpcap-format network trace files?it performs live network-monitoring only.

A variety of more specialized sniffing tools are also provided with dsniff. The mailsnarf command captures mail messages from SMTP or POP traffic, and writes them in the standard mailbox format:

# mailsnarf
mailsnarf: listening on eth0
From Sat Mar  1 21:00:02 2003
Received: (from
        by (8.11.6/8.11.6) id h1DJAPe10352
        for; Sat, 1 Mar 2003 21:00:02 -0500
Date: Sat, 1 Mar 2003 21:00:02 -0500
From: Engelbert Humperdinck <>
Message-Id: <>
Subject: Elvis lives!

I ran into Elvis on the subway yesterday.
He said he was on his way to Graceland.

Suppose you want to encourage users who are sending email as clear text to encrypt their messages with GnuPG (see Chapter 8). You could theoretically inspect every email message, but of course this would be a gross violation of their privacy. You just want to detect whether encryption was used in each message, and to identify the correspondents if it was not. One approach is:

# mailsnarf -v "-----BEGIN PGP MESSAGE-----" | \
  perl -ne 'print if /^From / .. /^$/;' | \
  tee insecure-mail-headers

Our regular expression identifies encrypted messages, and the mailsnarf -v option (similar to grep -v) captures only those messages that were not encrypted. A short Perl script then discards the message bodies and records only the mail headers. The tee command prints the headers to the standard output so we can watch, and also writes them to a file, which can be used later to send mass mailings to the offenders. This strategy never saves your users' sensitive email data in a file.

dsniff comes with similar programs for other protocols, but they are useful mostly as convincing demonstrations of the importance of secure protocols. We hope you are already convinced by now!

The filesnarf command captures files from NFS traffic, and saves them in the current directory:

# filesnarf
filesnarf: listening on eth0
filesnarf: > known_hosts (1303@0)
filesnarf: > love-letter.doc (8192@0)
filesnarf: > love-letter.doc (4096@8192)
filesnarf: > .Xauthority (204@0)
filesnarf: > myprog (8192@0)
filesnarf: > myprog (8192@8192)
filesnarf: > myprog (8192@16384)
filesnarf: > myprog (8192@40960)

The last values on each line are the number of bytes transferred, and the file offsets. Of course, you can capture only those parts of the file transmitted on the network, so the saved files can have "holes" (which read as null bytes) where the missing data would be. No directory information is recorded. You can select specific filenames using a regular expression (and optionally with the -v option, to invert the sense of the match, as for mailsnarf or grep).

The urlsnarf command captures URLs from HTTP traffic, and records them in the Common Log Format (CLF). This format is used by most web servers, such as Apache, and is parsed by many web log analysis programs.

# urlsnarf
urlsnarf: listening on eth1 [tcp port 80 or port 8080 or port 3128] - - [ 1/Mar/2003:21:06:36 -0500] "GET
cgi-bin/counter?ft=0|dd=E|trgb=ffffff|df=dugsong-dsniff.dat HTTP/1.1" - - "http://" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.
9) Gecko/20020513" - - [ 1/Mar/2003:21:06:46 -0500] "GET
~dugsong/dsniff/faq.html HTTP/1.1" - - "" 
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.9) Gecko/20020513"

By default, urlsnarf watches three ports that commonly carry HTTP traffic: 80, 3128, and 8080. To monitor a different port, use a capture filter expression:

# urlsnarf tcp port 8888
urlsnarf: listening on eth1 [tcp port 8888]

To monitor all TCP ports, use a more general expression:

# urlsnarf -i eth1 tcp
urlsnarf: listening on eth1 [tcp]

A regular expression can be supplied to select URLs of interest, optionally with -v as for mailsnarf or filesnarf.

A few other programs are provided with dsniff as a proof of concept for attacks on switched networks, man-in-the-middle attacks, and slowing or killing TCP connections. Some of these programs can be quite disruptive, especially if used incorrectly, so we don't recommend trying them unless you have an experimental network to conduct penetration testing.

9.19.4 See Also

dsniff(8), mailsnarf(8), filesnarf(8), urlsnarf(8). The dsniff home page is

    Chapter 9. Testing and Monitoring