Head First系列计划用于记录一些工具的简单使用方法以及有意思的概念。尽量做到由表及里,层层深入。

后面如果未加说明,参考的 Linux 内核源码版本均为 4.10.10。

1. 介绍

man tcpdump

首先要说的是,不要死记硬背固定的命令。在理解了基本的参数后,可以根据具体情况自己灵活组合出有效的命令来。

为什么要用 tcpdump?
一方面,大部分 *nix 服务器没有图形界面,\
	也没有预装 Wireshark,却几乎都预装了 tcpdump;
另一方面,tcpdump 的包过滤功能太强大。

下面是我根据网上资料重新组织出的讲解思路,如有错误请指教。

使用tcpdump需要用到root权限。

简单来说,一个tcpdump命令串可以是下面这个形式:

# tcpdump [options] [filter expressions]

options-打头,filter expressions则不是。为了避免歧义,作为一个好习惯,最好用单引号把你的表达式包起来(对于简单的语句也可以不用),后面讲到逻辑运算时,还会用到小括号。

2. 选项

-i INTERFACE

-i eth0-i any表示监听所有网络接口。

-s SIZE

对一个包抓取前多少字节。默认是 68 字节,-s 0表示抓取包的所有内容。

-A

数据以 ASCII 形式显示。

-X

数据以 Hex 形式显示(这个倒是很有用)。

-w FILENAME

将抓取数据写入文件。

-r FILENAME

从文件中读取数据并展示。

-n

不对 IP 做域名解析。

-nn

既不对 IP 解析,也不对 port 做服务解析。

-tttt

使用人类易读的时间形式(有用倒是有用,但这个选项怎么长这样)。

-c NUMBER

抓取 NUMBER 个符合所有条件的包后停止。

-D

显示当前有哪些可用的 INTERFACE。

-S

使用 absolute sequence number。

选项就介绍这么多,足够大多数情况使用了。

3. 过滤表达式

过滤表达式就非常有趣了,和正则表达式一样,甚至和各种编程语言一样。我们能够利用基本的 gadgets 创造出解决问题的工具。

3.1 组合

首先,有几组不同类型的组合标示符:

上面三列之间是可以组合的(事实上有些组合是非法的,如tcp net,另外顺序有时也是有要求的)!对某一列缺少指定则表示这一列的所有包都符合条件。

一些例子如下:

tcpdump -i eth0 host 192.168.137.128 -r file.pcap
tcpdump -i eth0 tcp dst port 22
tcpdump -i any src net 192.168.137.0/24

对于host,你在某些包过滤中还可以指定mac地址:

tcpdump -i eth0 ether dst host 00:01:02:03:04:05

对于port,你也可以使用dst portrange 21-23这种形式来限定端口范围。

3.2 包大小限定

less/greater

tcpdump less 128
tcpdump greater 28

3.3 逻辑运算

上面的各种组合已经很厉害了,这里的逻辑运算能够帮你生成更强大的筛选条件。

and	or	not
&&	||	!

使用上下哪一种形式都可以。

例如:

tcpdump -i eth0 '(dst port 80) && (tcp) && (less 128)'
tcpdump -i eth0 '(dst port 80) && (tcp) && (greater 128)'

注意括号的使用。对有过编程经验的朋友来说,括号的意义和重要性不必再说。

3.4 高级玩家技能

下面进入更厉害的环节。核心目的是缩小筛选粒度。方法是定位到具体包的特定位置

tcp为例:

如果我们想筛选带ACKFIN标志的数据包该怎么做呢?从上图可以看出,标志位占 6 个比特,偏移量为 13 字节。所以所有符合要求的包头,它们的偏移 13 字节处的那个字节必定为XXX11XXX形式,其值至少为 16 + 8 = 24。我们可以这样限制:

tcpdump '(tcp[13] & 16 != 0) && (tcp[13] & 8 != 0)'

对于IP/ICMP等协议,也都可以采用类似方式指定对应位的信息。

另外,还有其他一些更方便的表达方式,下面仅仅举出例子:

syn标志:

tcpdump 'tcp[tcpflags] == tcp-syn'

片段选择:

tcpdump 'tcp[32:4] = 0x47455420'

4. 惯用法

大家可以根据上面学到的内容推理一下它们的功能。

语句

time tcpdump -nn -i eth0 'tcp[tcpflags] = tcp-syn' -c 10000 > /dev/null
tcpdump -ttttnnvvS
tcpdump -nnvXSs 0 -c1 icmp
tcpdump -nnvvS src 10.5.2.3 and dst port 3389
tcpdump -nvX src net 192.168.0.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16
tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)'

参考文献