Security

Use tcpdump for traffic analysis

The tcpdump tool is powerful and flexible, but compared with graphical tools like Wireshark its effective use may appear to be a dark art. It really isn't that difficult to use once you pick up the basics, though.
The tcpdump tool is an old mainstay of network debugging and security monitoring, and security experts all over the world swear by its usefulness. It is a command line tool that eschews all the makeup and jewelry of other traffic analysis tools such as Ettercap and Wireshark, both of which provide packet sniffing functionality with a convenient captive interface. In contrast to such tools, tcpdump takes a command at the shell, with options specified at that time, and dumps the results to standard output. This may seem primitive to some users, but it provides power and flexibility that isn't available with the common captive interface alternatives.

Options

The tcpdump utility provides dozens of options, but I'll just cover a few of them here:

  • -A: Print each packet in ASCII.
  • -c N: Where the letter N is a number, this option tells tcpdump to exit after N packets.
  • -i interface: Capture packets on the specified network interface.
  • -n: Don't resolve addresses to names.
  • -q: Provide less verbose ("quiet") output so output lines are shorter.
  • -r filename: Read packets from the specified file rather than a network interface. This is usually used after raw packets have been logged to a file with the -w option.
  • -t: Don't print a timestamp on each line of output.
  • -v: Provide more verbose output. Verbosity can be increased more with -vv, and even more than that with -vvv.
  • -w filename: Write raw packets to the specified file.

Expressions

The tcpdump utility also supports command-line expressions, used to define filtering rules so that you get exactly the traffic you want to see, ignoring "uninteresting" packets. Expressions consist of a number of primitives and, optionally, modifier terms. The following primitives and modifiers do not constitute a comprehensive list, but they are among the most commonly useful.

Primitives

  • dst foo: Specify an address or hostname to limit captured packets to traffic sent to a particular host.
  • host foo: Specify an address or hostname to limit captured packets to traffic to and from a particular host.
  • net foo: Specify a network or network segment using CIDR notation to limit packet capture.
  • proto foo: Specify a protocol to limit captured packets to network traffic using that protocol.
  • src foo: Specify an address or hostname to limit captured packets to traffic sent by a particular host.

Modifiers

  • and: Use this to chain together primitives when you want to limit captured packets to those that meet the requirements of the expressions on both sides of the and.
  • not: Use this modifier just before a primitive when you want to limit captured packets to those that do not meet the requirements of the following expresssion.
  • or: Use this to chain together primitives when you want to limit captured packets to those that meet the requirements of one or more of the expressions on either side of the or.

Examples

All of these options and expression primitives and modifiers, along with others listed in the tcpdump manpage, can be used to construct very specific commands that produce very precise output.

  • tcpdump -c 50 dst foo can give you information that may help identify the source of heavy incoming traffic targeting an overloaded server with hostname "foo", dumping the first 50 packets as output.
  • tcpdump -c 500 -w `date +"%Y%j%T"`.log dumps 500 packets to a file named with a current time/date stamp (e.g. 200820715:16:31.log) so that they can later be filtered according to the information you want to see. I have the command date +"%Y %j%T" aliased to stamp in my shell's rc file, so I can shorten a command like this to tcpdump -c 500 -w `stamp`.log, saving me from having to remember all the formatting options for the date command off the top of my head.
  • tcpdump port 22 src or dst foo and src and dst not bar produces ongoing output that shows all port 22 (presumably SSH protocol) activity originating from or targeting host "foo" unless it is originating from or targeting host "bar". If foo is only supposed to be accessed via SSH by bar, this command will allow ongoing monitoring of unauthorized SSH traffic to and from foo. You could even start a number of persistent monitoring processes with tcpdump like this within a tmux session on a dedicated monitoring server.

As you can no doubt see, tcpdump's expressions capabilities are roughly equivalent to a simple domain specific programming language that is extremely easy to understand. With that kind of power and flexibility at my fingertips, there's little need to use anything else for general traffic analysis tasks.

About

Chad Perrin is an IT consultant, developer, and freelance professional writer. He holds both Microsoft and CompTIA certifications and is a graduate of two IT industry trade schools.

19 comments
oparker
oparker

A couple CL examples I use daily are as follows. There are unendable examples of options, but these few will need to be in anyone's arsenal trying to figure out why someone can't get connected, or can't access something specific, VPNs, etc. tcpdump -nes0 -i eth0 ether host "" tcpdump -nes0 -i eth0 host "" to capture to a file for later analysis in a program like Wireshark, just add: -w ~/ to the end of your 'live watch' command, This creates the named file in the root directory. I prefer to use Wireshark to do my filtering, so I rarely do any on the commandline level. But there are all the options you need to do so available in this tool. Also, by adding an ampersand (&) to the end of your command line command (when not capturing to a file), you can then work the command line while the dump is displaying. Obviously this only works if you are trying to get someone connected, as a good connection won't let you do much as it will be too 'busy'. If you want to start a capture writing to file, and then get back to the command line, consider looking into the screen command or some such. Sorry for being so verbose, but I remember learning to use tcpdump and those are a few things I learned first that allowed me to fairly productive out of the gate. HTH

david
david

One item Chad... The last example has a few flaws and could use a bit more explaining... The proto keyword is somewhat more complex, I believe you were looking for the port keyword which specifies which TCP or UDP port number (in your case ssh/TCP 22). The man page is very helpful when playing with the protocols. A useful example is when looking at VPN connections: tcpdump port 500 or ip proto 51 The above will capture IKE (UDP 500) and the encrypted connection (IP type 51/ESP). A useful piece of assistance with complex expressions like the one you used with ssh and hosts foo and bar are parenthesis. Without them, you have to structure your query in precise order and you may not be able to get specifically what you're looking for. Most shells require that you escape or quote them as they are shell reserved symbols, but they allow you to do complex boolean logic in a much more readable way. To provide an alternative to your syntax for the last example: tcpdump "port ssh and not ( host foo and host bar and port ssh )" Which breaks down as: any communications with src or dst on port ssh/22 except if foo and bar are communicating on port ssh/22. Also, at least in bash, the double quotes are necessary so that bash will not try and interpret the parenthesis itself.

