Cover V10, I11

Article
Figure 1
Figure 2
Figure 3
Figure 4
Figure 5
Figure 6
Table 1

nov2001.tar

Ethereal

Matt Lesko

Packet sniffers, sometimes referred to as protocol or network analyzers, are invaluable tools for network and systems administrators. With an abundance of commercial and free software products available, it may be difficult to choose a good product. This article describes Ethereal, a free packet sniffer that not only decodes network traffic, but can filter and analyze it, all with an advanced, GTK-based GUI. Additionally, Ethereal can read the data files from a multitude of other packet sniffers, letting you analyze previously collected data. The files can even be compressed with gzip, and Ethereal will read and write to them invisibly.

Installation

Ethereal can be downloaded from the main Web site:

http://www.ethereal.com/download.html
or from any of their mirrors worldwide. The latest version (as of this writing) is 0.8.19. It requires GTK+ 1.2 or greater, which can be downloaded from:

http://www.gtk.org/download/
and the libpcap packet capture library, which can be downloaded from:

http://www.tcpdump.org
Perl is also required to build the included documentation. Additionally, it is recommended that you download and install zlib, available at:

http://www.info-zip.org/pub/infozip/zlib/
so that Ethereal can work with gzipped files on the fly, and NET-SNMP libraries, if you want to enable SNMP support, available at:

http://net_snmp.sourceforge.net/
Pre-compiled binary packages are available for all the major UNIX flavors, as well as for Windows NT. However, the Windows NT version requires more effort to get working and will not be covered here.

Starting It Up

After you have successfully compiled the software (or installed the binary packages available), you can start up the program with the command /usr/local/bin/ethereal &. Change this if you installed Ethereal in a location other than the default. You must be root to execute this program; it will not run otherwise. If you do not want to be root to execute the program, you can set the setuid bit on as root by executing the following command:

# chmod 4755 /usr/local/bin/ethereal & chmod 4755 /usr/local/bin/tethereal
Be aware that this command lets anyone execute the program with root privilege. So, not only can any user capture data on the network, but should any security holes be found in Ethereal, an attacker could gain control through it. Once Ethereal starts up, you will see a standard packet-sniffer GUI with three panes: the top pane, where captured packets are displayed; the middle pane, which contains the protocol tree for the currently selected packet and displays each field and value for the packet; and the bottom pane, which contains a hex dump of the selected packet (Figure 1). There is also a small text-entry box below the bottom pane, with the title "Filter". Filtering will be described later in this article.

Capturing Packets

Now it's time to capture your first packets. To do this, Ethereal must put your Ethernet card into promiscuous mode, which is why it must be executed with root user privileges. Some cards do not support promiscuous mode, but these are extremely rare, so it's safe to assume that your card will work. Before you proceed, make sure you have the system or network administrator's permission. Putting a card into promiscuous mode and capturing traffic on the network may not only set off various intrusion detection systems (IDS), but may cause general discontent to the network administrator. The presence of a sniffer can be a sign that one of the machines in the network has been cracked.

Go to the top menu, select "Capture", then "Start". A new dialog box should appear asking for information (Figure 2). The first entry box asks which interface should be put into promiscuous mode. This is eth0 in my computer, but this may vary from computer to computer. The next entry box is the packet count, which tells Ethereal how many packets to capture before stopping. A value of "0" will capture packets indefinitely, or until the user presses "Stop".

The "Filter" option allows a tcpdump-style capture filter to be used (which will be covered later). The "File" option designates a file to which the data can be saved. This can also be ignored for now. Next, the "Capture Length" option allows the user to select the maximum byte size of each packet to capture. Next is the "Capture packets in promiscuous mode" option, which is turned on by default. If you turn off this option, you will only be able to capture data going directly to and from your computer. The next two options, "Update list of packets in real time" and "Automatic scrolling in live capture" are not necessary if you are saving the capture to a file, but are very useful for watching the network on the fly.

The last three options all deal with name resolution: "Enable MAC name resolution", "Enable network name resolution", and "Enable transport name resolution". These three options can create additional traffic that grows with the amount of data collected, so users that do not want to disturb the network may want to turn these options off. After you have made your selections, press "OK", and the packet capturing begins. A small dialog box will appear with the packet collection statistics, and a "Stop" button appears that you can use to end the capture (Figure 3).