marco
marco

Good work Chad. Let me just chip in by saying that the first time i used tcpdump to dump a file for later analysis in former ethereal, now whireshark, i was missing a lot of data. After fidling around i found that by default tcpdump only saves the first 68 bytes of every packet, if i'm not mistaken. To save the whole packet try the -s switch. For example the maximum packet size traversing an ethernet segment should almost always be 1500 (MTU for ethernet), so "tcpdump -s 1500" should do the trick. Regards Marco

ironhead
ironhead

You're missing the boat when you make a case for "tcpdump VERSUS Wireshark", et al. I use command line tcpdump packet captures on a daily basis, and 98% of the time I dump the output to a file, only to then load it up in Wireshark to do the real packet analyzing. tcpdump AND Wireshark go together hand-in-hand; tcpdump is an easy way to copy what is traversing an interface, and Wireshark is an easy way to view that traffic in a graphical format. (FYI - the other 2% of the time I'm dumping the output to a screen, just to see if traffic is passing through...)

apotheon
apotheon

I appear to have had a brain fart while writing that article. I fixed the SSH example. Thanks for pointing out the error.

david
david

Most current releases of tcpdump allow the use of "-s 0" which captures the entire packet regardless of how large it is... Not all versions support it, but if they do, its easier than trying to remember the MTU for your device/interface.

apotheon
apotheon

I probably should have mentioned that in the article. Thanks for bringing it up.

jhoward
jhoward

I work with VoIP and I use tcpdump to capture instances of devices sending SIP messaging to make sure they are communicating correctly with the other devices and applications. Especially in production environments packet captures can get huge really fast and you sometimes have to wait quite a bit for what you are looking for to happen. This is where the -C, -G and -W switches come in handy. Basically they let you create fixed sized rotating logs which allow you to monitor a packet capture without fear of using up your hard drive space and significantly less fear of missing the packets you were looking for.

oparker
oparker

Anyone who would downplay the use of the tcpdump/wireshark combo doesn't do much analysis or else has all the time in the world to do so. Using both daily, I cannot imagine being without either to be honest. tcpdump is great for live analysis for general problems. And it has no peer for capture. But if I have a few megs of packets to analyze, wireshark lets me filter them ten different way in a matter of minutes, uses color coding to help you zero in on specific targets, etc. Sure you don't NEED to use a GUI, but if speed and efficiency is a primary concern and you have to do this sort of thing all day for hundreds of different networks of every imaginable configuration, you will soon find the merits of using this incredible combination of tools... Just my .02

seanferd
seanferd

And I'm not someone who does net analysis frequently. I suspect, in fact, that it would be easier for the occasional user than installing one of the GUI utilities (then needing also to install winpcap as well). But never mind me, I don't run large networks, and know next to nothing.

AlexNagy
AlexNagy

tcpdump doesn't just do packet sniffing, it can also analyze the packets it picks up. Why would you need another tool to do the analysis? The only tool I've ever used for network/security analysis is nmap which is built on top of tcpdump. You just don't need anything else.

apotheon
apotheon

"[i]Wireshark is an easy way to view that traffic in a graphical format[/i]" Why would I need to do that?

knucklhead
knucklhead

It took me this far to make the connection. Injecting a little levity is a nice touch.

seanferd
seanferd

Not everyone reads through all the switches for a given command. Good of you to point that out.

AlexNagy
AlexNagy

I am going to assume you've never done much work on the linux command line using the basic tools that come with most, if not all distributions. We'll ignore tcpdump for now and just stick to analysis, as this could be put to use on any sort of log file. Back when I first started hosting my own web server (GNU/Debian, Apache, iptables, router with my box dmz'd) I often found myself the target of interest (I did use a gui tool to monitor, in a general way, activity on my connection) more then once from the same IP address over a period of days (my attempts to disuade them from bothering me were unsuccessful, that is until I contacted their ISP, more on that later). With Apache I had it keep very detailed log files, which I rotated and compressed once they reached around 10MB. Using nothing more then a fairly simple one liner I was able to go through several days worth of log files and compile the results into a single file in less then ten minutes (and that's including the time it took me to learn how to use cat), and I did it all without any gui tools. Had I used a gui tool, knowing how clunky they are, I could have spent hours trying to get the end result I wanted (which was damning evidence of attempts to gain unauthorized entry into my box, which to my knowledge never happened). Now back to tcpdump. You grab the packets and log them to a file. You apparently already know what you are looking for otherwise there's not point to the exercise. Write a simple one liner, even put it in a bash script (I guess for Windows it would be a VB script or some such) for later use, and let the computer do the work. How can you get more efficient then that using two different programs to do the job? I wish I was still running Linux at the moment (other needs cause me to keep Windows on this box), because I could re-figure out that one liner and share it with everyone in this discussion.

apotheon
apotheon

"Foo" and "bar" are actually part of a broader concept known as "metasyntactic variables". The single most common metasyntactic variable to use is [url=http://en.wikipedia.org/wiki/Foo][b]foo[/b][/url], and [b]bar[/b] is the traditional second metasyntactic variable, followed by [b]baz[/b]. Beyond three, and you should probably start coming up with meaningful names -- though there's a traditional progression beyond bar, too. . . . but yeah, "foobar" (i.e., FUBAR) is a fun bit of subtle reference to add to a discussion of serious topics like this.

Editor's Picks