For the first demonstration of Ethereal's power, let's make a connection to a Solaris machine via telnet and see the importance of using secure connections whenever possible. First, we will clean up the captured packets to make it a bit easier to find what we're looking for.

Go down to the "Filter" entry box and type tcp.port == 23, and then press return. The top pane should now display only packets that involved that port. The middle pane displays a very useful breakdown of all the fields for each packet, which can be a great way to examine TCP/IP from the inside.

Now let's use one of the most useful functions of Ethereal -- the ability to follow an entire TCP stream from start to finish. First, in the main frame select a packet that has traveled from the computer to the server of our choosing (in my case, a computer called Nietzsche). Go to "Tools" on the menu, and then select "Follow TCP Stream". The stream shows two lines of control characters followed by the banner for the system. "SunOS 5.7" is displayed, then a prompt for the username, which is "matt". After this is the password prompt, and because telnet sends all of its data in the clear, the password is visible to anyone who happens to be listening on the network. In this case, we can see that the correct password is "trustno1" and the server logs in the user. The user then types "who" (the letters are doubled up because each character is echoed back to the user), and a list of other users is displayed. We can also watch the user type "ls" in his home directory. After this, the user executes a CTRL-D (^D), which logs him out (Figure 4).

To further demonstrate the insecurity of telnet, make the same connection as last time, but this time use a Secure Shell (SSH) client. I recommend OpenSSH (see http://www.openssh.com for more information and downloads). When we attempt to follow the TCP stream in this case, we can read only the first part of the connection protocol, containing both computers' versions of the software (Figure 5). The rest of the channel becomes encrypted, and cannot be sniffed. If this demonstration hasn't convinced you of the need for secure shell access on your machines, then nothing will. This is just a demonstration of the information that can be gathered from watching a network. With a bit of practice, Ethereal can even be used to diagnose network problems (e.g., a server that mistakenly sends out too many ARP requests that eat up precious bandwidth).

Writing Filters

There are two sorts of filters in Ethereal -- display filters and capture filters. The display filters were designed as part of the Ethereal package and, as such, are quite powerful and improving all the time. The capture filters are based on pcap code and use the same syntax as tcpdump.

Display Filters

Because most readers will probably be most familiar with the TCP/IP protocol suite, the information here will pertain to them, but this does not mean that Ethereal does not have support for other networking protocols. The simplest filter is one that simply checks for the presence of a particular protocol. For example, to display only TCP packets, all that would be required for the filter is "tcp". The information can further be broken down by protocol field, but to use these, you must learn to use the comparison operators. Table 1 shows the operators, with the C-style syntax and the English abbreviation-style syntax, as well as a description of their use.

To filter out all packets except those destined to port 80 (http traffic), we could write "tcp.port == 80" or "tcp.port eq 80". When referring to host addresses, either a dotted decimal address or a hostname can be used. The following two examples are the same: "ip.addr == www.sysadminmag.com" and "ip.addr == 66.35.216.85". Additionally, you can subject the filter to allow only those from a certain subnet. To do this, use the Classless InterDomain Routing (CIDR) standard for writing subnets (e.g., "ip.addr == 192.168.0.0./24"). The filters can become really powerful when combined with logical expressions, which, once again, can be expressed in either C-style syntax or English abbreviated syntax:

and && Logical AND

or || Logical OR

xor ^^ Logical XOR

not ! Logical NOT

Furthermore, enclosing them in parentheses can combine the expressions. Thus, the following expression:

(ip.addr == 192.168.0.1 && tcp.port == 80) || (ip.addr != 192.168.0.1 && tcp.port == 443)
can be written in English as: any packet from 192.168.0.1 going to or from port 80 (http), or any packet not from 192.168.0.1 and going to or from port 443 (https). That sums up the basic functionality of display filters. Read the Ethereal manpage for an extensive list of protocols that can be filtered in this manner.

Capture Filters

Capture filters, based upon those of tcpdump, are based upon the notion of primitives. Each primitive has an id, usually a numerical or textual representation of what is being looked for, preceded by a qualifier, which tells the program what the id is referring to.

There are three main categories of qualifier: type, dir, and proto. The first qualifier (type) includes host, net, and port. The host qualifier is true only for traffic to and from that host, so "host mycomputer.mydomain.com" would only print traffic to and from that particular computer. Multiple addresses can be given for a host qualifier and each address will be checked. Next, net operates on a dotted decimal network (e.g., net 192.168 to record all traffic within that network). The final form, port, operates in a similar manner; therefore, port 80 would record all traffic traveling to and from port 80.

The next qualifier, dir, is short for direction, and specifies a direction of traffic from a computer. The possible values are src, dst, src or dst, and src and dst. Thus, to collect only traffic with a destination port of 80, the syntax would be src port 80.

The last form, proto, restricts the filter to one particular form of protocol with possible options of ether, ip, arp, rarp, tcp, udp, and few other more esoteric protocols. Any host expression can be prepended with ip, arp, or rarp to collect only packets with the host in the protocol. To collect only those protocols that fall under the TCP/IP suite, the following syntax is used: ip proto protocol, where protocol is one of the following protocols: icmp, igrp, tcp, udp, or nd.

Unlike the display filters, the capture filters can only use the following keywords for filtering: and, not, and or. These can also be written in the standard C syntax (&&, ||, and !, respectively). Some examples are in order:

net 192.168 -- True for all packets with that as part of the network address.

dst host hostname -- Only data that has hostname as the destination.

src port port -- Only data with a source port of port. This sort of option can be preceded with either tcp or udp in order to differentiate the two. If it's not given, both protocols will return true.

Peering inside the packet is slightly more arcane with the capture filter style, and it is done by the following convention:

proto [ expr : size ]
where proto is a protocol (listed previously), expr is the offset in bytes from the beginning of the packet, and size is an optional argument giving the length of the desired field (it can be either one, two, three, or four bytes, and defaults to one). After this, a mathematical expression is written, followed by another number. Thus, to check an Ethernet packet for multicast, ether[0] & 1 != 0 is used. All of the standard mathematical notations (>, <, >=, <=, =, !=), as well as the binary operators (+, -, *, /, &, |), can be used as the expression. Using this form effectively requires an intimate knowledge of the protocols involved, and it may be more trouble than it is worth.

That's a pretty basic, yet useful summary of the filtering capabilities of Ethereal. It is important to recognize when you are supposed enter a display filter and when you are supposed to enter a capture filter. The capture filter can be entered, or selected from a list, in the "Start Capture" dialog box, and the display filter is entered at the bottom of the main GUI frame and can be entered after a capture. You'll also notice that when using the "Follow TCP Stream" tool that it will automatically filter the data for you.

Tethereal

Ethereal also comes with a command-line version, which can provide the same functionality as the GUI version, but can be easily accessed through a terminal (Figure 6). Tethereal uses the same decoding engine as Ethereal and, as such, accepts the same types of filtering keywords. Tethereal calls display filters "read filters", but other than that, filters are written the same in Tethereal and Ethereal. Here is a list of the most commonly used options:

-w writefile -- Specifies a file for the data to be written to; otherwise, prints it to the screen.

-f expression -- Uses the capture filter-style expression expression for the traffic dump.

-i interface -- Uses the network interface interface.

-n -- Disables network name resolution (i.e., hostname lookups).

-r readfile -- Reads in packet data from file readfile.

-R filter -- Uses the read (or display) filter filter with the program.

-V -- Prints a protocol tree for each packet rather than a summary.

-x -- Prints a hex and ASCII dump following a protocol tree for each packet.

It is also important to remember that when giving filters on the command line, most of the special characters, such as not ('!') and the grouping parentheses, must be escaped from the shell, usually by preceding them with a "\".

Conclusion

With the powerful display and capture filters, an extensible, portable GUI, and a command-line client that provides a similar level of functionality as the GUI, Ethereal is a program that should be in every systems or network administrator's toolbox.

Matt Lesko has worked as a systems administrator supporting Solaris, AIX, Linux, and OpenBSD for the past three years. He can be contacted at: matt@advancedatatools.com.